Files
EventSnap/backend/migrations
MechaCat02 e1c689d1a7 chore(migrations): renumber 021-023 to 023-025 to clear the collision with main
main independently shipped 021_hashtag_counts_respect_bans and
022_client_upload_idempotency. sqlx::migrate! embeds ./migrations and refuses two
files per version, so these three had to move before the branch could merge at all.

Contents are untouched — only the version prefixes change. Renumbering (rather than
renumbering main's) is the safe direction: main is already deployed, so its 021 and
022 are applied in production and their versions are now immutable.
2026-08-08 21:04:58 +02:00
..

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.