# Matriz de aceptacion SmartPlus

> **Corte canónico posterior al despliegue — 2026-10-21.** Prevalece sobre
> los cortes históricos de este documento. Release productivo: `134cde35`,
> activo mediante `/var/www/html/smart -> smart-release-134cde35`. La cuenta
> de servicio FCM está instalada fuera del repositorio y visible para
> FPM/worker/scheduler. Las migraciones tenant de `website_id=5` fueron
> aplicadas con backup identificado antes de ejecutarlas; el preflight pasó
> con disco al 88%. El APK release de producción está instalado en
> `373ead9f`.

> Estado de aceptación: implementación y pruebas automatizadas aprobadas para
> la mayoría de reglas; queda pendiente solo la evidencia E2E controlada de
> pedido nuevo y la validación runtime de `water_distributor` inactivo,
> presentaciones/campaña comercial real y bidones físicos. No confundir esas
> pruebas pendientes con la configuración/deploy, que ya están aplicados.

Estado al 2026-10-20. Esta matriz distingue pruebas locales de pruebas de
integracion; una prueba local no se presenta como evidencia de staging.

| # | Escenario | Estado | Evidencia |
|---:|---|---|---|
| 1 | Producto maestro | Local cubierto | `PresentationPriceResolverTest`, `ContainerCatalogTest` |
| 2 | Varias presentaciones | Local cubierto | migraciones y `ItemUnitTypePointRuleTest` |
| 3 | Precios diferentes | Local cubierto | `PresentationPriceResolverTest` |
| 4 | Solo una presentacion acumula | Local cubierto | `PresentationPointIntegrationServiceTest` |
| 5 | Solo una presentacion canjea | Local cubierto | `PresentationPointIntegrationServiceTest` |
| 6 | Acumular puntos | Local cubierto | `PointLedgerServiceTest` |
| 7 | Canje de 11 puntos | Local cubierto por regla configurable | `PointLedgerServiceTest`, `PresentationPointIntegrationServiceTest` y migracion de campanas |
| 8 | Segundo canje rechazado | Local cubierto | bloqueo de saldo e idempotencia en `PointLedgerServiceTest` |
| 9 | Crear pedido | Pendiente E2E | La API/UI del pedido existe localmente; falta ejecutar el escenario autenticado en demo con datos controlados |
| 10 | Asignar repartidor | Pendiente E2E | La asignación y outbox existen localmente; falta comprobar el flujo autenticado en demo |
| 11 | Notificacion FCM | Parcial local | outbox y reintentos pasan pruebas; falta Firebase real con APK cerrada, pantalla bloqueada y segundo dispositivo |
| 12 | Aceptar desde APK | Parcial local | contrato y APK local pasan; falta conectar el escenario completo contra demo |
| 13 | Cantidades, presentacion y total | Local cubierto | contrato móvil y `presentation_contract_test.dart` |
| 14 | Registrar efectivo | Local cubierto | `DeliveryRouteCashSettlementServiceTest` y cola offline Flutter; falta ejecutar flujo real en demo |
| 15 | Registrar Yape con foto | Local de contrato | validaciones en `OrderNoteController`; falta demo |
| 16 | Validar cobro en caja | Local cubierto | API y panel web de liquidaciones con revision idempotente `approved/rejected`; falta UI demo |
| 17 | Entregar bidon | Local cubierto | `ContainerMovementServiceTest` y QR |
| 18 | Recibir bidon vacio | Local cubierto | movimientos y conciliacion de ruta |
| 19 | Bidon dañado | Local cubierto | estados y movimientos |
| 20 | Cerrar ruta | Local cubierto por servicio | `DeliveryRouteAutoFinisherTest`; falta prueba E2E |
| 21 | Ultima ubicacion | Parcial local | API/GPS implementados; falta validar UI demo durante una ruta activa |

## Puerta externa actual

El objetivo E2E vigente es `https://demo.sistemax.net.pe`. El staging anterior
fue retirado y no forma parte de la validación actual. La suite no permite
configurar staging ni producción como destino.

No se ejecutaron migraciones tenant sobre MariaDB remoto, pruebas destructivas
en producción, commits, push ni deploy.
## Actualizacion posterior

| # | Escenario | Estado | Evidencia |
|---:|---|---|---|
| 22 | Diferencia de entrega requiere aprobacion antes del cobro | Implementado localmente | `approval_status`, endpoint de revision protegido por `water_distributor`, migracion reversible; falta prueba E2E con caja y APK |

