Skip to content

SCRUM-263 — Config optimistic locking on schema replace

Found while building the schema editor (SCRUM-252).

What exists

Piece Notes
PUT /namespaces/{ns}/schema requires the schema version the editor loaded: If-Match: "<n>" (quoted or bare) or ?base_version=<n>; both must agree; W/ rejected. Missing → 428 precondition_required. Stale → 409 stale_schema "schema vN was saved since vM" with the current schema in error.details.schema
GET /namespaces/{ns}/schema sends ETag: "<schema_version>" to echo back
Store ReplaceSchema(…, expected *int, …) the check runs under the existing FOR UPDATE on the namespace row, in the insert's transaction; nothing (no row, no audit) is written when stale. nil = unchecked, internal use only; the seed passes the version it just observed

The admin UI's schema page must send the precondition (SCRUM-263 UI part, merged together with this).

How to verify

cd services/config
CONFIG_TEST_DATABASE_URL=postgres://auth_rw:pw@127.0.0.1:5433/config_test?sslmode=disable \
  go test -race -count=2 ./...

Tests: precondition parsing (quoted, bare, query, conflicting pair, W/); 428 without it; stale → 409 with details; ETag on GET; store: stale writes nothing and no audit row; 8 concurrent PUTs with one If-Match → one 200 (n+1) and seven 409, one audit row; gap-free versions when writers retry on 409.

Results at time of writing

  • gofmt, go vet, go test -race with the DB (9 packages): pass (twice in the run, once more on the rebased branch).

How it was built

DeepSeek run scoped (Landlock) to services/config; the runs were interrupted twice by WSL crashes and finished by continuation rounds. Claude review: lock/transaction order and the seed's precondition checked; no changes needed.