Files
Codewalkers/docs/database-migrations.md
Lukas May 4656627a59 fix: Restore drizzle-kit generate by syncing snapshot baseline
Snapshots were stale since migration 0008. Generated a schema-derived
snapshot at 0032 so drizzle-kit generate works again (zero diff on
current schema.ts). Also fixed migration 0032 to use statement-breakpoint
separator required by better-sqlite3.

- Added 0032_snapshot.json derived from current schema.ts
- Fixed 0032 SQL to use --> statement-breakpoint between statements
- Updated CLAUDE.md and database-migrations.md with correct workflow
2026-03-06 10:36:07 +01:00

58 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Database Migrations
This project uses [drizzle-kit](https://orm.drizzle.team/kit-docs/overview) for database schema management and migrations.
## Overview
- **Schema definition:** `apps/server/db/schema.ts` (drizzle-orm table definitions)
- **Migration output:** `apps/server/drizzle/` directory (SQL files + `meta/_journal.json` + `meta/NNNN_snapshot.json`)
- **Config:** `drizzle.config.ts`
- **Runtime migrator:** `apps/server/db/ensure-schema.ts` (calls `drizzle-orm/better-sqlite3/migrator`)
## How It Works
On every server startup, `ensureSchema(db)` runs all pending migrations from the `apps/server/drizzle/` folder. Drizzle tracks applied migrations in a `__drizzle_migrations` table so only new migrations are applied. This is safe to call repeatedly.
The migrator discovers migrations via `apps/server/drizzle/meta/_journal.json`**not** by scanning the filesystem.
## Workflow
### Making schema changes
1. Edit `apps/server/db/schema.ts` with your table/column changes
2. Generate a migration:
```bash
npx drizzle-kit generate
```
3. Review the generated SQL in `apps/server/drizzle/NNNN_*.sql`
4. Verify multi-statement migrations use `--> statement-breakpoint` between statements (required by better-sqlite3 which only allows one statement per `prepare()` call)
5. Commit the migration file, snapshot, and journal update together
### Important: statement breakpoints
better-sqlite3 rejects SQL with multiple statements in a single `prepare()` call. Drizzle-kit splits on `--> statement-breakpoint`. If you hand-write or edit a migration with multiple statements, append `--> statement-breakpoint` to the end of each statement line (before the next statement):
```sql
ALTER TABLE foo ADD COLUMN bar TEXT;--> statement-breakpoint
CREATE INDEX foo_bar_idx ON foo(bar);
```
### Applying migrations
Migrations are applied automatically on server startup. No manual step needed.
For tests, the same `ensureSchema()` function is called on in-memory SQLite databases in `apps/server/db/repositories/drizzle/test-helpers.ts`.
## History
Migrations 00000007 were generated by `drizzle-kit generate`. Migrations 00080032 were hand-written (the snapshots fell out of sync). A schema-derived snapshot was restored at 0032, so `drizzle-kit generate` works normally from that point forward.
## Rules
- **Use `drizzle-kit generate`** for new migrations. It reads schema.ts, diffs against the last snapshot, and generates both SQL + snapshot automatically.
- **Never use raw CREATE TABLE statements** for schema initialization. The migration system handles this.
- **Always commit migration files.** They are the source of truth for database evolution.
- **Migration files are immutable.** Once committed, never edit them. Make a new migration instead.
- **Keep schema.ts in sync.** The schema file is the source of truth for TypeScript types; migrations are the source of truth for database DDL. Both must reflect the same structure.
- **Test with `npm test`** after generating migrations to verify they work with in-memory databases.