Skip to content

Plan Soterex — Cierre MVP1 + Módulo Caja (v2, 2026-07-28)

Reemplaza a plan-cierre-mvp1.md. Incorpora las decisiones de la reunión "Avances Soterex" (2026-07-28) y el cambio de routing del Backoffice. Repo: git@github.com:raxardev/soterex.git · main (dev) → staging → production. Dividido en entregas independientes (E1–E7): cada una es un branch + PR propio, ejecutable por Claude Code de punta a punta, con review (code-reviewer) antes de merge.


Decisiones tomadas (fuente: reunión 2026-07-28 + definiciones de Carlos)

  1. Backoffice sin dashboard. La ruta default del rol Backoffice es la pantalla "Pago" (buscador + resultado exacto + "Mis transacciones"). La pantalla vive dentro de la sección Operación del sidebar, con el nombre "Pago". Referencia pixel: backoffice-home-final.html.
  2. Módulo Caja: opcional por país, habilitable desde Ubicaciones. Caso de uso concreto: Guatemala (sin EPOS). Ecuador no lo activa (sigue operando con su EPOS). Cuando el módulo está apagado, todo funciona exactamente como hoy.
  3. Dos saldos independientes: prefondeo por país (USD) + saldo de caja por sucursal (moneda local).CORREGIDO (2026-08-05, ver ADR-007): son tres capas, porque el contrato nuevo mete a la Holding entre Soterex y el país.
    • Prefondeo Holding — global, en USD. Es el pool que ya existe: descuenta amount + fee.
    • Prefondeo País (nuevo) — por país, en USD. Descuenta solo principales; las comisiones se liquidan a fin de mes entre Holding y Soterex. Admite saldo negativo.
    • Saldo de caja por sucursal — sin cambios respecto de lo ya implementado.
  4. Cada pago descuenta de ambos CORREGIDO (2026-08-05, ADR-007): cada pago descuenta de las tres capas, con reglas distintas — Holding amount + fee, País amount, Caja amount en la moneda de pago del país. Mover plata del país a una caja no descuenta el prefondeo del país (es distribución banco→cajón, no gasto).
  5. Tipo de cambio: editable desde Ubicaciones, por país, solo aplica a pagos. Debe quedar historial completo de cada cambio (valor, vigencia, quién, cuándo) y registrarse como evento de auditoría. AGREGADO (2026-08-05, ADR-007): el TC deja de ser un requisito universal del pago. Guatemala no tiene autorización para cambio de divisa y paga en dólares, así que la moneda de pago pasa a ser configurable por país (countries.pago_en_moneda_local). El módulo de TC no se toca: queda listo para cuando llegue la autorización o el esquema de casa de cambio tercerizada.
  6. Apertura y cierre de caja diarios por sucursal (saldo inicial → operaciones → cierre con cuadre). CORREGIDO (2026-08-05, ADR-007): el saldo inicial no se tipea — se hereda del saldo de cierre de la sesión anterior de esa caja (cero en la primera apertura). Las diferencias se resuelven por AJUSTE (falta/sobra plata) o FONDEO (entra plata nueva), nunca editando el inicial.
  7. Supervisor: tiene la acción de agregar saldo (fondear) a cada caja. La aprobación de pagos por supervisor se decidió NO implementar — el flujo de pago queda como está hoy. (Documentar como decisión explícita, no como omisión.)
  8. Wizard de pago con steps documentales (en este orden): ① carta firmada → ② scan de la identificación → ③ foto de la persona sosteniendo la identificación. La foto la toma el operador con su dispositivo y se sube.
  9. Papeleta / comprobante de pago: membretada, con monto en moneda local y en USD (+ TC aplicado), en formato de impresión térmica de papel angosto. Queda adjunta a la ficha de la transacción y es reimprimible.
  10. Comisiones: son un valor fijo por unidad (no porcentaje), editable por país como está hoy.CORREGIDO (2026-07-31, ver doc/architecture/ADR-005-modulo-caja-doble-saldo.md): la comisión no es editable por CIS — la devuelve Soterex granular por transacción (fee en SendRequest, ver doc/site/public/openapi.yaml), y ya es información restringida desde el 25/07 (doc/functional/.../02-roles-permisos.md §2.5: solo visible en Reportes y Dashboard de Supervisor, nunca en pantallas operativas). El campo commission_pct editable de ABM Países se elimina — no reflejaba la realidad (estaba desconectado del fee real desde el día 1: el mock de Soterex usa 1.5% hardcodeado, ABM Países mostraba 3.5%). Las comisiones solo descuentan del prefondeo en USD (ya es así hoy: amount + fee, sin cambios), nunca de la caja; de la caja de la sucursal se descuenta únicamente el monto de la transacción en moneda local.
  11. Fondeo de caja: solo el rol Supervisor puede sumar saldo a la caja de la sucursal.
  12. Pantalla de Pago (con módulo Caja activo): muestra el saldo actual de la caja de la sucursal y tiene un validador de saldo suficiente — no se puede confirmar un pago si la caja no cubre el monto en moneda local. PRECISADO (2026-08-05, ADR-007): la caja es la única validación de saldo del pago. Se elimina el corte por prefondeo (INSUFFICIENT_PREFUNDING) en países con módulo Caja — la plata del cajón manda. En países sin módulo Caja (Ecuador/EPOS) se mantiene validación, ahora contra el prefondeo del país.
  13. Apertura de caja: registra a los dos usuarios involucrados: el supervisor y el usuario backoffice.CORREGIDO (2026-08-05, ADR-007): se elimina la autorización del Supervisor para abrir y cerrar caja — la pidió sacar tesorería al ver que el ledger inmutable ya da la trazabilidad, y exigía que el Supervisor estuviera físicamente en el PDV. La apertura sigue generando su asiento de depósito y su comprobante membretado, con un solo usuario.
  14. Cierre de caja: es por monto total (sin conteo de denominaciones). Genera un comprobante de cierre membretado con saldo inicial, todos los movimientos involucrados y saldo final, más un asiento de retiro por el total para que la caja quede en cero. Ambos comprobantes (apertura y cierre) quedan disponibles en la lista de movimientos.
  15. Papeleta a 58 mm de ancho. Membrete: el sencillo con el logo de CIS (aplica a la papeleta y a los comprobantes de apertura/cierre).
  16. Tipo de cambio: lo pueden editar Admin y Supervisor.
  17. Foto del step ③: no es obligatoria (opcional siempre, sin configuración adicional).
  18. Previsualización: todos los documentos subidos (carta, scan, foto) tienen preview con buen diseño en el wizard y en la ficha de la transacción.

