import { test } from 'node:test'; import assert from 'node:assert/strict'; import { mkdtemp, rm } from 'node:fs/promises'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; import Database from 'better-sqlite3'; import { readMigrationFiles } from 'drizzle-orm/migrator'; import { openDatabase } from '../src/db/index.js'; test('사용 중 적용된 초기 계정 DB 버전을 후속 마이그레이션으로 보정하고 기록 보존', async () => { const folder = await mkdtemp(join(tmpdir(), 'hop-legacy-')); try { const path = join(folder, 'legacy.sqlite'), old = new Database(path), migrations = readMigrationFiles({ migrationsFolder: join(import.meta.dirname, '../drizzle'), }); old.exec( 'CREATE TABLE __drizzle_migrations(id INTEGER PRIMARY KEY AUTOINCREMENT,hash TEXT NOT NULL,created_at INTEGER)', ); for (const [index, migration] of migrations.slice(0, 5).entries()) { for (let statement of migration.sql) { if (index === 4 && statement.includes('CREATE TABLE `__new_deletion_operations`')) statement = statement.replace('`guestId` text,', '`guestId` text NOT NULL,'); old.exec(statement); } old .prepare('INSERT INTO __drizzle_migrations(hash,created_at) VALUES (?,?)') .run( index === 4 ? 'fb1af44cf19e4f77c50f07608ba046819dce40cae3925e0b632d1d9afa045068' : migration.hash, index === 4 ? 1791448938074 : migration.folderMillis, ); } const now = Date.now(); old .prepare('INSERT INTO guest_sessions(id,tokenHash,expiresAt,createdAt) VALUES (?,?,?,?)') .run('guest', 'hash', now + 86400000, now); old .prepare('INSERT INTO deletion_operations(id,guestId,createdAt,undoUntil) VALUES (?,?,?,?)') .run('operation', 'guest', now, now + 5000); old.close(); const { sqlite } = openDatabase(path); const info = sqlite.pragma('table_info(deletion_operations)') as { name: string; notnull: number; }[]; assert.equal(info.find((c) => c.name === 'guestId')!.notnull, 0); assert.equal((sqlite.prepare('SELECT count(*) AS n FROM guest_sessions').get() as any).n, 1); assert.equal( (sqlite.prepare('SELECT guestId FROM deletion_operations WHERE id=?').get('operation') as any) .guestId, 'guest', ); assert.equal((sqlite.pragma('foreign_key_check') as any[]).length, 0); assert.equal( ( sqlite .prepare('SELECT count(*) AS n FROM __drizzle_migrations WHERE hash=?') .get('fb1af44cf19e4f77c50f07608ba046819dce40cae3925e0b632d1d9afa045068') as any ).n, 1, ); sqlite.close(); const again = openDatabase(path); assert.equal( (again.sqlite.prepare('SELECT count(*) AS n FROM guest_sessions').get() as any).n, 1, ); again.sqlite.close(); } finally { await rm(folder, { recursive: true, force: true }); } });