# 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. |