E1 — Quick wins (bugs + dashboard general)

Sin dependencias. Ideal primer PR.

  • E1.1 Fix filtro por PDV en la lista de transacciones: reproducir en staging; revisar cadena completa (param del componente Vue → request → Form Request → scope del query). Test de feature (Laravel) + test de componente.
  • E1.2 Dashboard general (roles que sí lo tienen — el Backoffice ya no): convertir el gráfico actual a barras; agregar: pagadas por día (30 días), transacciones por estado, top PDVs por monto, monto pagado por semana. Tokens y tipografías existentes; ejes con moneda local y fechas dd/mm.

E2 — Routing Backoffice + pantalla "Pago"

Depende de: nada (puede ir en paralelo con E1). El scoping backend va acá porque la pantalla no sirve sin él.

  • E2.1 Backend — scoping duro del rol Backoffice (no solo UI):
    • Listados: solo transacciones donde el usuario participó (modified_by / tabla de participación).
    • Búsqueda: exacta por n° de transacción, o por nombre completo del beneficiario (mín. nombre + apellido), máx. 5 resultados, log de auditoría por búsqueda (quién/qué/cuándo), rate limiting anti-enumeración, documento enmascarado en el resultado.
    • Tests: IDOR entre usuarios, máscara, rate limit.
  • E2.2 Frontend — pantalla "Pago":
    • Nueva entrada "Pago" en la sección Operación del sidebar (visible según permiso).
    • Réplica de backoffice-home-final.html: input terminal >_, card de resultado con CTA "Iniciar pago", panel "Mis transacciones", empty state con cursor (respeta prefers-reduced-motion). Componentes: TerminalSearchInput, MatchResultCard, MyTransactionsLog, EmptyTerminalState.
    • Routing: al loguearse un usuario Backoffice, la ruta raíz redirige a "Pago". El rol Backoffice no ve el Dashboard (guard de ruta + item oculto en sidebar + endpoint de dashboard denegado para el rol).
    • Dark mode con las variantes -dark existentes. Contraste AA verificado.

