Skip to content

catalogue: retrofit PUT /v1/catalogue/item/:uid with three-phase Cypher + TOCTOU guard #407

Description

@JanSmrcka

Follow-up from #406.

Context

The new PATCH /v1/catalogue/item/:uid endpoint (PR #406) has three hardening layers the existing PUT does not:

  1. Three-phase Cypher: all MATCHes resolve every referenced node (user, item, supplier, category, detail properties) before any SET/MERGE/DELETE runs. Partial writes on a missing reference are impossible at the query-shape level, independent of transaction rollback.
  2. Cypher-level lost-update guard: WHERE item.lastUpdateTime.epochSeconds = \$eps AND item.lastUpdateTime.nanosecond = \$nanos catches concurrent writes that raced past the service-layer Go check, with full nanosecond precision.
  3. MATCH-before-DELETE swap for supplier/category: an invalid new target UID can't leave the item stripped of its supplier/category relationship.

PUT currently has:

  • Only the service-layer Go check for `lastUpdateTime` (TOCTOU-prone).
  • The legacy destructive Details-delete loop (unrelated to this issue but worth noting).
  • No three-phase guarantee — `SET item.lastUpdateTime` runs before subsequent MATCH failures would be detected.

Proposal

Retrofit UpdateCatalogueItemQuery in `services/catalogue-service/catalogue-db-queries.go` with the same three-phase structure. The audit `action: "UPDATE"` value is already consistent, so no changes to history consumers.

Scope

  • UpdateCatalogueItemQuery restructured (phase-1 MATCHes → phase-2 writes → phase-3 audit)
  • UpdateCatalogueItem service maps empty-result to helpers.ERR_CONFLICT (matching PATCH behavior)
  • Cypher-level guard on item.lastUpdateTime.epochSeconds + nanosecond
  • Tests mirroring `TestPatchCatalogueItemQuery_Phase1MatchFailure_NoPartialWrite` and `TestPatchCatalogueItemQuery_CypherLockRejectsSubMillisecondRace` but targeted at PUT

Non-goals

  • Changing PUT's semantics (still full-replace; details still cleared if omitted — that's the PUT contract)
  • Changing the HTTP shape

Risk

Low. Existing PUT consumers (FE item edit form) won't see behavior changes, only stronger consistency under concurrent load.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions