- pnpm workspace: apps/{web,server}, packages/{contracts,db,domain,adapters,tasks,agent,testkit}
- server: Hono + zod-openapi, API Key auth with scopes, redacting pino logger, SSE event bus with replay, worker heartbeat
- db: Kysely + pg, file migrator, 0001_init (settings/api_key/audit_event/outbox_event)
- web: React Router 7 SPA console shell with 12 workspace placeholders, uhd_web tokens/ui/guard scripts
- docs: ADR-001 (Node over Deno), dev runbook, design system rules
Co-Authored-By: Claude Fable 5.1 <[email protected]>
32 lines
1.2 KiB
TypeScript
32 lines
1.2 KiB
TypeScript
import { promises as fs } from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { type Kysely, sql } from "kysely";
|
|
import { FileMigrationProvider, type MigrationResultSet, Migrator } from "kysely/migration";
|
|
|
|
/** 迁移目录:packages/db/migrations,文件名 NNNN_name.ts,导出 up/down */
|
|
export const MIGRATIONS_DIR = fileURLToPath(new URL("../migrations", import.meta.url));
|
|
|
|
// biome-ignore lint/suspicious/noExplicitAny: 迁移器不关心具体表类型
|
|
export function createMigrator(db: Kysely<any>): Migrator {
|
|
return new Migrator({
|
|
db,
|
|
provider: new FileMigrationProvider({ fs, path, migrationFolder: MIGRATIONS_DIR }),
|
|
});
|
|
}
|
|
|
|
/** 迁移到最新;失败时抛出 */
|
|
// biome-ignore lint/suspicious/noExplicitAny: 同上
|
|
export async function migrateToLatest(db: Kysely<any>): Promise<MigrationResultSet> {
|
|
const result = await createMigrator(db).migrateToLatest();
|
|
if (result.error) throw result.error;
|
|
return result;
|
|
}
|
|
|
|
/** 清空 public schema(仅开发/测试用) */
|
|
// biome-ignore lint/suspicious/noExplicitAny: 同上
|
|
export async function resetSchema(db: Kysely<any>): Promise<void> {
|
|
await sql`drop schema if exists public cascade`.execute(db);
|
|
await sql`create schema public`.execute(db);
|
|
}
|