E3 — Permisos desde la ficha de usuario

Sin dependencias de E2/E4. El tab separado desaparece.

  • E3.1 UX: sección "Permisos" inline en crear/editar usuario: rol base (Cajero PDV, Supervisor, Backoffice, Admin) que precarga matriz módulo × acción (ver/crear/editar/aprobar/exportar), checkboxes de override con indicador visual de origen (rol vs. manual). Guardado atómico usuario+permisos.
  • E3.2 Backend: validación de no-escalación (nadie otorga más de lo que tiene, salvo Admin), auditoría de cambios de permisos, tests (asignación, revocación, escalación denegada, rollback).
  • E3.3: incluir en la matriz los permisos nuevos que introduce E4 (gestión de caja, edición de TC, fondeo, apertura/cierre) aunque el módulo llegue después — dejan de requerir migración de permisos luego.

E4 — Módulo Caja (backend + configuración)

Depende de: E3 (permisos). Es la entrega más grande; puede subdividirse en E4a (modelo+config) y E4b (operatoria) si el PR crece demasiado.

  • E4.1 Configuración en Ubicaciones:
    • Flag modulo_caja por país (on/off). Con el flag apagado: cero cambios visibles ni de comportamiento.
    • Moneda local del país (ISO 4217).
    • Tipo de cambio: valor vigente editable solo por Admin y Supervisor + tabla de historial (exchange_rates: país, valor, vigente_desde, creado_por, creado_en). Editar = crear registro nuevo, nunca sobreescribir. Evento de auditoría en cada alta.
    • Comisión por país: se mantiene como está hoy — valor fijo por unidad (no porcentaje), editable por país.
  • E4.2 Modelo de datos:
    • cash_boxes (caja por sucursal/ubicación): saldo actual en moneda local.
    • cash_sessions (apertura/cierre): sucursal, fecha, saldo apertura, saldo cierre, abierto_por (backoffice) + autorizado_por (supervisor), cerrado_por, referencia a los comprobantes de apertura y cierre.
    • cash_movements: tipo (deposito_apertura | fondeo | pago | ajuste | retiro_cierre), monto local, monto USD, TC aplicado, referencia a transacción cuando aplica, usuario, timestamp. Inmutable (correcciones = movimiento inverso).
    • El prefondeo por país sigue como está (USD); solo se le agrega el descuento automático por pago con Caja activa.
  • E4.3 Operatoria:
    • Fondeo de caja — acción exclusiva del Supervisor: suma saldo local a una caja, con motivo y auditoría. Ningún otro rol puede sumar valor a la caja.
    • Apertura de caja: requiere al supervisor y al usuario backoffice (ambos registrados). Genera un asiento de depósito por el saldo inicial y un comprobante de apertura membretado (logo CIS) con ambos usuarios, fecha/hora, sucursal y monto. No se puede pagar con caja cerrada.
    • Cierre de caja: por monto total. Genera el comprobante de cierre membretado con saldo inicial, el detalle de todos los movimientos de la sesión y el saldo final, más un asiento de retiro por el total que deja la caja en cero. Los comprobantes de apertura y cierre quedan accesibles desde la lista de movimientos.
    • Descuento en el pago (transaccional, todo-o-nada), con Caja activa:
      • Prefondeo del país (USD): se descuenta el monto de la transacción + la comisión por unidad.
      • Caja de la sucursal (moneda local): se descuenta únicamente el monto de la transacción convertido al TC vigente — la comisión nunca toca la caja.
      • El TC usado queda congelado en el movimiento y en la transacción. Validaciones: saldo suficiente en ambos saldos, caja abierta, TC vigente existente.
  • E4.4 Auditoría: eventos en el módulo de Auditoría existente para: edición de TC, fondeo, apertura (con ambos usuarios), cierre, ajuste, y pago con descuento en ambos saldos (con TC aplicado).
  • E4.5 Comprobantes de apertura y cierre: PDF membretados (logo CIS, mismo motor que la papeleta de E5), formato térmico 58 mm, accesibles y reimprimibles desde la lista de movimientos.
  • E4.6 Tests: descuento atómico con rollback si falla una pata; comisión descuenta solo del prefondeo USD y jamás de la caja; pago rechazado con caja cerrada / saldo insuficiente en cualquiera de los dos / sin TC; fondeo denegado a roles distintos de Supervisor; apertura sin los dos usuarios = inválida; cierre deja saldo exactamente en cero con el asiento de retiro; historial de TC intacto tras ediciones; flag de país apagado = comportamiento actual intacto.

