Files
telegram-bot-workers/scripts/migrate-conversations.ts
2026-02-05 12:47:35 +09:00

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;
}