feat(datastore): migrate primary keys to UUIDv7 (except blob_storage_* and upload_sessions)
🧭 Summary
Migrates primary keys from bigint to UUIDv7 across the schema, so API-exposed entities no longer mix identifier types (bigint vs uuid) in responses. UUIDv7 ids are generated application-side (RFC 9562); the converted tables drop their *_id_seq sequence and column default. The database carries no data in any environment yet, so migrations are edited in place rather than added.
📏 Scope
The rule: only the blob-storage tier keeps a bigint sequence-backed id.
✅ Keepbigintid:blob_storage_attachments,blob_storage_blobs, andupload_sessions(internal storage-session state, never API-exposed).🔀 Flipid→uuid(19 tables):repository_collections,repositories,container_repositories,container_images,container_blobs,container_manifests,container_manifest_relationships,container_tags,npm_repositories,npm_packages,npm_versions,npm_files,npm_tags,npm_metadata_files,maven_repositories,maven_packages,maven_versions,maven_files, and therepository_collection_repositoriesjoin (FK columns only).namespaceswas alreadyuuid.- Every foreign-key column referencing a converted table flips to
uuid. Columns referencing the blob-storage tier (for exampleblob_storage_attachment_id) staybigint.upload_sessions.repository_idisuuidbecause it holds arepositories.id, even though the table keeps abigintprimary key.
⚠️ Breaking change
The management API serializes Repository.id as a uuid string instead of an integer. api/openapi/v1.yaml is updated accordingly. This is the intended outcome of #185 (closed) (no mixed identifier types in responses); names and slugs remain the addressable identifiers.
🛠️ Implementation notes
- Datastore stores generate ids via a shared
newID()helper (internal/datastore/ids.go,uuid.Must(uuid.NewV7())) and includeidin each INSERT, dropping the now-redundant sequence-backedRETURNING. IdempotentON CONFLICT DO NOTHINGupserts keep reading back the existing row on conflict. structure.sqland the jet models are regenerated from the converted schema.- Schema integration tests assert
uuidfor converted tables andbigintfor the blob-storage tier andupload_sessions;docs/dev/database.mddocuments the new rule.
✅ Validation
go build ./...,go vet ./...andgo vet -tags=integration ./...: clean.- Unit suite and the full integration suite (
go test -tags=integration ./...): green. - Migrations apply and round-trip; squawk lint clean;
structure.sqland jet regeneration show no drift; OpenAPI validates.
📝 Follow-up
ADR 007 and ADR 009 document the previous bigint+sequence rule but are synced from the handbook repo and cannot be edited here. A separate handbook MR will update both to the new rule (noting that application-side UUIDv7 removes the server-side sequence that was the logical-replication desync concern, while UUIDv7's time-ordering keeps B-tree insert locality close to a bigserial).
Related to #185 (closed)