50a5118a78
feat(api): ExceptionFilter + e2e 409 para RubroConProductosActivos ( closes #41 )
...
Mapea RubroConProductosActivosException → HTTP 409 con error code
rubro_con_productos_activos. Test e2e usa DI override (patrón issue #36 )
para stub IProductQueryRepository sin sembrar Products reales en DB.
2026-04-19 17:08:42 -03:00
c974e824e0
feat(infrastructure): ProductQueryRepository.CountActiveByRubroAsync + integration test
...
Implementa SELECT COUNT(1) FROM dbo.Product WHERE RubroId = @RubroId AND IsActive = 1.
Tests de integración verifican: 0 sin productos, count correcto con mix
activos/inactivos/otro rubro, y solo inactivos retorna 0.
2026-04-19 17:08:35 -03:00
900fd5e975
feat(application): DeactivateRubroCommandHandler guard contra Products activos
...
Extiende IProductQueryRepository con CountActiveByRubroAsync, inyecta
el repositorio en el handler e intercala el chequeo después del guard
de hijos activos. Tests de unidad cubren: throw, success con 0 productos,
y estabilidad del orden de guardas (hijos primero).
2026-04-19 17:08:30 -03:00
e9d1e3237d
feat(domain): RubroConProductosActivosException + test ( closes #41 )
...
Co-authored-by: fix/issue-41-rubro-deactivation-guard
2026-04-19 17:08:23 -03:00
616f6432d1
fix(frontend): openEdit fetch ProductTypeDetail antes de abrir dialog ( closes #37 )
...
Reemplaza el stub con nulls por queryClient.fetchQuery con getProductTypeById,
deshabilitando el botón durante la carga y mostrando toast.error si falla.
2026-04-19 16:53:00 -03:00
b4f17d6961
refactor: eliminar NullProductQueryRepository dead code + EXISTS en ProductQueryRepository (PRD-002 S1 S2)
2026-04-19 13:37:10 -03:00
a7cfcdb683
test(frontend): ProductsPage pagination + filter tests (PRD-002 W5)
2026-04-19 13:36:48 -03:00
0f5455aba6
test(frontend): ProductFormDialog + DeactivateProductDialog tests (PRD-002 W3 W4)
2026-04-19 13:35:23 -03:00
2b79b6f769
feat(frontend): ProductForm reactivo a flags ProductType (PRD-002 W2)
2026-04-19 13:33:53 -03:00
d262454b28
fix(api): ExceptionFilter 409 para ProductTypeInactivo y RubroInactivo (PRD-002 W1)
2026-04-19 13:31:38 -03:00
08a4738daf
feat(frontend): Products feature — CRUD page, form, dialogs, hooks (PRD-002)
...
Implements full frontend for PRD-002: 5 API fns, 5 hooks (useProducts,
useCreateProduct, useUpdateProduct, useDeactivateProduct), ProductForm,
ProductFormDialog, DeactivateProductDialog, ProductsPage with CanPerform
gating. Router entry at /admin/products and sidebar link added. 19 Vitest
tests GREEN (api, hooks, page).
2026-04-19 13:24:42 -03:00
165abc8245
feat(api): ProductsController + ExceptionFilter Product cases, fix permiso count to 27 (PRD-002)
2026-04-19 13:17:31 -03:00
8c9a50504d
feat(infrastructure): ProductRepository + ProductQueryRepository, DI swap activates guard (PRD-002)
2026-04-19 13:10:21 -03:00
bb455be745
feat(application): Product handlers + DI registration, fix permiso count to 27 (PRD-002)
2026-04-19 13:07:59 -03:00
8b555e1f8b
feat(application): Product commands, DTOs, IProductRepository, validators (PRD-002)
2026-04-19 13:02:42 -03:00
16197cf242
feat(domain): Product entity + 5 domain exceptions (PRD-002)
2026-04-19 12:59:58 -03:00
230405e056
feat(frontend): wire dialogs en ProductTypesPage (PRD-001 W3)
...
Conecta ProductTypeFormDialog (create/edit) y DeactivateProductTypeDialog
en ProductTypesPage: botón "Nuevo Tipo", acción Editar por fila, acción
Desactivar por fila, empty state CTA "Crear primer tipo".
9 tests nuevos de page integration. Total: 390.
2026-04-19 12:10:09 -03:00
9cb1e84ec0
feat(frontend): ProductTypeForm + Dialog + DeactivateDialog con TDD (PRD-001 W3)
...
Implementa los 3 componentes de UI faltantes con enfoque Red→Green:
- ProductTypeForm: zod schema con transforms para multimedia numérica,
lógica condicional (multimedia deshabilitada cuando allowImages=false),
normalización en submit.
- ProductTypeFormDialog: mode create/edit, inline error 409, aria-describedby (NFR8).
- DeactivateProductTypeDialog: AlertDialog confirmar soft-delete, inline error 409 EnUso.
18 tests nuevos (8 form + 6 dialog + 4 deactivate). Total: 381.
2026-04-19 12:08:36 -03:00
3db4dedb91
feat(frontend): feature product-types completa (PRD-001)
...
types, api, hooks, ProductTypesPage, router /admin/product-types,
sidebar Tipos de Producto; 11 vitest tests nuevos — suite total 363 GREEN.
2026-04-19 10:01:12 -03:00
170789886b
feat(api): ProductTypesController + ExceptionFilter 4 casos PRD-001
...
CRUD endpoints con validación FluentValidation inline; 4 nuevas excepciones mapeadas
en ExceptionFilter; conteos de permisos 25→26 actualizados; 12 e2e tests nuevos.
2026-04-19 09:57:11 -03:00
936d1dc353
feat(infrastructure): ProductTypeRepository Dapper + DI wiring (PRD-001)
...
CRUD + paginado con filtros sobre dbo.ProductType; history temporal verificada en tests.
11 integration tests nuevos, suite total 935 GREEN.
2026-04-19 09:49:08 -03:00
5c8f19bf39
feat(application): CRUD handlers + validators + DI de ProductType (PRD-001)
...
Create/Update/Deactivate handlers con TransactionScope + audit; validators FluentValidation;
DI wiring NullProductQueryRepository + 5 handlers; SqlTestFixture V017 + permiso count 25→26.
2026-04-19 09:46:31 -03:00
3c9e852379
feat(application): IProductTypeRepository + IProductQueryRepository stub + queries (PRD-001)
2026-04-19 09:38:51 -03:00
132d17c99f
feat(domain): ProductType entity + domain exceptions (PRD-001)
2026-04-19 09:36:29 -03:00
a0a1874ac2
test(frontend): apretar match exacto del title en CategoryTree (CAT-002 W2)
2026-04-19 08:52:34 -03:00
4f25233bab
feat(frontend): tieneAvisos en RubroTreeNode + disable btn subrubro (CAT-002)
2026-04-19 08:35:42 -03:00
bb5dde6e24
feat(api): ExceptionFilter 409 para regla de oro + DTO delta (CAT-002)
2026-04-19 08:31:39 -03:00
f861dfa826
feat(application): RubroTreeBuilder + GetRubroTree con tieneAvisos (CAT-002)
2026-04-19 08:25:13 -03:00
c03aad8c5a
feat(application): guard avisos en MoveRubroCommandHandler (CAT-002)
2026-04-19 08:24:07 -03:00
216983623a
feat(application): guard avisos en CreateRubroCommandHandler (CAT-002)
2026-04-19 08:22:55 -03:00
9e50a929ae
feat(application): RubroTreeBuilder + GetRubroTree con tieneAvisos (CAT-002)
2026-04-19 08:20:36 -03:00
673194e249
feat(application): IAvisoQueryRepository + NullAvisoQueryRepository (CAT-002)
2026-04-19 08:18:56 -03:00
ddd28ea4d5
feat(domain): excepciones regla de oro rama/hoja (CAT-002)
2026-04-19 08:17:45 -03:00
bd2febf411
fix(frontend): MoveRubroDialog type cast para zodResolver output (CAT-001)
2026-04-19 07:42:56 -03:00
46ef3878de
feat(frontend): MoveRubroDialog + wire en RubrosPage + aria-describedby (CAT-001)
...
Implementa MoveRubroDialog con flattenExcludingSubtree para prevenir ciclos en UI,
lo conecta en RubrosPage y agrega DialogDescription en RubroFormDialog.
2026-04-19 07:42:55 -03:00
f07802f769
fix(frontend): corregir tipos zodResolver en RubroFormDialog (CAT-001)
...
- Reemplaza z.union([z.coerce.number(), z.literal('')]) por z.string().transform+pipe para evitar inferencia unknown en zodResolver
- Simplifica RubroFormValues a {nombre: string, tarifarioBaseId?: number | null}
- Actualiza RubrosPage: tarifarioId ya llega como number|null del schema transform
2026-04-19 07:42:55 -03:00
b22e9fe59a
feat(frontend): rubros feature + CategoryTree + CRUD dialogs (CAT-001)
...
Co-Authored-By: none
2026-04-19 07:42:54 -03:00
5e2323e0bc
feat(api): RubrosController + integration tests e2e + audit verification (CAT-001)
2026-04-19 07:42:54 -03:00
f8e9d18379
feat(infrastructure): RubroRepository Dapper + DI + integration tests (CAT-001)
2026-04-19 07:42:53 -03:00
d9fc9a2867
feat(application): Rubros commands/queries + RubroTreeBuilder + audit (CAT-001)
2026-04-19 07:42:26 -03:00
dcb2e5ada6
feat(domain): Rubro entity + domain exceptions (CAT-001)
2026-04-19 07:42:26 -03:00
0d50d4f3cc
feat(bd): V016 create Rubro table con SYSTEM_VERSIONING (CAT-001)
...
- dbo.Rubro: adjacency list, self-FK, soft-delete, temporal retention 10y
- Filtered unique index UQ_Rubro_ParentId_Nombre_Activo + covering IX_Rubro_ParentId_Activo
- Permission catalogo:rubros:gestionar seeded + assigned to admin role
- V016_ROLLBACK.sql: full reversal script
- RubrosOptions class (MaxDepth=10) + appsettings.json Rubros section
- services.Configure<RubrosOptions> registered in Infrastructure DI
- database/README.md updated with V013-V016 entries
2026-04-19 07:42:25 -03:00
bcbba2c012
Merge pull request 'chore(frontend): limpiar lint errors pre-existentes' ( #33 ) from chore/frontend-lint-preexisting into main
2026-04-19 10:41:16 +00:00
3cb89f80a3
Merge pull request 'chore(tests): dotnet format sobre archivos pre-existentes' ( #32 ) from chore/dotnet-format-testfixtures into main
2026-04-19 10:41:14 +00:00
50a3c87b14
chore(frontend): limpiar lint errors pre-existentes
...
11 errores en archivos pre-existentes (0 en rubros/). Categorización:
2 bugs reales removidos, 1 FP con disable comentado, 8 FPs suprimidos con eslint-disable-next-line.
Files:
- src/web/src/components/ui/badge.tsx — react-refresh/only-export-components (FP: shadcn/ui co-ubica badgeVariants con el componente por diseño)
- src/web/src/components/ui/button.tsx — react-refresh/only-export-components (FP: ídem, buttonVariants)
- src/web/src/components/ui/form.tsx — react-refresh/only-export-components (FP: shadcn/ui co-ubica useFormField hook)
- src/web/src/pages/admin/audit/AuditFilters.tsx — react-refresh/only-export-components x2 (FP: EMPTY_FILTERS y toApiFilter co-ubicados con el componente que los consume)
- src/web/src/features/permisos/components/RolPermisosEditor.tsx — react-hooks/set-state-in-effect (FP: patrón válido de derived state desde prop externa asignados)
- src/web/src/features/users/components/PermisosEditor.tsx — react-hooks/set-state-in-effect (FP: ídem, permisoData → mapa local de overrides)
- src/web/src/pages/admin/audit/AuditPage.tsx — react-hooks/set-state-in-effect (FP: acumulación de páginas paginadas desde query externa)
- src/web/src/features/users/pages/CreateUserPage.tsx — @typescript-eslint/no-unused-vars (FP: _created existe por contrato de callback, no se necesita el valor)
- src/web/src/lib/dateFormat.ts — @typescript-eslint/no-unused-vars (FP: _opts reservado para extensibilidad futura; formato hardcodeado por compatibilidad Intl)
- src/web/src/tests/api/axiosClient.test.ts — @typescript-eslint/no-unused-vars (bug real: requestCount incrementado en mock handler pero nunca asercionado; variable eliminada)
2026-04-18 21:00:00 -03:00
9957724c40
chore(tests): dotnet format sobre archivos pre-existentes (surfaced durante CAT-001)
...
Fix mecánico de whitespace detectado por dotnet format --verify-no-changes durante la verify phase de CAT-001 (PR #30 ). Sin cambios funcionales.
2026-04-18 20:56:23 -03:00
1cb69cbaf3
chore(frontend): DialogDescription en dialogs para a11y (silencia Radix warning)
2026-04-18 20:55:36 -03:00
67da544bb4
refactor(udt-011): AuditRetentionEnforcerJob usa TimeProvider inyectado
2026-04-18 11:07:43 -03:00
b79dfb2f34
refactor(udt-011): AuditPartitionManagerJob usa TimeProvider inyectado
2026-04-18 11:07:40 -03:00
ff912cc6a9
refactor(udt-011): AuditIntegrityCheckJob usa TimeProvider inyectado
2026-04-18 11:07:36 -03:00