MARS-136 ·
marsRe-key grading attribution to práctica-pick (jtpUserId) — reverses live-SA model
- Ref
MARS-136(#1130)- Project
mars- Status
- backlog
- Priority
- normal
- Type
- feature
- Assigned
- — coder
- Created by
- wi-cli-venus
- Created
- 2026-06-16T06:04:00.937Z
- Updated
- 2026-06-16T06:04:00.937Z
Questions
No questions.
Event log
-
Elazar ruling 2026-06-16 (aro:mars): 'real life is SSOT, golden rule for Mars.' Canonical grading attribution = the práctica pick (práctica.jtpUserId = whoever the student selected as JTP/Docente on that práctica), NOT studentAssignments.assignedTeacherUserId. The attributions/SA table is DEMOTED: maintained but NO grading/KPI/credit decisions made from it. Whoever was picked as JTP/Docente on a práctica grades it + gets KPI/credit; an ayudante picked into the JTP slot counts as the JTP. Adjunto chases the picked person on ungraded. REVERSES feedback_live_vs_snapshot_attribution; AFFIRMS feedback_ayudante_pickable_as_jtp. Scope is system-wide (KPI Adjunto/Titular emails + grading-attribution drills + any surface deciding grading from assignedTeacherUserId). Stage: KPI email first (live complaint), other surfaces follow. Runway: next KPI cron send Mon 2026-06-22 (Mon Jun 15 was AR holiday). Interim 8e2563e all-0 suppression stays live (harmless under new rule). Plan: coder+db design/scope-map -> audit design review -> staged implement -> cross-review + PTD. Memories to update on ship: reverse feedback_live_vs_snapshot_attribution, adjust feedback_jtp_only_grading_responsibility.
-
DESIGN COMPLETE (pre-compact checkpoint), build NOT started — held pending Elazar Q1-Q4 + audit re-review of revised design. MODEL VALIDATED: practicas.jtpUserId IS a genuine student pick — required+validated field in practicas/nueva (practica-form.tsx L401, actions.ts L369-397), pre-filled from SA assignedJtp but student-overridable (the override is how ayudante-as-JTP happens); SA only last-resort fallback for blank, prevented by required-guard. Premise safe. STAGING: S0 (gates all) = retire write-path clobber replayOpenPracticaJtpToSa (practica-jtp-sync.ts) — it UPDATEs practicas.jtpUserId=newSA on every reassign, clobbering the canonical pick; FIX = backfill jtpUserId where IS NULL only, NEVER overwrite non-null, STOP touching ayudanteUserId (MARS-60), query practicas directly not vPracticasSinEvaluar (circular), unwire at updateAlumno/reassignTeacher/fixAssignmentJtp/fixAssignmentAyudante + create-cascade. S1 getJtpStats PENDING-axis + admin-delta jtp_pra flip to pr.jtpUserId (roster studentCount STAYS SA). S2 getScopedPracticas x2 (practica.ts+alumnos.ts) — flip ONLY the attribution predicate to vp.jtpUserId, access-scope EXISTS-on-SA predicate STAYS (visibility regression risk). S3 weekly-kpi ADJUNTO/TITULAR re-key inclusion=Adjuntos UNION pickers(jtpUserId) + counts by pick; removes need for 8e2563e suppress (left harmless). DB (db-mars, rides coder push, re-export schema.md+reference-data): vPracticasSinEvaluar rekey SA->pr.jtpUserId (ZERO row delta confirmed); vHealthPracticasStale DROP only stale_jtp branch (105 now-expected false-pos), keep ayudante branch; vComisionStudentsByJtp + vComisionAyudantesByJtp NO CHANGE (display-only/no-consumer, STAY SA). OPEN: Q1 graded-axis (rec A: graded keys on pick by approvalState), Q2 4 non-TCM pickers (rec A surface+flag a-solucionar), Q3 Adjunto-dual-role (rec A show both labeled), Q4 roster display stays SA (rec A) — all sent to Elazar lettered. Interim 8e2563e (v2.16.59 all-0 suppress) LIVE+PASS. Runway: next KPI cron Mon 2026-06-22. On ship: update feedback_jtp_only_grading_responsibility per Q1 outcome.