feat(maven): maven_virtual_repositories schema (S30 plan: 1/25)
Summary
Step 1 of the S30 plan (Depends on: —): the maven_virtual_repositories schema — the parent table, its unique index, the jet output, and the S20-A collateral the new cascading child forces.
- Migration
20260916100000_create_maven_virtual_repositories.sql: parent plus 64HASH(namespace_id)partitions under-- +goose NO TRANSACTION, the inline uuid-v7CHECK,ON DELETE CASCADEon the(repository_id, namespace_id)composite foreign key andNO ACTIONon the namespace key as trailingALTER TABLE ... ADD CONSTRAINTstatements, and the(namespace_id, repository_id)unique index. - Regenerated
structure.sqland jet output. - Schema and rowshapes integration suites in the migrations package, mirrored against npm's
npm_virtual_repositoriessuites — zero dropped subtests, every enumerated column value covered positively. - The FK schema guard's
wantCascadeTargetsgrows by the new child; the S20-A inbound-FK count sentence is corrected to "ten of the twelve ... cascade".
Targets main directly: the step declares no dependencies, and no open MR touches these files.
Diff size
3,219 added lines across 11 files, past the 500-reviewable-LOC line:
| File group | Added | Reviewable |
|---|---|---|
structure.sql + jet output |
1,338 | no — machine-checked (db:structure-check, jet:generate-check) |
| The migration | 685 | yes |
| New integration suites | 1,190 | tests |
| Guard, checksum, mirror-collateral, S20-A prose | 6 | yes |
Reviewable source is ~1,880. The plan prices Step 1 as one step (~1,900 total); splitting it would separate the migration from the only suites that pin it, and Steps 2–3 serialize on this table landing first.
Plan divergences, booked for the docs(plans) amendment
- Lock posture. The plan pins the container junction's in-file Up-side
SET lock_timeout = '1s'/SET statement_timeout = '5s'; the migration follows #548's schema-wide decision instead: the provider owns the Up-side bound as a connection startup option — a SQLSETwould override it for this file's statements forever, and Steps 2–3 copy this file's shape — therequire-timeout-settingswaiver carries the posture, and only the Down brackets. Main's newest migration (20260915130000) already embodies this reading. - npm mirror collateral. The two npm mirror suites gain
//nolint:dupltwin directives and one tense fix — unbooked in the plan, measured firing when stripped.
A step MR cannot edit the plan file, so both ride the planned docs(plans) amendment MR.
Governing ADRs
ADR-007 governs the schema, and the migration conforms to it as written: the ON DELETE CASCADE general rule for format child tables "and their virtual and remote variants" (ADR-007 :174), the uuid-v7 CHECK mandate (:30), HASH(namespace_id) partitioning (:1125), and the (namespace_id, repository_id) unique index (:1131); the namespace foreign key's NO ACTION equals ADR-007's unstated-action default, and the repositories-facing pair is declared in the maven_virtual_repositories ERD block. Verified against the canonical handbook text at HEAD on 2026-09-15 — the local mirror is fresh for this file. The amendment #943 tracks (the range/length CHECK constraints and the junction ON DELETE pair) covers subjects that materialize in Steps 2–3, not in this diff. ADR-001, 004, 005, 008, 009, and 012 were checked against the diff: no surface of theirs appears here.
Testing
- New schema and rowshapes integration suites (
//go:build integration, migrations package), mirrored against npm's with zero dropped subtests; the unique-constraint rejection asserts SQLSTATE 23505; the catalog-derivedTestIDUUIDVersionCheck_CoversEveryApplicationGeneratedIDTablepicks the new table up automatically. - The FK schema guard (
TestRepositoryStore_DeleteFKAssumption_SchemaGuard) derives the live topology from the catalog and now requires the new cascade. go test ./internal/datastore/migrations/green locally; CI runs the full suite. Integration-tagged files linted withgolangci-lint run --build-tags=integration— 0 issues on diff lines.- e2e scenarios: none added or affected — this step ships schema only, with no client-facing route; the plan books the
e2e.maven.virtual.*catalog group at Step 20. - Conformance: no Maven protocol behavior is implemented (schema only), so no conformance run is due.
/validate-stepran pre-push: the sequence-number blocker it found is fixed at the tip (69d094d88, renumber above main's head); the plan-vs-code lock-posture contradiction was ruled keep-code by the operator (#548, above); the remaining WARNs are the two amendment items above.
Related to #289 (step 1 of 25; the issue tracks the whole S30 implementation)
Database Review Evidence
Migrations
Note
Timings are from CI (db:migrate matrix, goose verbose) against an
empty database, in apply / rollback order per PG version.
Production-scale validation via Database Lab is not yet available. See
Database review evidence
for the matrix rationale and how to read the numbers.
| Migration | PG 16 | PG 17 | PG 18 |
|---|---|---|---|
20260916100000_create_maven_virtual_repositories.sql |
OK (823.56ms / 164.08ms) | OK (503.1ms / 138.09ms) | OK (1.06s / 304.95ms) |
Migration notes:
- PG 18 up (1.06s) is ~1.3x PG 16 and ~2.1x PG 17 — under the 2x version-regression threshold, and ~0.4% of the 5-minute boot budget. The cost is the parent-plus-64-partition CREATE and the unique index; no out-of-band move needed.
Queries
None: the step is schema-only (parent table, partitions, unique index, jet output). No hand-written query methods changed, so there is no SQL to EXPLAIN in this MR. Query evidence follows in the steps that add the datastore methods.