4b0567d252
feat(application): commands/queries + IProductPricingService (PRD-003)
...
- IProductPriceRepository (AddAsync/GetByProductIdAsync/GetActiveAsync)
- ProductPriceDto, AddProductPriceCommand/Response, GetProductPricesQuery
- AddProductPriceCommandValidator (FluentValidation + TimeProvider, fecha >= hoy_AR)
- AddProductPriceCommandHandler (TransactionScope AsyncFlow, audit fail-closed)
- GetProductPricesQueryHandler (verifica producto existe, lista vacía válida)
- IProductPricingService + ProductPricingService (GetPriceAtAsync → decimal?)
- DI wiring en DependencyInjection.cs
- 29 tests NSubstitute + FakeTimeProvider, 1081 Application.Tests GREEN
2026-04-19 18:08:16 -03:00
54b0265994
feat(domain): ProductPrice entity + exceptions (PRD-003)
2026-04-19 17:59:43 -03:00
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
b4f17d6961
refactor: eliminar NullProductQueryRepository dead code + EXISTS en ProductQueryRepository (PRD-002 S1 S2)
2026-04-19 13:37:10 -03:00
d262454b28
fix(api): ExceptionFilter 409 para ProductTypeInactivo y RubroInactivo (PRD-002 W1)
2026-04-19 13:31:38 -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
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
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
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
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
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
a9838427a4
feat(udt-011): T400.30 — inject TimeProvider into Infrastructure critical services
...
AuditLogger, SecurityEventLogger: inject TimeProvider and use
_timeProvider.GetUtcNow().UtcDateTime for occurredAt timestamps.
JwtService: inject TimeProvider; use GetUtcNow() for token IssuedAt/Expires.
DI: update JwtService factory to pass sp.GetRequiredService<TimeProvider>().
Repositories: remove ?? DateTime.UtcNow fallback in UpdateAsync since callers
always provide FechaModificacion via domain mutators.
2026-04-18 10:12:24 -03:00
d69da5ff4c
feat(udt-011): T400.10 — inject TimeProvider into all Application handlers
...
All command handlers that call domain mutators now inject TimeProvider
via constructor and use _timeProvider.GetUtcNow().UtcDateTime as the
explicit 'now' argument. Replaces previous direct DateTime.UtcNow usage.
2026-04-18 10:12:17 -03:00
4e1d8f69ab
feat(udt-011): T400.20 — domain mutators accept explicit DateTime now param
...
Remove DateTime.UtcNow calls from all With*/Deactivate/Reactivate/
CerrarVigencia/NuevaVersion domain methods. Caller (Application layer)
is now responsible for passing the UTC timestamp obtained via
_timeProvider.GetUtcNow().UtcDateTime.
2026-04-18 10:12:03 -03:00
3c264aa7a1
chore(udt-011): register DateOnlyJsonConverter in Program.cs AddJsonOptions
2026-04-18 09:47:19 -03:00
a75d2f75a0
feat(udt-011): DateOnlyJsonConverter as yyyy-MM-dd
2026-04-18 09:47:16 -03:00
54d2340bb9
feat(udt-011): register TimeProvider.System in AddApplication DI
2026-04-18 09:44:21 -03:00
4e70b0f847
feat(udt-011): TimeProviderArgentinaExtensions.GetArgentinaToday cross-platform
2026-04-18 09:43:35 -03:00
600ff52dd2
refactor(infra): eliminar LegacySeedMap/NormalizeUpperSnakeToPascal de IngresosBrutosRepository
2026-04-17 19:11:51 -03:00
3eda59f5aa
feat(adm-009): ExceptionFilter mapping for fiscal exceptions ({error, message} unified)
2026-04-17 18:40:05 -03:00
b1a461b6cb
feat(adm-009): FiscalController with raw-body Porcentaje/Alicuota defense
2026-04-17 18:40:02 -03:00
25407583eb
feat(adm-009): Fiscal API DTOs (requests + responses + mapper)
2026-04-17 18:39:58 -03:00
83dd680fa3
feat(adm-009): TipoDeIvaRepository + IngresosBrutosRepository Dapper implementations + DI registration
2026-04-17 18:23:10 -03:00
bd0c4deea7
feat(adm-009): TipoDeIva + IngresosBrutos handlers, DTOs, DI registration
2026-04-17 18:09:52 -03:00
eead0a35cd
feat(adm-009): ITipoDeIvaRepository + IIngresosBrutosRepository abstractions
2026-04-17 18:09:36 -03:00
1d051c93d6
feat(adm-009): Permiso.AdministracionFiscalGestionar constant
2026-04-17 17:53:17 -03:00
f267e4f427
feat(adm-009): domain exceptions for fiscal entities
2026-04-17 17:52:57 -03:00