La comprobación de demo del 2026-10-20 pasó los dos smoke tests: `/login`
responde correctamente y `/pos` exige sesión sin devolver error HTTP. Esto no
prueba todavía el flujo autenticado de reparto.
La prueba `DeliveryAdjustmentApprovalServiceTest` cubre la aprobacion
idempotente de varias diferencias con una sola operacion.

## Estado canonico posterior

La matriz anterior conserva el historial de auditoria. Para la decision actual:

- Los escenarios 1-8, 13, 17-20 y 22 estan cubiertos localmente, no en E2E.
- Los escenarios 9-12, 14-16 y 21 requieren prueba contra demo con sesion y
  datos de prueba controlados.
- FCM sigue siendo parcial: las pruebas de reintento usan transporte simulado.
- La entrega central sigue siendo parcial porque pago, bidones y puntos no
  estan demostrados en una sola transaccion E2E.
- El gate `water_distributor` tiene evidencia backend; falta evidencia visual
  de menu y respuesta `403` dentro de la APK.
- El objetivo de Playwright vigente es solo `demo.sistemax.net.pe`; no se debe
  ejecutar la suite contra staging retirado ni contra produccion.

## Corte canónico 2026-10-21

- El flujo autenticado de pedido demo, asignación, FCM con la aplicación fuera
  de pantalla y apertura del pedido correcto ya fue probado con `PD01-11`.
- El release productivo vigente incluye el commit funcional
  `8cf5f9ece18c910b4d9e0f98c0481cf98163f4f6`; Playwright post-deploy terminó
  4/4 y los contenedores SmartPlus quedaron saludables.
- La interfaz web ahora solicita observación para los estados terminales que
  el backend valida como obligatorios.
- Persisten como pendientes de certificación E2E: segundo dispositivo,
  concurrencia, caída real de Firebase, cobro Yape/Plin con foto y revisión de
  Caja, ruta con liquidación, QR físico, offline cerrado y gate runtime con el
  giro de agua inactivo.

## Actualizacion de gate en servicios internos

Ademas de login, API, web y APK, los servicios internos de reparto y bidones
ahora exigen el giro `water_distributor` activo. Esto cubre movimientos,
depositos, QR, carga/liquidacion de ruta, liquidacion de efectivo y aprobacion
de diferencias. La validacion automatizada directa del movimiento de bidon
esta incluida; aun falta evidencia runtime autenticada con el giro activado y
desactivado.
## Actualizacion de pruebas y seguridad

- La aceptacion online y la aceptacion offline sincronizada inician el
  tracking nativo y estan cubiertas por `delivery_repository_offline_test.dart`.
- `tests/e2e/demo-delivery-security.spec.js` verifica, cuando se proporcionan
  credenciales locales, que la lista de pedidos no exponga `password` ni
  `api_token`.
- La prueba E2E de seguridad se omitio en la ejecucion sin credenciales; la
  comprobacion autenticada manual contra demo sigue fallando hasta desplegar
  la sanitizacion local.

- El POS tampoco expone reglas nuevas de puntos cuando `water_distributor` esta
  inactivo, aunque las tablas existan. `PosPresentationPointMetadataTest`
  cubre los estados activo e inactivo. El sistema legacy de puntos se conserva
  para otros giros y no forma parte de la funcionalidad nueva de presentaciones
  de agua.

## Correcciones posteriores de activacion

- El libro nuevo de puntos tambien valida el giro dentro del servicio, no solo
  en su servicio integrador.
- La APK elimina la cache visible cuando recibe `403` por giro inactivo y no
  abre pedidos desde notificaciones antiguas en ese estado.
- La confirmacion de entrega ya no tiene rutas ni botones en el panel web; el
  actor de confirmacion es el repartidor desde el APK.
- Suite PHP actual: 100 pruebas aprobadas; Flutter: `flutter analyze` y
  `flutter test` aprobados (15 pruebas)
  por espacio temporal insuficiente.

## Verificacion adicional posterior

- Se eliminaron los metodos muertos de confirmacion web y no quedan
  referencias a `deliveryLocation`, `deliveryManualComplete` ni a sus rutas.
- La prueba autenticada de seguridad contra demo continua fallando porque el
  servidor remoto aun devuelve `password` bajo `sale_notes[*].user`; la
  correccion local pasa las pruebas unitarias y no se ha desplegado.

- El endpoint web de cambio de estado rechaza `delivered`; la confirmacion
  final queda reservada al flujo movil del repartidor.
- La prueba E2E de seguridad comprueba tambien metadatos de contrasena y la
  forma exacta de `sale_notes`; la prueba queda pendiente solo de ejecutarse
  contra un release corregido en demo.

