PARKED until measured: consolidate serial write paths into set-based SQL (practica create/edit, perfil, memberships)
PARKED BY ELAZAR 2026-09-05, deliberately. Do NOT start this until the connection-layer fixes are live and MEASURED. Reason given: one change at a time on the path that creates student data. A measurement reminder fires from 2026-09-09 (see the daily DM script; ask bin-venus-cc / nw-venus-cc). Found by coder-mars-ca's data-layer audit 2026-09-05 (source-only, no runtime timings - priority is by potential held-slot time and cardinality against the 6-slot / 10s pool). NOT independently re-verified by coder-mars-cc: items 1 and 6 of that audit were verified and split out (MARS-689 and the archive-context item); these five were not. Re-verify each against source before implementing - a sibling audit in this same batch asserted a missing React cache() wrapper that was in fact present, so treat every claim below as a lead, not a finding. Highest cardinality first: 1. practicas/nueva/actions.ts:715-912 holds an advisory-lock transaction while inserting EVERY tooth (796-821), conducto (830-854) and image row (861-910) one at a time. Proposed: create_practica_atomic taking validated JSON arrays with set-based INSERTs/CTEs. Must preserve idempotency, seq allocation, archive GUCs, FK/trigger behaviour; image storage stays in Node before DB work. 2. Same action re-reads each treatment option TWICE - validation query per tooth at 438-441, then again inside the transaction at 824-828, including duplicate option ids. Proposed: one category-scoped WHERE id = ANY lookup, validate once, carry isEndo/value forward. The second loop extends the time the transaction holds its slot. 3. mi-cursada/[id]/editar/actions.ts:878-1233 holds state/edit/teeth locks then serially updates teeth (1020-1063), conductos (1096-1137), deleted images (1184-1191) and inserts uploads (1199-1233). Proposed: update_practica_edit_atomic with validated JSON. Must preserve version/ownership locks, the label park/reapply for uq_practicaToothConductos_tooth_label, archive context/triggers; uploads stay in Node. 4. perfil/actions.ts:130-141 reads notification lookup options then does NINE serial INSERT ... ON CONFLICT writes, one per notification type. Proposed: one set-based upsert from JSON/unnest, keeping lookup validation and current triggers/unique key. 5. user-actions.ts:311-321 creates teacher memberships in a loop. Proposed: one INSERT ... SELECT FROM unnest(comisionIds) WITH ORDINALITY to retain first-item isPrincipal semantics and existing duplicate-error/trigger behaviour. Secondary, lower impact: editar/actions.ts:488-502, 580-584, 644-646 - four sequential pre-transaction reads that could become one edit-validation bundle. These are database-shaped work under the PostgreSQL boundary rule, so db-mars-cc authors the SQL and the coder lane writes typed callers. Reference impl: migration 083. Related: MARS-688, MARS-689, MARS-680.
Activity
-
db03-mars-ca