fix(isms): lock control-link edits before write (CS-701)

Merged
TO
4mo ago
+23-0

Why

Flagged on the production-deploy PR #3364 (P2): addControls/removeControl wrote the control-link rows first and only then called invalidateApprovalIfNeeded (which holds the per-document lock). So the link write ran outside the lock and could interleave with approve() before serialization kicked in.

Impact was limited — control links are not part of the frozen version snapshot, so no published version could be corrupted — but the mutation should still be serialized like every other content edit, and the lock-before-write pattern is the correct one.

Fix

Both control transactions now take lockDocument() as their first statement, before createMany/deleteMany. The conditional invalidateApprovalIfNeeded (real-change-only) is unchanged, and the advisory lock is transaction-scoped + re-entrant, so re-taking it there is a no-op. Added an ordering test asserting the lock precedes the write.

Tests

  • 325 API ISMS tests passing, typecheck clean, on top of current main.

Completes the ISMS concurrency hardening (#3366, #3367). Flagged in #3364.

šŸ¤– Generated with Claude Code

https://claude.ai/code/session_012CweXoSSEP89mX93u3Bdcp


Summary by cubic

Lock control-link edits before writes so addControls/removeControl run inside the per-document lock and serialize with approve(). Implements CS-701.

  • Bug Fixes
    • Call lockDocument first in both transactions, before createMany/deleteMany, to prevent interleaving with approve().
    • Keep invalidateApprovalIfNeeded conditional; the lock is re-entrant so re-taking it is a no-op. Added a test asserting the lock precedes the write.