feat: versioned migrations runner (phase 1 — no behaviour change)
Adds backend/src/db/migrations-runner.js: - Tracks applied migrations in _migrations table - Applies .sql files from src/db/migrations/ in alphabetical order - Each file runs in a transaction — fail-fast, no partial state - `migrate:bootstrap` marks 000_baseline.sql as applied on existing DBs 000_baseline.sql — full schema snapshot from prod DB (168 objects, 2026-05-06). Removed stale PostgreSQL migration files (001_init.sql, 002_constraints.sql) that used SERIAL/EXTENSION syntax incompatible with SQLite. npm scripts: migrate → migrations-runner.js (versioned) migrate:bootstrap → mark baseline applied (run once per env) migrate:legacy → legacy migrate.js (kept for reference) On prod DB after `migrate:bootstrap`: "Nothing to apply — schema is up to date". Legacy migrate.js still in place; tests still use it via setup.js (unchanged). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# Versioned migrations
|
||||
|
||||
Each schema change is a separate `.sql` file, applied in alphabetical order.
|
||||
Applied files are tracked in the `_migrations` table.
|
||||
|
||||
## Applying migrations
|
||||
|
||||
```sh
|
||||
npm run migrate # apply pending migrations (safe to re-run)
|
||||
npm run migrate:bootstrap # mark 000_baseline.sql as applied on existing DB (run ONCE per env)
|
||||
npm run migrate:legacy # run legacy migrate.js (kept for reference, do not use)
|
||||
```
|
||||
|
||||
## Naming convention
|
||||
|
||||
```
|
||||
NNN_short_description.sql
|
||||
```
|
||||
|
||||
Examples: `001_add_user_avatar.sql`, `002_drop_unused_columns.sql`
|
||||
|
||||
To find the next number:
|
||||
```sh
|
||||
ls backend/src/db/migrations/*.sql | sort -r | head -1
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
1. **Never edit** a migration file after it has been committed and deployed.
|
||||
2. To revert: write a new migration that undoes the change.
|
||||
3. Each file must be valid SQLite SQL (not PostgreSQL — no SERIAL, no EXTENSION).
|
||||
4. Use `IF NOT EXISTS` / `IF EXISTS` where possible for safety.
|
||||
5. Test on a copy of the prod DB before deploying.
|
||||
|
||||
## Deploy order (first time on a new environment)
|
||||
|
||||
```sh
|
||||
npm run migrate:legacy # initialize full schema (existing init script)
|
||||
npm run seed:permissions # seed default permissions and achievements
|
||||
npm run migrate:bootstrap # mark 000_baseline.sql as applied
|
||||
npm run migrate # apply any newer migrations (should say "nothing to apply")
|
||||
npm start
|
||||
```
|
||||
|
||||
## Adding a new migration
|
||||
|
||||
```sh
|
||||
# 1. Create the file
|
||||
echo "ALTER TABLE users ADD COLUMN avatar_url TEXT;" > backend/src/db/migrations/001_add_avatar_url.sql
|
||||
|
||||
# 2. Apply and verify
|
||||
npm run migrate
|
||||
|
||||
# 3. Commit
|
||||
git add backend/src/db/migrations/001_add_avatar_url.sql
|
||||
git commit -m "db: add avatar_url column to users"
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `000_baseline.sql` | Snapshot of full schema as of 2026-05-06. Never runs on existing DBs. |
|
||||
Reference in New Issue
Block a user