# Migrations SQLx-managed Postgres migrations. Each `NNN_topic.up.sql` has a matching `NNN_topic.down.sql`. Run by `sqlx::migrate!()` at app start. ## Rules 1. **Never edit a shipped migration.** If a column needs to change or a fix needs to land, write a new migration. Production has already applied the old one and SQLx tracks each by checksum — editing in place will fail to apply on existing databases. 2. **Always pair `.up.sql` with a `.down.sql`.** Reverts may not be perfect (data loss is sometimes unavoidable) but the file must exist and do the best it can. 3. **Prefer additive changes.** New columns, new tables, new keys in `config`. Drop / rename only when there is no alternative. 4. **No business logic in migrations.** Schema + seeds only. Anything that needs Rust code goes in a one-off binary, not a migration file. 5. **One concern per migration.** Easier to revert. Easier to read in `git log`. ## Numbering Zero-padded three digits, monotonically increasing. The next free number lives at the bottom of the directory listing — pick that. ## Seed-only migrations When you only need to add `config` keys (feature flags, defaults), use `INSERT … ON CONFLICT DO NOTHING` so existing operator overrides survive. See `009_feature_toggles.up.sql` for the canonical shape.