Move follow-up radiograph gate+lock+insert into one atomic Postgres function (MARS-683 finding 3)
Split out of MARS-683 (audit finding 3 on 4713c06, deferred so it would not block two user-visible prod fixes). src/app/(protected)/mi-cursada/[id]/followup-radiograph-action.ts does the ownership/approved-state gate, lookupOptions resolution, FOR UPDATE row locking, sortOrder computation via a correlated MAX subquery, setArchiveContext and the practicaImages INSERT as raw Node SQL inside withTransaction. That is relational transactional business logic and belongs in Postgres per mars-commons PostgreSQL Boundary + evolutiva-db.md. Ask: db-mars-cc supplies ONE typed atomic function (shape of migration 083's create_support_ticket_atomic / reply_support_ticket_atomic) that takes practicaId, practicaToothId, studentUserId, the uploaded image fields and the label, performs the gate + lock + insert, and returns a discriminated outcome the caller can map to Spanish copy. Node keeps auth, api-images I/O, and user copy. The coder lane writes the typed caller. Note for whoever picks this up: MARS-683 added a post-error persistence probe in the Node catch because withTransaction commits inside its try, so a lost commit ack is indistinguishable from a rollback (src/lib/db.ts:83). Moving the work into a DB function does NOT by itself remove that ambiguity - the ack can still be lost - so the probe or an equivalent must survive the refactor. Deleting it as redundant would silently restore the delete-a-referenced-image bug that audit blocked at ce0e232. Three regression tests in followup-radiograph-action.test.ts pin the three branches; keep them green or replace them deliberately. Not urgent: the feature has been used once since 08-27 and the correctness bugs are fixed.
Activity
-
Scope obsolete: the action this refactor targeted (followup-radiograph-action.ts) was deleted at 20de571 when Elazar ordered the unrequested follow-up-radiograph feature removed. There is no caller left to move into Postgres. Cancelled as scope obsolete, not as work declined - had the feature stayed, the boundary finding was valid.