[PRD-002 / Domain] Rubro deactivation guard — rechazar desactivar Rubro con Productos activos #41
Reference in New Issue
Block a user
Delete Branch "%!s()"
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?
Descripción del problema
Con PRD-002 merged (Product CRUD activado), una brecha semántica quedó expuesta:
Hoy:
DeactivateRubroCommandHandlersolo valida si un Rubro tiene hijos Rubros activos. Si tiene Productos activos referenciándolo víaProduct.RubroId, la desactivación procede sin error → los Productos quedan con referencias a un Rubro inactivo (inconsistencia semántica).Escenario:
RubroIdahora apunta a un Rubro conActivo=0.Rubro.Activo=1ya no devuelven el nombre del Rubro para esos Productos.Root cause: PRD-002 diff deferred este guard a follow-up (scope discipline — PRD-002 ya entregaba ≥60 tests). Decision D5 en proposal (#467) documentó explícitamente la diferencia.
Solución propuesta
1. Extender validación en
DeactivateRubroCommandHandler:ProductQueryRepository.ExistsActiveByRubroAsync(rubroId)(NEW METHOD)RubroEnUsoPorProductosException(nueva excepción de dominio)2. Implementar
ProductQueryRepository.ExistsActiveByRubroAsync(int rubroId):3. Nueva excepción:
4. ExceptionFilter entry:
5. Tests:
DeactivateRubroCommandHandlerTests+ nuevo scenarioDeactivate_WithActiveProducts_Returns409EnUsoCategoriesControllerTests(oRubrosControllerTests?) + scenario DELETE Rubro con Product activo → 409Archivos afectados
src/api/SIGCM2.Domain/Exceptions/RubroEnUsoPorProductosException.cs(NUEVA)src/api/SIGCM2.Infrastructure/Persistence/ProductQueryRepository.cs— agregarExistsActiveByRubroAsync(int rubroId)src/api/SIGCM2.Application/Categories/Deactivate/DeactivateCategoryCommandHandler.cs— agregar validaciónsrc/api/SIGCM2.Api/Filters/ExceptionFilter.cs— agregar caseRubroEnUsoPorProductosException → 409DeactivateCategoryCommandHandlerTests.cs, API controller testsDeletebutton ya deshabilitado si hay Productos (implementado durante W5 fixes en PRD-002). Si no, agregar inline 409 handling enDeactivateCategoryDialog.Estimación
Priority
MEDIUM — Semánticamente importante (integridad de referencias), pero la ventana de exposición es limitada (entre merge PRD-002 y merge de este fix). Sin datos reales en STAGING, el riesgo es bajo.
Target: Resolver antes de PRD-008 (seed de 12 productos legacy). Si un producto queda huérfano en seed, el issue sigue de cerca.
Assignee: dmolinari
Label: followup
Related: PR #40 (PRD-002 merged), decision D5 proposal #467, spec R6 deactivate
Engram:
sdd/prd-002-product-crud/proposal(D5 — Rubro deactivation guard deferred)Next UDT: PRD-003