Admin lever to clear a profile-photo block (and handle self-deleted photos re-entering the ladder)
MARS-580 precondition (b) of 2, both required before BLOCKING_RUNG_ENFORCED can go back to true in src/lib/profile-photo-nag.ts. Today there is NO staff-side remedy for a blocked student. Soporte is reachable from the block panel by design, but an admin who receives that ticket has no lever to pull. MARS-580's own text requires 'soporte reachable + admin clear' as the escape hatch for the MARS-567 lockout class. Also unresolved from MARS-580 Q4: deleteProfileImage lets a student clear their own photo and re-enter the ladder, landing straight at the blocking rung because visit days only accumulate and never reset. Decide whether self-deletion should be allowed at all while the requirement is in force, or whether it should reset the ladder epoch for that student. Scope to decide with Elazar/PM before building: does 'clear' mean a grace window, an exemption flag, or an admin-uploaded photo on the student's behalf. Class-A if it introduces a permission-gated admin action - design ping BEFORE implementing, per MARS-580's classification.
Activity
-
parent=#2328
-
design approved pm-mars-cc + audit-mars-ca 2026-08-22; migration 120 applied by db-mars-cc (93d5321); code + 28 tests green locally, pushing
-
SHIPPED d29ad7a v2.75.0 + P2 db9e147 v2.75.1 + P1 1fb8680 v2.75.2. Admin grace-window exemption (adminConsole action setProfilePhotoExemption/clearProfilePhotoExemption, control on /usuarios/<id>, server-clamped 1-180d default 30, reason required, admin:photo-exempt-set/clear archive reasons, appEvents row per grant/clear) + self-delete restarts the ladder (profilePhotoLadderStartedAt set in the same UPDATE that clears the photo, only when one existed). ONE predicate (isPhotoExemptActive) feeds nag, layout withhold and createPractica refusal via getProfilePhotoNagState. DB: db-mars-cc migration 120, handoff 93d5321, vUsers + vUsersFull threaded. Tests 30 across 4 photo suites. audit-mars-ca: BLOCK:d29ad7a (P2 alumno gate missing) -> BLOCK:db9e147 (P1 lookup join on value alone) -> PASS:1fb8680 deep (tag audit-mars-ca-mt46ddjqg50r). PTD 2.75.2 live == remote main. MARS-580 preconditions (a) MARS-627 and (b) this are BOTH now met; the BLOCKING_RUNG_ENFORCED flip is a separate commit and carries the layout/createPractica integration assertions audit asked for.