Files
Synapsis/scripts/migrate.ts
T
cyph3rasi b46be5c076 Reconcile the accepted safe federation helper with E2EE integration hardening and complete PIN-based encrypted DMs
Hop-State: A_06FPC0CGS3F7SJG3BGW0YF0
Hop-Proposal: R_06FPC0BK6YEV7XASNM7C908
Hop-Task: T_06FPAWA3279RBMJAR0BHM10
Hop-Attempt: AT_06FPBZWSBFTB9B5YH9JY9QR
2026-07-15 06:40:06 -07:00

59 lines
1.6 KiB
TypeScript

import { sql } from 'drizzle-orm';
import { migrate } from 'drizzle-orm/tursodatabase/migrator';
import { closeDb, db } from '../src/db';
interface DuplicateIdentityRow {
field: 'did' | 'handle';
value: string;
duplicateCount: number;
}
async function assertIdentityUniqueness(): Promise<void> {
const tables = await db.all<{ name: string }>(sql.raw(
"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'users' LIMIT 1",
));
if (tables.length === 0) return;
const duplicates = await db.all<DuplicateIdentityRow>(sql.raw(`
SELECT 'did' AS field, did AS value, COUNT(*) AS duplicateCount
FROM users
GROUP BY did
HAVING COUNT(*) > 1
UNION ALL
SELECT 'handle' AS field, handle AS value, COUNT(*) AS duplicateCount
FROM users
GROUP BY handle
HAVING COUNT(*) > 1
LIMIT 20
`));
if (duplicates.length === 0) return;
const sample = duplicates
.map((row) => `${row.field}=${JSON.stringify(row.value)} (${row.duplicateCount} rows)`)
.join(', ');
throw new Error(
`Database identity preflight failed: duplicate users must be resolved before migration: ${sample}`,
);
}
async function main() {
try {
await assertIdentityUniqueness();
const result = await migrate(db, { migrationsFolder: './drizzle' });
if (result) {
throw new Error(`Database migration failed: ${JSON.stringify(result)}`);
}
await db.run(sql.raw('PRAGMA wal_checkpoint(TRUNCATE)'));
console.log('Database migrations are up to date.');
} finally {
await closeDb();
}
}
main().catch((error) => {
console.error(error);
process.exit(1);
});