diff --git a/apps/api/src/db/migrate.ts b/apps/api/src/db/migrate.ts new file mode 100644 index 0000000..fc93b91 --- /dev/null +++ b/apps/api/src/db/migrate.ts @@ -0,0 +1,24 @@ +import { drizzle } from 'drizzle-orm/postgres-js'; +import { migrate } from 'drizzle-orm/postgres-js/migrator'; +import postgres from 'postgres'; + +/** + * Drizzle-Migrations beim API-Boot anwenden. Idempotent — Drizzle führt + * `drizzle.__drizzle_migrations` als Tracking-Tabelle, applied + * Migrations werden geskipped. + * + * Pattern: mana/docs/playbooks/MIGRATIONS_BOOTSTRAP.md + */ +export async function runMigrations(databaseUrl: string, migrationsFolder: string): Promise { + console.log('[migrate] applying drizzle migrations…'); + // `onnotice` schluckt Postgres-NOTICEs („schema drizzle already + // exists, skipping"), die der Migrator beim 2.+ Boot wirft. + const client = postgres(databaseUrl, { max: 1, onnotice: () => {} }); + try { + const db = drizzle(client); + await migrate(db, { migrationsFolder, migrationsSchema: 'drizzle' }); + console.log('[migrate] done'); + } finally { + await client.end({ timeout: 5 }); + } +} diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 0318f89..3e7e753 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -23,6 +23,15 @@ import { pullRequestsRouter as marketplacePullRequestsRouter } from './routes/ma import { discussionsRouter as marketplaceDiscussionsRouter } from './routes/marketplace/discussions.ts'; import { moderationRouter as marketplaceModerationRouter } from './routes/marketplace/moderation.ts'; import { marketplaceMeRouter } from './routes/marketplace/me.ts'; +import { runMigrations } from './db/migrate.ts'; + +// Drizzle-Migrations beim Boot (vor Routen-Mount). Aktivieren via env- +// Flag — Production hat's an, Local-Dev meist aus weil dort drizzle-kit +// push direkt benutzt wird. Siehe mana/docs/playbooks/MIGRATIONS_BOOTSTRAP.md +if (process.env.WORDECK_RUN_MIGRATIONS === 'true' && process.env.DATABASE_URL) { + const folder = process.env.WORDECK_MIGRATIONS_FOLDER ?? './src/db/migrations'; + await runMigrations(process.env.DATABASE_URL, folder); +} const app = new Hono(); diff --git a/infrastructure/docker-compose.production.yml b/infrastructure/docker-compose.production.yml index b9b8499..32cbb34 100644 --- a/infrastructure/docker-compose.production.yml +++ b/infrastructure/docker-compose.production.yml @@ -65,6 +65,10 @@ services: # auf 'true' setzen (und sofort wieder rausnehmen). WORDECK_AUTH_DEV_STUB: ${WORDECK_AUTH_DEV_STUB:-false} NODE_ENV: production + # Drizzle-Migrations beim Container-Start automatisch + # anwenden (idempotent über `drizzle.__drizzle_migrations`). + # Siehe mana/docs/playbooks/MIGRATIONS_BOOTSTRAP.md + WORDECK_RUN_MIGRATIONS: 'true' ports: - '127.0.0.1:3191:3081'