chore: add server provisioning migrations
- 003_add_server_tables.sql: server_orders, server_instances tables - 003_server_sessions.sql: KV-based session tracking - 004_add_terminated_at.sql: track instance termination time Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
161
migrations/003_MIGRATION_NOTES.md
Normal file
161
migrations/003_MIGRATION_NOTES.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Migration 003: Server Sessions from KV to D1
|
||||
|
||||
**Date**: 2026-01-28
|
||||
**Type**: Session Storage Migration
|
||||
**Status**: Ready to Deploy
|
||||
|
||||
## Overview
|
||||
|
||||
Migrated server consultation session management from KV Namespace to D1 Database for better consistency, reliability, and integrated data management.
|
||||
|
||||
## Changes Summary
|
||||
|
||||
### 1. Database Schema (`schema.sql` + `migrations/003_server_sessions_d1.sql`)
|
||||
|
||||
**New Table**: `server_sessions`
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS server_sessions (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
status TEXT NOT NULL CHECK(status IN ('gathering', 'recommending', 'selecting', 'ordering', 'completed')),
|
||||
collected_info TEXT,
|
||||
last_recommendation TEXT,
|
||||
messages TEXT,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
expires_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_server_sessions_expires ON server_sessions(expires_at);
|
||||
```
|
||||
|
||||
### 2. Code Changes
|
||||
|
||||
**Updated Files**:
|
||||
- `/src/server-agent.ts` - Session management functions (getServerSession, saveServerSession, deleteServerSession)
|
||||
- `/src/openai-service.ts` - Session check in generateOpenAIResponse()
|
||||
- `/src/tools/server-tool.ts` - start_consultation, continue_consultation, cancel_consultation actions
|
||||
- `/src/routes/handlers/callback-handler.ts` - server_order and server_cancel callbacks
|
||||
|
||||
**Function Signature Changes**:
|
||||
```typescript
|
||||
// Before (KV)
|
||||
export async function getServerSession(kv: KVNamespace, userId: string): Promise<ServerSession | null>
|
||||
export async function saveServerSession(kv: KVNamespace, userId: string, session: ServerSession): Promise<void>
|
||||
export async function deleteServerSession(kv: KVNamespace, userId: string): Promise<void>
|
||||
|
||||
// After (D1)
|
||||
export async function getServerSession(db: D1Database, userId: string): Promise<ServerSession | null>
|
||||
export async function saveServerSession(db: D1Database, userId: string, session: ServerSession): Promise<void>
|
||||
export async function deleteServerSession(db: D1Database, userId: string): Promise<void>
|
||||
|
||||
// New
|
||||
export async function cleanupExpiredSessions(db: D1Database): Promise<number>
|
||||
```
|
||||
|
||||
**Removed**:
|
||||
- All `[SESSION DEBUG]` logging (unnecessary with D1's strong consistency)
|
||||
- KV constants: `SESSION_TTL`, `SESSION_KEY_PREFIX`
|
||||
|
||||
**Added**:
|
||||
- `SESSION_TTL_MS` constant (3600 * 1000 = 1 hour)
|
||||
- `cleanupExpiredSessions()` function for cron cleanup
|
||||
- Automatic expiry checking in queries (`WHERE expires_at > ?`)
|
||||
|
||||
### 3. Key Implementation Details
|
||||
|
||||
**Session Storage**:
|
||||
- JSON serialization for complex fields (collected_info, last_recommendation, messages)
|
||||
- Automatic TTL management with expires_at column
|
||||
- Strong consistency (no eventual consistency issues)
|
||||
|
||||
**Error Handling**:
|
||||
- Graceful JSON parsing with try-catch
|
||||
- Null checks for expired/missing sessions
|
||||
- Proper logging without debug noise
|
||||
|
||||
**Performance**:
|
||||
- Primary key on user_id for fast lookups
|
||||
- Index on expires_at for efficient cleanup
|
||||
- Single query for session retrieval
|
||||
|
||||
### 4. Migration Path
|
||||
|
||||
**Automatic Migration**:
|
||||
- Old KV sessions will expire naturally (1 hour TTL)
|
||||
- New sessions are created in D1 automatically
|
||||
- No manual data migration needed
|
||||
|
||||
**Zero Downtime**:
|
||||
- D1 table creation is idempotent (IF NOT EXISTS)
|
||||
- Code handles missing sessions gracefully
|
||||
- Users can restart consultation if session expires
|
||||
|
||||
### 5. Benefits
|
||||
|
||||
**Before (KV Namespace)**:
|
||||
- Eventual consistency (delayed reads)
|
||||
- Complex debugging (async replication)
|
||||
- Separate data store (fragmented)
|
||||
- Manual cleanup needed
|
||||
|
||||
**After (D1 Database)**:
|
||||
- Strong consistency (immediate reads)
|
||||
- Simple debugging (SQL queries)
|
||||
- Integrated storage (single database)
|
||||
- Automatic cleanup (expires_at + cron)
|
||||
|
||||
### 6. Deployment Steps
|
||||
|
||||
```bash
|
||||
# 1. Apply migration (creates table)
|
||||
wrangler d1 execute telegram-conversations --file=migrations/003_server_sessions_d1.sql
|
||||
|
||||
# 2. Verify table creation
|
||||
wrangler d1 execute telegram-conversations --command "SELECT name FROM sqlite_master WHERE type='table' AND name='server_sessions'"
|
||||
|
||||
# 3. Deploy code changes
|
||||
npm run deploy
|
||||
|
||||
# 4. Test server consultation flow
|
||||
# Send message: "서버 추천"
|
||||
# Verify session is created in D1
|
||||
wrangler d1 execute telegram-conversations --command "SELECT * FROM server_sessions LIMIT 5"
|
||||
```
|
||||
|
||||
### 7. Rollback Plan
|
||||
|
||||
If issues occur:
|
||||
|
||||
1. **Code Rollback**: Revert to previous commit (KV-based code)
|
||||
2. **Database**: Drop table if needed
|
||||
```sql
|
||||
DROP TABLE IF EXISTS server_sessions;
|
||||
DROP INDEX IF EXISTS idx_server_sessions_expires;
|
||||
```
|
||||
|
||||
**Note**: Old KV sessions are unaffected (will expire naturally)
|
||||
|
||||
### 8. Testing Checklist
|
||||
|
||||
- [x] Migration SQL syntax validated
|
||||
- [x] Schema.sql updated
|
||||
- [x] All code references updated (env.SESSION_KV → env.DB)
|
||||
- [x] Logging cleaned up (no debug noise)
|
||||
- [ ] Local testing (`npm run dev`)
|
||||
- [ ] Production deployment
|
||||
- [ ] Session creation test
|
||||
- [ ] Session retrieval test
|
||||
- [ ] Session expiry test
|
||||
- [ ] Concurrent session handling
|
||||
|
||||
### 9. Notes
|
||||
|
||||
**Important**:
|
||||
- `server_order_confirm:` and `delete_confirm:` sessions remain in KV (not migrated, separate feature)
|
||||
- Troubleshoot agent still uses KV (separate migration needed if required)
|
||||
- D1 binding (`env.DB`) already exists in project
|
||||
|
||||
**Future Improvements**:
|
||||
- Consider migrating troubleshoot sessions to D1
|
||||
- Add session analytics (query D1 for session stats)
|
||||
- Implement session history/audit log
|
||||
Reference in New Issue
Block a user