113 lines
3.5 KiB
TypeScript
113 lines
3.5 KiB
TypeScript
/**
|
|
* 기존 message_buffer 데이터를 새 conversation 테이블로 마이그레이션
|
|
*
|
|
* 사용법:
|
|
* 1. Worker 내부에서 1회성 호출
|
|
* 2. 또는 wrangler dev에서 수동 트리거
|
|
*/
|
|
|
|
import type { Env } from '../src/types';
|
|
|
|
export async function migrateExistingConversations(env: Env): Promise<{
|
|
migrated_users: number;
|
|
migrated_messages: number;
|
|
errors: string[];
|
|
}> {
|
|
const db = env.DB;
|
|
const result = {
|
|
migrated_users: 0,
|
|
migrated_messages: 0,
|
|
errors: [] as string[],
|
|
};
|
|
|
|
// 1. 기존 message_buffer에서 사용자 목록 조회
|
|
const { results: users } = await db
|
|
.prepare(`
|
|
SELECT DISTINCT u.telegram_id, mb.user_id
|
|
FROM message_buffer mb
|
|
JOIN users u ON mb.user_id = u.id
|
|
`)
|
|
.all<{ telegram_id: string; user_id: number }>();
|
|
|
|
if (!users || users.length === 0) {
|
|
console.log('마이그레이션 대상 없음');
|
|
return result;
|
|
}
|
|
|
|
console.log(`마이그레이션 대상 사용자: ${users.length}명`);
|
|
|
|
// 2. 각 사용자별 마이그레이션
|
|
for (const user of users) {
|
|
try {
|
|
const tableName = `conv_${user.telegram_id}`;
|
|
|
|
// 테이블 생성
|
|
await db.exec(`
|
|
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
role TEXT NOT NULL CHECK(role IN ('user', 'assistant')),
|
|
content TEXT NOT NULL,
|
|
tool_calls TEXT,
|
|
tool_results TEXT,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`);
|
|
|
|
await db.exec(`
|
|
CREATE INDEX IF NOT EXISTS idx_${tableName}_created ON ${tableName}(created_at DESC)
|
|
`);
|
|
|
|
// 메시지 복사
|
|
const { results: messages } = await db
|
|
.prepare(`
|
|
SELECT role, message as content, created_at
|
|
FROM message_buffer
|
|
WHERE user_id = ?
|
|
ORDER BY created_at ASC
|
|
`)
|
|
.bind(user.user_id)
|
|
.all<{ role: string; content: string; created_at: string }>();
|
|
|
|
if (messages && messages.length > 0) {
|
|
for (const msg of messages) {
|
|
// role 변환: bot -> assistant
|
|
const role = msg.role === 'bot' ? 'assistant' : 'user';
|
|
await db
|
|
.prepare(`INSERT INTO ${tableName} (role, content, created_at) VALUES (?, ?, ?)`)
|
|
.bind(role, msg.content, msg.created_at)
|
|
.run();
|
|
}
|
|
|
|
result.migrated_messages += messages.length;
|
|
}
|
|
|
|
// 메타 테이블에 등록 (이미 존재하면 업데이트)
|
|
await db
|
|
.prepare(`
|
|
INSERT INTO conversation_tables (telegram_id, table_name, message_count, last_message_at)
|
|
VALUES (?, ?, ?, (SELECT MAX(created_at) FROM ${tableName}))
|
|
ON CONFLICT(telegram_id) DO UPDATE SET
|
|
message_count = excluded.message_count,
|
|
last_message_at = excluded.last_message_at
|
|
`)
|
|
.bind(user.telegram_id, tableName, messages?.length || 0)
|
|
.run();
|
|
|
|
result.migrated_users++;
|
|
console.log(`✓ ${user.telegram_id}: ${messages?.length || 0}개 메시지 마이그레이션 완료`);
|
|
|
|
} catch (error) {
|
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
result.errors.push(`${user.telegram_id}: ${errMsg}`);
|
|
console.error(`✗ ${user.telegram_id}: 마이그레이션 실패 - ${errMsg}`);
|
|
}
|
|
}
|
|
|
|
console.log('\n=== 마이그레이션 결과 ===');
|
|
console.log(`사용자: ${result.migrated_users}명`);
|
|
console.log(`메시지: ${result.migrated_messages}개`);
|
|
console.log(`에러: ${result.errors.length}건`);
|
|
|
|
return result;
|
|
}
|