## Auditoria de continuidad 2026-10-20

| Requisito | Resultado actual | Evidencia |
|---|---|---|
| Sanitizacion de datos sensibles en pedidos de reparto | Corregido localmente y probado | 3 pruebas unitarias; ruta nombrada y deteccion por controlador |
| Sanitizacion en demo | Validado | Playwright autenticado: 1 aprobado; no devuelve credenciales internas |
| Release reversible | Parcial | Intento de demo revertido a HTTP 200; release de prueba y backup conservados |
| Migraciones remotas | Pendiente | No se ejecutaron durante este intento |
| Cierre manual de ruta | Eliminado | El APK, API y cola offline ya no exponen `finishRoute`; solo queda el auto-finisher |
| FCM con APK cerrada | Configurado; prueba E2E real pendiente | El servidor monta la cuenta de servicio en los contenedores y el APK usa `smartplus-delivery-production`; falta generar una asignacion real y verificarla con la app cerrada |

La correccion de seguridad se desplego en un release aislado y reversible. El
smoke de demo paso 2 pruebas, la prueba autenticada de seguridad paso 1 y
`/login` respondio HTTP 200. Las migraciones y el resto de la funcionalidad del
plan no se ejecutaron en este release.

## Estado vigente despues de la auditoria

- El cierre de ruta es automatico; no existe accion manual de finalizar.
- El APK Android detiene el rastreo ante `403` por giro
  `water_distributor` desactivado y conserva el rastreo ante fallas temporales
  de red.
- La migracion de reglas de puntos quedo ordenada antes de la extension de
  campanas y la prueba de cadena incluye `tenant_settings`.
- Una presentacion legacy sin regla nueva de puntos no pierde su fallback fuera
  del giro de agua.

## Evidencia movil actualizada

- Flutter: 15 pruebas y `flutter analyze` aprobados.
- APK debug compilado e instalado en el dispositivo Android conectado.
- Playwright demo: 3 pruebas aprobadas.
- La validacion interactiva del APK continua pendiente porque el dispositivo
  quedó bloqueado tras la instalación.

## Evidencia adicional de asignacion

- `DeliveryAssignmentNotificationTest` verifica que una asignacion pendiente
  genere el outbox de FCM y que el repartidor no pueda cambiarse ni
  desasignarse cuando el pedido ya esta `en_route`.

## Corte vigente de auditoria

Este bloque reemplaza los conteos historicos anteriores de esta matriz.

- Suite PHP local vigente: **105 pruebas aprobadas**.
- Suite Flutter vigente: **17 pruebas aprobadas**; `flutter analyze` sin
  incidencias.
- Playwright autenticado en `https://demo.sistemax.net.pe/pos`: listado,
  contexto de reparto, liquidaciones y filtros de estado respondieron HTTP
  200. El listado actual contiene 3 pedidos aceptados y 3 entregados.
- El intento controlado de crear un pedido nuevo no pudo continuar: el tenant
  demo responde que falta `order_note_items.item_unit_type_id`. No se repitio
  la operacion para evitar duplicados y no se ejecuto una migracion remota.
- El APK fisico `373ead9f` carga pedidos, cantidades, precios, totales,
  direcciones y contactos; detalle, retroceso y pantalla de ruta pasaron la
  comprobacion. La aceptacion nueva, FCM con APK cerrada, GPS durante una ruta
  y cobro E2E siguen sin certificarse con una entrega nueva; la cuenta de
  servicio FCM ya esta disponible en produccion, pero falta ejecutar el caso
  real con notificacion cerrada.
- Todas las funciones nuevas de reparto, bidones, presentaciones y puntos
  mantienen como condicion el giro `water_distributor` activo. La evidencia
  actual de esa condicion es automatizada/local; falta la prueba runtime con
  un tenant cuyo giro este inactivo.
- Playwright E2E ejecutado sin credenciales en el proceso: 2 smoke tests
  aprobados y 2 escenarios autenticados omitidos de forma segura. La misma
  consulta autenticada de solo lectura fue comprobada manualmente contra el
  demo y respondio HTTP 200.
- Se elimino tambien la opcion muerta `Entregado` de la vista antigua de
  ordenes; la confirmacion final sigue reservada al APK del repartidor y el
  endpoint web conserva el rechazo 422 como defensa.
- La prueba del gate ahora cubre login de APK, API movil y seguimiento
  administrativo; los tres escenarios reciben bloqueo cuando el giro esta
  inactivo.
