feat(migrations): add maven_versions.size_bytes column, backfill, and index
Summary
Step 1 of the Maven version size accounting plan (issue #550 (closed)): add maven_versions.size_bytes per ADR-007's artifact-level storage accounting, with the backfill and the size-ordered partial index.
- Column —
ADD COLUMN size_bytes bigint NOT NULL DEFAULT 0. The constant default keeps the ADD metadata-only (no table rewrite) on PG 11+, so old and new binaries coexist in a rolling deploy. - Backfill — a set-based recompute grouped by version: distinct
blob_sha256permaven_version_idfrommaven_filesjoined toblob_storage_blobson(namespace_id, sha256). Soft-deleted files are included; package-level rows (maven_version_id IS NULL) are excluded; fileless versions keepDEFAULT 0. The direct join substitutes for the ADR'sblob_storage_blobs_by_namespaceshadow, documented in the migration comment and the plan. - Index —
(namespace_id, maven_package_id, size_bytes DESC) WHERE soft_deleted_at IS NULL, mirroring the remote twin.
Rolling-deploy safe: the store's inserts use explicit column lists, so the regenerated jet column changes no query semantics.
Files changed
internal/datastore/migrations/sql/20260813150000_add_maven_versions_size_bytes.sql— the migration (Up/Down, squawk exemptions carried where required)internal/datastore/migrations/structure.sql— regenerated schema dump (column on parent + all 64 partitions,ON ONLYindex +ATTACH PARTITIONentries)internal/datastore/jet/artifact_registry/public/{model,table}/maven_versions.go— regenerated jet typesinternal/datastore/migrations/maven_schema_integration_test.go— column-shape, default, NULL-rejection, partition-recursion, index-shape, and backfill testsinternal/datastore/migrations/migrations_checksum_test.go— head-version constant moved in lockstep
Test coverage
- Column shape (
bigint NOT NULL),DEFAULT 0materialization - Explicit-NULL insertion rejected
- Index shape incl. the size-ordered
DESCand thesoft_deleted_at IS NULLpredicate - Recursion over all 64 partitions
- Backfill correctness against hand-written expected constants (dedupe, soft-deleted inclusion, package-level exclusion, fileless default)
E2e scenario catalogs
No catalog scenario added or affected — the catalogs in docs/testing/e2e/ cover user-level Docker/OCI flows; this work adds a schema column, a backfill, and an index with no user-flow delta (said per the testing-catalogs guardrail). The management-API display field that surfaces size_bytes is Step 5 of the plan and lands separately.
Size justification
Reviewable LOC is 827 — over the 500 ceiling in docs/dev/development-model.md. The excess is almost entirely the schema-integration and helpers suites for the single migration (review fixes added the same-size dedupe fixture, Down/Up round-trip assertions, a negative-storability test, and shared format-neutral helpers); the count also includes 51 lines in CLAUDE.md for the comment-and-test conventions this MR codifies, and splitting tests from the migration would defeat the test-first structure, so the size is justified as-is.
Database Review Evidence
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 |
|---|---|---|---|
20260813150000_add_maven_versions_size_bytes.sql |
OK (195.03ms / 50.58ms) | OK (96.2ms / 49.36ms) | OK (160.02ms / 37.75ms) |
Migration notes:
- No anomalies: all versions apply and roll back cleanly, sub-second on an empty database (well under the 1s slow-migration bar and the 5-minute boot budget); up/down asymmetry is within noise; PG 16's up timing (195ms) trails PG 17/18 but is trivial in absolute terms.
Related to #550 (closed)