import { db } from '../src/db/client.js'; import { CHAT_CONVERSATION_MESSAGE_TABLE, CHAT_CONVERSATION_REQUEST_TABLE, } from '../src/services/chat-room-service.js'; const LEGACY_CHAT_RESOURCE_PREFIX = '/.codex_chat/'; const API_CHAT_RESOURCE_PREFIX = '/api/chat/resources/.codex_chat/'; const requestedSessionId = process.argv[2]?.trim() || null; function rewriteLegacyChatResourceUrls(text: string) { const normalized = String(text ?? '').replaceAll(LEGACY_CHAT_RESOURCE_PREFIX, API_CHAT_RESOURCE_PREFIX); return normalized.replace( /\((?:\/[^)\s]*?)?(\/api\/chat\/resources\/\.codex_chat\/[^)\s]*?)(?:\/api\/chat\/resources\/\.codex_chat\/[^)\s]*)?\)/g, (_match, resourcePath) => `(${resourcePath})`, ); } async function backfillTable( tableName: string, textColumn: string, ) { const rows = await db(tableName) .modify((query) => { if (requestedSessionId) { query.where('session_id', requestedSessionId); } }) .where(textColumn, 'like', `%${LEGACY_CHAT_RESOURCE_PREFIX}%`) .select('id', 'session_id', textColumn); let updatedCount = 0; const touchedSessionIds = new Set(); for (const row of rows) { const currentText = String(row[textColumn] ?? ''); const nextText = rewriteLegacyChatResourceUrls(currentText); if (nextText === currentText) { continue; } await db(tableName) .where('id', row.id) .update({ [textColumn]: nextText, }); updatedCount += 1; touchedSessionIds.add(String(row.session_id ?? '')); } return { tableName, textColumn, updatedCount, touchedSessionIds: Array.from(touchedSessionIds).filter(Boolean), }; } try { const messageResult = await backfillTable(CHAT_CONVERSATION_MESSAGE_TABLE, 'text'); const requestResult = await backfillTable(CHAT_CONVERSATION_REQUEST_TABLE, 'response_text'); console.log(JSON.stringify({ requestedSessionId, updatedRowCount: messageResult.updatedCount + requestResult.updatedCount, tables: [messageResult, requestResult], }, null, 2)); } catch (error) { console.error(error); process.exitCode = 1; } finally { await db.destroy(); }