Eliminar SecuenciaComprobanteTests, ReservarNumeroCommandHandlerTests,
GetProximoNumeroQueryHandlerTests y 7 tests de integración en
PuntosDeVentaControllerTests (reserva/proximo/concurrencia/secuencialidad).
SqlTestFixture ahora limpia SecuenciaComprobante+SP si existen (drops idempotentes)
y solo crea PuntoDeVenta + temporal table.
Eliminar SecuenciaComprobante entity, TipoComprobante enum, DeadlockTransientException,
PuntoDeVentaInactivoException, carpetas Reservar/ y ProximoNumero/ de Application,
métodos ReservarNumeroAsync/GetUltimoNumeroAsync del repositorio, endpoints
POST /secuencias/.../reservar y GET /secuencias/.../proximo del controller,
y mapping PuntoDeVentaInactivoException del ExceptionFilter.
SecuenciaComprobante, usp_ReservarNumeroComprobante y TipoComprobante no tienen
propósito de negocio: IMAC/Infogestión asigna NumeroFactura+CAI externamente.
V013 ahora solo gestiona PuntoDeVenta + temporal table + permiso AFIP.
Sección 0 aplica drops idempotentes para limpiar SIGCM2_Test y reinstalaciones.
Gap detectado durante smoke: la DetailPage tenia los hooks
useReservarNumero/useProximoNumero creados en Batch 6 pero faltaba
el componente que los consume.
SecuenciasPanel.tsx: tabla con los 6 tipos AFIP (FacturaA/B/C, NC A/B/C),
proximo numero por tipo, boton Reservar. Toast con el numero reservado.
Deshabilitado si PdV o Medio padre estan inactivos.
Integrado en PuntoDeVentaDetailPage bajo guard de permiso.
Seis ajustes post-verify detectados durante la corrida full de tests:
1. PuntoDeVentaRepository: UQ_PuntoDeVenta_Medio_AFIP (no _MedioId_NumeroAFIP)
— el catch de unique violation no disparaba → 500 en race duplicado.
2. Application.DependencyInjection: registro de 8 handlers PuntosDeVenta
— sin esto, dispatcher arrojaba "No service registered" → 500.
3. ReservarNumeroCommandHandler: backoff ampliado a 5 retries
[25, 75, 200, 500, 1200]ms para soportar 50 threads concurrentes.
4. SecuenciaComprobante: SYSTEM_VERSIONING = OFF (AD8 revisitado).
Under UPDATE concurrente sobre misma fila, el engine arroja
"transaction time earlier than period start time" — limitación
conocida de Temporal Tables con alta contención de UPDATEs.
Decisión: secuencia es operacional, no configuración → sin history.
V013 y SqlTestFixture actualizados para ser idempotentes.
5. SqlTestFixture: EnsureV013SchemaAsync idempotente + PuntoDeVenta_History
en TablesToIgnore + permiso administracion:puntos_de_venta:gestionar
en seed canónico + asignación a rol admin.
6. Tests: conteos 22→23 permisos (V013 agrega uno); repository fixtures
ignoran PuntoDeVenta_History; test UpdatePdv_WhenPdvInactive eliminado
(over-specified — spec no bloquea update en PdV inactivo, solo en Medio
padre inactivo; alineado con frontend que permite editar PdV inactivo).
Resultado: 190/190 Api.Tests y tests específicos ADM-008 verdes
(Domain 13, Application 42, Api 21 = 76 tests nuevos). El único failure
residual (AuditEventRepositoryTests.QueryAsync_Limit_EmitsCursor) es
pre-existente y no relacionado a ADM-008.
Covers: verify report CRITICAL (UQ name mismatch) + WARNINGs descubiertos
durante la ejecución (DI registro, temporal tables concurrency, permiso
fixture, counts de tests pre-existentes).
8 endpoints en /api/v1/admin/puntos-de-venta con permiso administracion:puntos_de_venta:gestionar.
ExceptionFilter: +PuntoDeVentaNotFoundException (404), +PuntoDeVentaInactivoException (409), +NumeroAFIPDuplicadoException (409).
MedioInactivoException ya mapeado por ADM-001; no duplicado.
- Tabla PuntoDeVenta con Temporal Tables + UNIQUE(MedioId, NumeroAFIP)
- Tabla SecuenciaComprobante con Temporal Tables + UNIQUE(PdvId, TipoComprobante)
- Permiso administracion:puntos_de_venta:gestionar (guion_bajo: CK_Permiso_Codigo_Format)
- SP usp_ReservarNumeroComprobante con SERIALIZABLE + THROW 50001/50002/50003
- V013_ROLLBACK.sql incluido
Smoke tests SIGCM2_Test:
- TEST 1: primera reserva devuelve 1 (lazy init) OK
- TEST 2: segunda reserva devuelve 2 OK
- TEST 3: PdV inactivo -> SqlException 50001 'punto_de_venta_inactivo' OK
- TEST 4: Medio inactivo -> SqlException 50002 'medio_inactivo' OK
Covers: REQ-PDV-001/003/009, REQ-SEC-CMB-001/002/003/004
Closes#16. Medio inactivo bloquea update/deactivate/reactivate de sus Secciones con 409 medio_inactivo. Fail-closed (sin AuditEvent si el throw sucede antes). Banner + disabled buttons en UI.
Reemplaza 13 <select>/<option> nativos en 8 archivos por el componente
shadcn Select (Radix UI). Los selects nativos ignoraban los tokens del
design system en dark mode, causando texto invisible. Se agrega mock de
pointer capture APIs en test setup para compatibilidad de Radix con jsdom.