chore(database): add foundation schema migrations
Summary
Foundation database schema for the Artifact Registry. Tooling infrastructure (pgFormatter, PG version matrix, CI jobs, dump-structure.sh) shipped in !249 (merged); this MR adds the migrations that exercise it.
Migrations
6 DDL migrations implementing the foundation tables from ADR-007 and ADR-022, plus the partitions schema and a slug immutability trigger.
| Table | Partitioned | Notes |
|---|---|---|
namespaces |
No | Root entity, UUIDv7 PK, immutable slug, billing entity columns, delivery mode override |
repository_collections |
HASH(namespace_id), 64 | Logical grouping within namespaces |
repositories |
HASH(namespace_id), 64 | Unified parent for all formats/kinds |
repository_collection_repositories |
HASH(namespace_id), 64 | Join table |
One migration per table, FK targets ordered first (per S04 conventions). All partitioned tables use NO TRANSACTION to stay within max_locks_per_transaction. Partition children live in the partitions schema per S04.
Also included
structure.sql: deterministic schema snapshot generated byscripts/db/dump-structure.sh, validated bydb:structure-checkCI job.
ADR alignment
namespaces.delivery_mode_override: from ADR-007 (handbook !19821).namespaces.billing_entity_type,namespaces.billing_entity_id: from ADR-022 (handbook !19789).repositoriespartial index on(namespace_id, visibility) WHERE soft_deleted_at IS NULL: from ADR-007 (handbook !19766).- No schema-level defaults on externally-provided columns (
platform,entity_type,billing_entity_type,billing_entity_id). The Core Module (Rails) must supply every value at namespace creation time. ADR amendment: handbook !19860.
Test plan
- CI green (all matrix jobs)
-
mise run db:setupapplies all migrations successfully
Database Review Evidence
Note
Timings are from CI (db:migrate matrix jobs, goose verbose mode)
against an empty database, in apply / rollback order per supported
PostgreSQL version. Production-scale validation via Database Lab is not
yet available. See
Database review evidence
in the dev docs for the matrix rationale, how to read the numbers, and
the current limitations.
Migrations
| Migration | PG 16 | PG 17 | PG 18 |
|---|---|---|---|
20260519155255_create_partitions_schema.sql |
OK (1.23ms / 1.41ms) | OK (2.32ms / 1.28ms) | OK (1.53ms / 1.38ms) |
20260519155257_create_namespaces.sql |
OK (17.63ms / 5.37ms) | OK (10.12ms / 6ms) | OK (11.44ms / 6.11ms) |
20260519155258_add_namespaces_slug_immutability_trigger.sql |
OK (3.35ms / 2.96ms) | OK (2.59ms / 2.77ms) | OK (5.75ms / 2.82ms) |
20260519155259_create_repository_collections.sql |
OK (732.74ms / 147.92ms) | OK (297.01ms / 152.63ms) | OK (321.08ms / 194.03ms) |
20260519155301_create_repositories.sql |
OK (1.83s / 332.23ms) | OK (654.28ms / 431.41ms) | OK (830.16ms / 417.52ms) |
20260519155303_create_repository_collection_repositories.sql |
OK (568.1ms / 166.7ms) | OK (350.06ms / 165.2ms) | OK (408.82ms / 210.45ms) |
Notes:
create_repositories.sql: PG 16 up (1.83s) is ~2.8x slower than PG 17 (654ms) and ~2.2x slower than PG 18 (830ms). Exceeds the 1s threshold on an empty database. Consistent with PG 16 partition DDL overhead.create_repository_collections.sql: PG 16 up (733ms) is ~2.5x slower than PG 17 (297ms) and ~2.3x slower than PG 18 (321ms). Same PG 16 partition pattern.