E5 — Wizard de pago con documentos + papeleta

Depende de: E2 (pantalla Pago) y E4 (descuento doble, TC). Con Caja desactivada, el wizard aplica igual pero sin la parte de saldos locales — confirmar si los steps documentales son solo para países con Caja o globales (asumo: solo países con módulo Caja activo, ya que reemplazan el proceso del EPOS).

  • E5.1 Wizard "Iniciar pago" (desde la card de resultado), steps:
    1. Carta firmada — upload PDF/imagen, con previsualización bien diseñada (thumbnail + vista ampliada), validación de tipo y tamaño.
    2. Scan de identificación — upload imagen/PDF, misma previsualización.
    3. Foto de la persona con la identificaciónopcional (se puede saltar). Captura desde cámara del dispositivo del operador (input capture) o upload, con preview.
    4. Confirmación — resumen: beneficiario, monto USD, TC vigente, monto en moneda local, saldo actual de la caja y saldo resultante. Sin comisión (corregido 2026-07-31: la comisión es información restringida desde el 25/07, no se muestra en pantallas operativas — el wizard lo opera Backoffice, el rol al que esa regla se lo prohíbe explícitamente; ver ADR-005). Validador de saldo: si la caja no cubre el monto en moneda local (o el prefondeo no cubre monto + comisión — el prefondeo sigue validando esto server-side aunque el número no se muestre), el botón de confirmar se bloquea con mensaje claro de qué saldo falta. Confirmar ejecuta el pago (descuentos de E4.3) y genera la papeleta.
  • E5.1b Saldo visible en la pantalla "Pago": con módulo Caja activo, la pantalla principal de Pago (E2.2) muestra el saldo actual de la caja de la sucursal de forma permanente (junto al estado de sesión de caja abierta/cerrada).
  • E5.2 Almacenamiento de documentos: S3 privado (bucket ya en Terraform o agregarlo), URLs firmadas de corta vida, nunca públicos; cifrado at-rest; asociados a la transacción; visibles en la ficha de la transacción con permiso y con la misma previsualización del wizard.
  • E5.3 Papeleta / comprobante:
    • PDF generado server-side, membrete sencillo con logo CIS, formato térmico 58 mm: logo, n° de transacción, fecha/hora, sucursal, operador, beneficiario + documento, monto en USD y en moneda local + TC aplicado, leyenda legal.
    • Se adjunta a la ficha de la transacción; reimprimible desde la ficha; botón de imprimir dispara el diálogo del navegador con CSS @page a 58 mm.
    • El mismo motor de generación se reutiliza para los comprobantes de apertura y cierre de caja (E4.5).
  • E5.4 Ficha de la transacción: nueva sección "Documentación del pago" con los 3 documentos + la papeleta, con auditoría de quién los ve/descarga.
  • E5.5 Tests: wizard no permite confirmar sin carta y scan (la foto sí puede faltar); validador bloquea confirmación con saldo insuficiente en caja o prefondeo; papeleta con montos, comisión y TC correctos; documentos inaccesibles sin permiso (URL firmada vencida = 403); reimpresión no regenera con TC nuevo (usa el congelado).

