Files
unknownandClaude Opus 5 06268bcfd6 feat(db): drizzle-schema, db-client und initiale migration
Vollstaendiges Datenmodell: Katalog (manufacturer, theme, set, tag,
instruction), Besitz (collection_item, location, missing_part, photo),
Wunschlisten (wishlist, wishlist_item) und die Auth-Tabellen von
better-auth inklusive passkey und invite.

Kernregel: ein set ist ein Katalogeintrag, ein collection_item die
Verknuepfung mit dem tatsaechlichen Besitz. Preise liegen als Cent in
INTEGER-Spalten, damit Summen exakt bleiben.

SQLite laeuft mit WAL, foreign_keys=ON und busy_timeout.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 22:25:22 +02:00

38 lines
1.2 KiB
TypeScript

/**
* Applies pending migrations from ./drizzle to the SQLite file.
*
* Runs on every container start (see docker/entrypoint.sh) and locally via
* `pnpm db:migrate`. Uses the migrator from drizzle-orm, which is part of the
* runtime bundle, so the image does not need drizzle-kit.
*/
import fs from 'node:fs';
import path from 'node:path';
import Database from 'better-sqlite3';
import { config as loadEnv } from 'dotenv';
import { drizzle } from 'drizzle-orm/better-sqlite3';
import { migrate } from 'drizzle-orm/better-sqlite3/migrator';
loadEnv({ path: '.env', quiet: true });
const dataDir = path.resolve(process.env.DATA_DIR ?? './data');
const dbDir = path.join(dataDir, 'db');
const dbPath = path.join(dbDir, 'bricktrack.db');
const migrationsFolder = path.resolve(process.env.MIGRATIONS_DIR ?? './drizzle');
fs.mkdirSync(dbDir, { recursive: true });
fs.mkdirSync(path.join(dataDir, 'files'), { recursive: true });
const sqlite = new Database(dbPath);
sqlite.pragma('journal_mode = WAL');
sqlite.pragma('foreign_keys = ON');
const db = drizzle(sqlite);
console.log(`[migrate] Datenbank: ${dbPath}`);
console.log(`[migrate] Migrationen: ${migrationsFolder}`);
migrate(db, { migrationsFolder });
console.log('[migrate] Fertig.');
sqlite.close();