# Auditoria actual del plan SmartPlus - reparto de agua

Fecha: 2026-10-21

## Regla de activacion

Todo lo exclusivo de reparto se habilita solo cuando, en la conexion del
tenant actual, existe `business_turns.value = water_distributor` y
`business_turns.active = true`. La fuente unica es
`App\\Services\\Tenant\\DeliveryBusinessTurnGuard` y falla cerrado si falta la
tabla, la conexion o la confirmacion.

## Estado punto por punto

| Punto | Estado actual | Evidencia | Falta para certificar |
|---|---|---|---|
| Resolver empresa por RUC | Implementado | `DeliveryTenantController@resolveRuc` | Segundo tenant real |
| Login del repartidor | Implementado | `DeliveryTenantController@login` y APK | Prueba fisica con tenant inactivo |
| Tenant y sucursal fija | Implementado | El login devuelve tenant y `establishment` del usuario | Dos sucursales reales |
| Marcar usuario repartidor | Implementado | `delivery_driver`, `UserController` | Revision visual final |
| Menu y backoffice limitado | Implementado | `DeliveryDriverWebRestriction`, `DeliveryDriverApiRestriction` | E2E visual con cuenta repartidor |
| POS, caja, pagos y comprobantes | Implementado | Middleware y guardas de controladores | Repetir con usuario real en release activo |
| Crear pedido de reparto | Implementado | `OrderNoteController`; modo condicionado al giro | Pedido nuevo controlado |
| Direccion, telefono y referencia | Implementado | `person_addresses` y campos de entrega | Varias direcciones del mismo cliente |
| Coordenadas y Maps por tenant | Implementado | Campos lat/lng y `google_maps_browser_key` | Validar clave y restricciones de cada tenant |
| Asignar repartidor | Implementado y probado | Asignacion condicional, outbox y ruta; Playwright devolvio 200 | Solicitud simultanea en dos dispositivos |
| Bloquear cambio fuera de Pendiente | Implementado y probado | Version, estado y update condicional; 409 ante conflicto | E2E con dos sesiones reales |
| Notificacion outbox | Implementado | Asignacion no muta si falta outbox; worker y reintentos | Migracion ausente en entorno aislado |
| FCM | Implementado en codigo | Servicio, cuenta privada, reintentos y mocks | FCM real con APK cerrada/bloqueada y caida real |
| Detalle movil | Implementado | Producto, presentacion, cantidad, total, direccion y telefono | Pedido nuevo con presentacion no legacy |
| Aceptar pedido | Implementado | `POST /api/delivery/orders/{id}/accept` | Aceptacion fisica en APK |
| Inicio automatico de ruta | Implementado | Aceptacion crea o reutiliza ruta y tracking | Ruta real con varios pedidos |
| Estados | Implementado | Pendiente, aceptado, en ruta, entregado, no entregado, reprogramado, rechazado y cancelado | Validacion visual completa en APK |
| GPS con pantalla apagada | Implementado en codigo | Servicio Android foreground, permisos y cola offline | Prueba fisica bloqueada y reconexion |
| Jornada y rastreo | Implementado en codigo | Sesiones, puntos, API y comando de cierre stale | Dispositivo real y giro apagado |
| Mapa administrativo | Implementado en codigo | Rutas activas, ultima ubicacion e historial | E2E visual durante jornada real |
| Entrega con GPS | Implementado | Endpoint movil y coordenadas persistidas | E2E fisico |
| Entrega sin GPS | Implementado | Confirmacion alternativa sin exigir coordenadas | Permiso denegado en dispositivo |
| Adicionales/faltantes/devoluciones | Implementado en backend | Lineas ajustadas, aprobacion y snapshots | E2E con diferencia real |
| Sustituciones | Implementado en backend | Payload fiscal separado y aprobacion | Documento fiscal persistido |
| Efectivo y vuelto | Implementado | Pago, monto recibido, vuelto, locks e idempotencia | Dos dispositivos simultaneos |
| Yape/Plin/transferencia | Implementado en backend | Referencia, archivo, validacion, rechazo y reintento | Foto real y revision de Caja |
| No cobrado/credito | Implementado | Estados y validaciones especificas | Confirmar politica comercial |
| Doble cobro | Implementado localmente | UUID, locks e idempotencia | Concurrencia real |
| Caja y liquidacion | Implementado | Revision/rechazo, efectivo esperado y cierre automatico | Ruta real completa |
| Comprobante duplicado | Implementado | `can_generate`, bloqueo de ajuste y `Ya generado` | Boleta nueva en runtime |
| Bidones y QR | Implementado en backend | Catalogo, QR, estados y movimientos idempotentes | Camara y QR fisico |
| Estado fisico de bidon | Implementado | Lleno, vacio, danado, reparacion, prestado, vendido y perdido | Validacion fisica |
| Carga y liquidacion de ruta | Implementado | `RouteContainerSettlementService` | Conciliacion fisica |
| Saldo por cliente | Implementado | Depositos y movimientos transaccionales | Varios intercambios reales |
| Presentaciones y precios | Implementado localmente | Reglas por sucursal/canal y snapshots | POS real con presentacion |
| Puntos y canje de 11 | Implementado tecnicamente | Ledger, campana, recompensa e idempotencia | Definir producto final y probar POS |
| Migraciones reversibles | Implementado en pruebas | Cadena, subida y reversa SQLite | Staging tenant y backup real |
| Gate transversal | Implementado y probado | Rutas, controladores, servicios, jobs, APK y POS | Tenant productivo con giro apagado |
| Deploy seguro | Implementado y probado | `flock`, preflight, `--no-build`, marker y rollback | Mantener disco bajo 90 % |

## Evidencia actual

- Commit local/remoto: `ff773b91888bab679e9457c3acaf860a0235c8e5`.
- Release activo: `/var/www/html/smart-release-ff773b918`.
- Docker monta `/var/www/html/smart`, que apunta al release activo.
- Healthcheck correcto: MariaDB, Redis, FPM, worker, scheduler y Nginx.
- HTTP `/login`: 200.
- Suite PHP: 150 pruebas aprobadas.
- Flutter: `flutter analyze` limpio y 20 pruebas aprobadas.
- Playwright: listado de pedidos HTTP 200 y asignacion controlada de `PD01-16`
  HTTP 200; el primer 409 fue un conflicto legitimo porque se envio un
  repartidor anterior distinto del estado actual.
- El disco fue reducido de 90 % a 85 % conservando el release activo y un
  respaldo; no se tocaron volumenes, imagenes ni backups.
- No se ejecutaron migraciones productivas en este deploy.

## Correccion aplicada durante esta auditoria

`PosController` ya no consulta directamente `business_turns` para decidir el
estado de reparto de la vista. Usa `DeliveryBusinessTurnGuard`, por lo que la
tabla ausente produce `active=false` y no un error. Tiene prueba de giro
inactivo y tabla ausente.

## Pendientes que no deben declararse como terminados

1. FCM real con APK cerrada y pantalla bloqueada.
2. Segundo dispositivo y concurrencia real.
3. Foto real de Yape/Plin y aprobacion o rechazo en Caja.
4. QR fisico y estados fisicos de bidones.
5. Offline con APK completamente cerrada.
6. Tenant aislado con `water_distributor.active=false` en runtime.
7. Migracion completa en staging y prueba de rollback.
8. Documento fiscal completo con adicional, faltante o sustitucion persistido.

Hasta cerrar esos puntos, el plan debe considerarse **implementado y
parcialmente certificado**, no completamente certificado.
