fix(adm-001): cascada de inactividad Medio→Seccion — Closes #16 #18
Reference in New Issue
Block a user
Delete Branch "fix/adm-001-cascada-inactividad"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Contexto
REQ-SEC-001 (crear Seccion) ya rechazaba con 404 si el Medio estaba inactivo, pero REQ-SEC-002 (update), REQ-SEC-003 (deactivate) y REQ-SEC-004 (reactivate) no extendían esa regla al padre. Esto dejaba una ventana abierta para mutar Secciones de un Medio desactivado.
Decisión adoptada (2026-04-17, issue #16): Opción B — freeze total en cascada: si
Medio.Activo = false, TODAS las mutaciones de Seccion devuelven409 medio_inactivo. Solo reactivar el Medio desbloquea la operación. Formalizado como REQ-SEC-006.Cambios
Backend
MedioInactivoExceptionnueva enSIGCM2.Domain/Exceptions/(extiendeDomainException)UpdateSeccion,DeactivateSeccion,ReactivateSeccion): inyectaIMedioRepository, validamedio.Activoantes de cualquier mutaciónExceptionFilter: mapeaMedioInactivoException→409 { error: "medio_inactivo", message }Frontend
MedioInactivoBanner(Alert destructive) enfeatures/secciones/components/SeccionesListPage: cuando hay filtro pormedioIdy el medio está inactivo → muestra banner + deshabilita "Nueva sección" + deshabilita Editar/Desactivar/Reactivar en tablaSeccionDetailPage: fetch del medio padre; si inactivo → muestra banner + deshabilita Editar/Desactivar/ReactivarDeactivateSeccionModal: acepta propdisabledpara bloquear el triggerCommits
feat(domain): MedioInactivoException (issue #16)feat(secciones): validar medio activo en update/deactivate/reactivate — issue #16feat(api): mapping 409 medio_inactivo en ExceptionFilter — issue #16feat(web): banner y disabled de secciones de medio inactivo — issue #16test(secciones): cobertura cascada de inactividad — issue #16Tests
Handle_MedioInactivo_ThrowsMedioInactivoExceptionAndNoAuditLogged— verifica que el throw ocurre ANTES del audit (fail-closed). Total: 38 → 41 passed.UpdateSeccion_WhenMedioInactive_Returns409,DeactivateSeccion_WhenMedioInactive_Returns409,ReactivateSeccion_WhenMedioInactive_Returns409— verificanerror: "medio_inactivo"+ sin AuditEvent row.SeccionesListPage.test.tsxverificando que el banner NO aparece cuando no hay filtro de medio activo. Total: 208 passed.Test plan
/api/v1/admin/secciones/{id}→ debe devolver409 { error: "medio_inactivo" }.../deactivatesobre la Seccion → 409.../reactivatesobre la Seccion → 409dotnet testverdenpx vitest runverde (208 tests)