E6 — Auditoría de seguridad completa (staging = producción)

Depende de: E2–E5 mergeadas (audita el estado final). Guía: skill security.

  • OWASP Top 10 sobre la app: verificación de token Firebase en backend, IDOR (crítico con el scoping de E2 y los documentos de E5), inyección (buscador), XSS, validación de notificaciones entrantes de Soterex (firma, idempotencia/replay), secretos fuera de código y logs.
  • Nuevo foco por E4/E5: PII sensible (documentos de identidad, fotos de personas) — acceso mínimo, URLs firmadas, retención definida, cifrado, no-logueo; integridad de saldos (imposibilidad de doble gasto con requests concurrentes — test de carrera sobre el descuento doble); manipulación de TC (solo roles autorizados, historial inmutable).
  • Infra: revalidar consenso (doc/architecture/infra-consensus.md), WAF/rate limiting cubriendo login + búsqueda + APIs Soterex + uploads, security groups, Aurora privada, backups con restore probado, bucket S3 de documentos bloqueado a público.
  • Entregable: doc/security/audit-mvp1.md con hallazgos por severidad; críticos y altos se corrigen dentro de esta entrega.

E7 — Documentación total

Última entrega; documenta el estado final. Guía: skill tech-writer.

  • Análisis funcional: actualizar con el rol Backoffice sin dashboard, pantalla Pago, módulo Caja completo (saldos, TC, apertura/cierre, fondeo), wizard documental, papeleta, y la decisión explícita de no implementar aprobación por supervisor.
  • Flujos/diagramas: flujo de pago con y sin módulo Caja, flujo de fondeo, apertura/cierre, ciclo de vida del TC.
  • ADRs nuevos: pantalla Pago como home del Backoffice; módulo Caja opcional por país; modelo de doble saldo y descuento; TC con historial inmutable; papeleta térmica; no-aprobación de supervisor.
  • Manual del usuario (BookStack): capítulos nuevos con screenshots reales (Playwright, como se hizo antes): Pago paso a paso, gestión de caja, edición de TC, reimpresión de papeleta.
  • README / doc/operations: variables nuevas, bucket S3, runbook de deploy actualizado, qué hacer ante descuadre de caja.
  • CHANGELOG del cierre MVP1 + Caja.

Orden y dependencias

E1 (quick wins) ──────────────┐
E2 (Pago + scoping) ──┐       │
E3 (permisos) ─────┐  │       │
                   └──┴─→ E4 (Caja) ─→ E4b (ajustes del cliente) ─→ E5 (wizard) ─→ E6 (seg.) ─→ E7 (docs)
  • E1, E2 y E3 pueden correr en paralelo (branches separados).
  • E4 arranca cuando E3 mergeó (permisos) — E2 solo hace falta para E5.
  • E4b (agregada el 2026-08-05) es la entrega correctiva que sale de la revisión del módulo Caja con el cliente: prefondeo en tres capas, caja sin Supervisor, moneda de pago por país. Va antes de E5 porque el wizard depende de la moneda de pago y de qué saldo valida el pago. Plan detallado en 2026-08-05-e4b-ajustes-caja-reunion-cliente.md, decisiones en ADR-007.
  • Cada entrega: branch → PR → review con code-reviewer → merge a main → deploy a staging → verificación manual → recién entonces arranca la dependiente.
  • Todos los puntos abiertos de la primera versión del plan quedaron resueltos e incorporados a la lista de decisiones (comisión por unidad, fondeo solo Supervisor, saldo visible + validador, comprobantes de apertura/cierre con doble usuario, cierre por monto total a cero, foto opcional, previews, 58 mm, membrete CIS, TC editable por Admin y Supervisor).

Documentación viva — se actualiza junto con el código, no es un anexo aparte.