Análisis Funcional: Integración Soterex (reemplazo Google Sheet)
Date: 2026-07-24 Status: Draft Autor: Product Owner Agent (Raxar Factory methodology) Fuentes: Definicion_integracion_soterex.vtt, Definicion_integracion_soterex(2).vtt, C2P_V14_Transactional_APIs (Soterex), respuestas del cuestionario de discovery (2026-07-24)
0. Resumen del alcance
La web app reemplaza únicamente el proceso manual de carga vía Excel/Google Sheet que hoy ejecuta CIS LATAM (marca "Zoom" en otros países) para procesar las transacciones que envía el aliado Soterex.
- Reemplaza: carga manual de Excel, macro generadora de MTCN, cálculo manual de comisión y descuento de prefondeo.
- No reemplaza: el flujo de papeleta/comprobante de pago (queda fuera de alcance) ni el sistema EPOS (mal referenciado como "hipos" en la charla) — no hay integración con EPOS en esta etapa.
- La integración con Soterex es bidireccional:
- WebApp → Soterex: la WebApp llama a
tokenC2P(auth) y luego aSendRequestmediante un cron cada 30 minutos para tomar las transacciones pendientes registradas por Soterex y generarles el MTCN. - WebApp → Soterex:
Cancel— cuando Backoffice cancela desde la webapp, esta llama al endpointCancelde Soterex. - WebApp → Soterex:
Notifications(webhook consumido por Soterex) para informar el MTCN generado y los cambios de estado (ACCEPTED, CANCELLED, PAID). - ⚠️ Falta definir cómo llega a la WebApp una cancelación iniciada por Soterex (ver Pregunta Abierta #2 revisada), dado que todos los endpoints salientes confirmados son WebApp → Soterex.
- WebApp → Soterex: la WebApp llama a
- Lanzamiento inicial: Guatemala, con diseño preparado para escalar a más países (ABM de Países). La comisión CIS es editable por país y el saldo de prefondeo es un pool por país (no por PDV individual).
- Autenticación MVP1: solo usuario/contraseña (usuario = mail). El cliente ya usa Microsoft 365 con dominio propio, pero el SSO (Google y Microsoft) queda para una fase posterior, no para el MVP1.
- Modelo de roles multipaís: un mismo usuario puede tener roles distintos en distintos países (ej: Admin en Guatemala y Supervisor en otro país), y un Supervisor puede estar a cargo de más de un PDV. Toda esta asignación debe ser editable (ver sección 2.3).
- Todo el proceso debe quedar con log completo y trazabilidad (transacciones, cambios de estado, movimientos y logins).
1. Sitemap
Nota: No existe pantalla de "papeleta" ni de "punto de venta" separada — el punto de venta opera con el rol Backoffice dentro del mismo sitemap.
2. Matriz de Roles / Permisos (configurable por Admin)
Definición (2026-07-24): la matriz de roles no es fija — es un módulo de configuración editable por el rol Admin (ABM Roles y Permisos, agregado al Sitemap en 1.). Para cada módulo/recurso del sistema, el Admin puede activar/desactivar 3 permisos por rol: Leer (L), Escribir (E), Borrar (B), con toggles on/off.
Regla de dependencia confirmada por el cliente: si Borrar = ON, entonces Escribir se activa automáticamente y no puede desactivarse mientras Borrar siga ON (Borrar depende de Escribir). Por consistencia del mismo patrón, se asume además que Escribir = ON requiere Leer = ON (no se puede escribir algo que no se puede leer) — a confirmar con el cliente, queda como sub-punto de la Pregunta Abierta #5.
Esto significa que el módulo de roles pasa a ser datos de configuración (seed), no un requisito fijo de negocio. Los 3 roles detectados en la charla (Backoffice, Supervisor, Admin) se cargan como valores iniciales por defecto, editables luego desde ABM Roles y Permisos.
2.1 Matriz por defecto (seed inicial, editable desde Admin)
| Módulo / Recurso | Backoffice (L/E/B) | Supervisor (L/E/B) | Admin (L/E/B) |
|---|---|---|---|
| Transacciones (listado + detalle) | L·E·— | L·E·— | L·E·B |
| Cambio de estado a PAID | — (incluido en Escribir de Transacciones) | ⚠️ a confirmar | ⚠️ a confirmar |
| Cancelar transacción | — (incluido en Escribir de Transacciones) | ⚠️ a confirmar | ⚠️ a confirmar |
| Prefondeo (asientos, pool por país) | L·—·— | L·E·— | L·E·B |
| Reportes contables (estado de situación) | —·—·— | L·—·— | L·—·— |
| Dashboard de volumen/comparativas por país y PDV | ⚠️ a confirmar | L·—·— | L·—·— |
| ABM Usuarios | —·—·— | —·—·— | L·E·B |
| ABM Países (incluye % comisión por país) | —·—·— | —·—·— | L·E·B |
| ABM Estaciones / PDV | —·—·— | —·—·— | L·E·B |
| ABM Configuración (timeout sesión) | —·—·— | —·—·— | L·E·B |
| ABM Roles y Permisos | —·—·— | —·—·— | L·E·B |
| ABM Asignación de Roles Multipaís/PDV | —·—·— | —·—·— | L·E·B |
| Logs de auditoría (movimientos y logins) | —·—·— | L·—·— | L·—·— |
Esta tabla es el seed inicial, no una regla rígida: el Admin puede reconfigurar cualquier celda desde
ABM Roles y Permisos, respetando la dependencia Borrar→Escribir(→Leer). Los ⚠️ siguen abiertos (ver sección 6) porque ahora son simplemente el valor por defecto sugerido, no una restricción de negocio confirmada.
2.2 ¿Se necesita UI/UX en esta etapa?
No. En esta fase (Análisis Funcional del Product Owner) alcanza con dejar definida la regla de negocio (matriz configurable, dependencia Borrar→Escribir) y el módulo en el sitemap. El diseño visual del componente de toggles (cómo se ve la grilla, si se bloquea visualmente el toggle de Escribir cuando Borrar está ON, etc.) es responsabilidad del agente ui-engineer en la etapa de diseño, y ya quedó anotado como señal de handoff en la sección 7.
2.3 Asignación de Roles Multipaís / Multi-PDV (confirmado 2026-07-24)
Esta es una dimensión adicional a la matriz L/E/B de la sección 2.1 (que define qué puede hacer cada rol) — acá se define qué rol tiene cada usuario, en qué país, y en qué PDV, y también debe ser editable desde Admin (ABM Asignación de Roles Multipaís/PDV).
Reglas confirmadas por el cliente:
- Un mismo usuario puede tener roles distintos en distintos países (ej: Admin en Guatemala y Supervisor en otro país).
- Un Supervisor puede estar a cargo de más de un PDV.
- Toda esta lógica de asignación (usuario × país × rol, y supervisor × PDVs) debe ser editable, no fija.
Nota de diseño para el
architect: esto implica que el control de acceso no es simplemente "Usuario → Rol", sino "Usuario → (País, Rol, [PDVs])" — cada sesión/consulta debe filtrar datos según el conjunto de países/PDVs donde el usuario tiene un rol asignado.
2.4 ⚠️ CORRECCIÓN (2026-07-25): el PDV de una transacción NO se conoce al ingresar — se asigna recién al resolverla
Esto corrige una implementación ya hecha en M1 — quedó documentado acá porque afecta directamente el alcance por PDV descripto en 2.3, y porque el criterio de aceptación original de M1 ("el listado no muestra transacciones... sin PDV") es exactamente el error inverso: si las transacciones entran sin PDV (como corresponde), esa regla haría que ningún Backoffice viera jamás una transacción pendiente.
Regla correcta:
- Soterex/
SendRequestno informa PDV — a esa altura es imposible saberlo. Una transacciónACCEPTEDrecién ingresada no tiene PDV asignado, solo país. - Todas las transacciones
ACCEPTEDde un país conforman una bolsa compartida — cualquier Backoffice/Supervisor con acceso a ese país (sin importar a qué PDV específico esté asignado) puede verlas y tomarlas. - El PDV recién se define cuando un usuario la resuelve (la pasa a
PAIDoCANCELLED): en ese momento se graba qué usuario y de qué PDV la resolvió (el PDV activo de ese usuario en su sesión — ver Pregunta Abierta nueva más abajo sobre qué pasa si el usuario tiene más de un PDV asignado). - El acotamiento por PDV de la matriz de permisos (2.3) aplica a transacciones ya resueltas (para reporting/auditoría por PDV), no a las
ACCEPTEDpendientes — esas son visibles a nivel país para cualquier Backoffice/Supervisor con acceso a ese país.
Requisito reforzado — verificación hasta el último momento: como ahora varios cajeros de distintos PDVs pueden estar mirando la misma transacción pendiente al mismo tiempo (comparten la bolsa del país), el riesgo de que dos personas intenten resolver la misma transacción a la vez sube — no es un caso raro, es esperable. El sistema tiene que volver a verificar el estado actual de la transacción justo antes de confirmar el cambio (no alcanza con haberlo chequeado cuando se abrió la pantalla) — si otro usuario ya la resolvió un instante antes, se rechaza el cambio con un error claro ("esta transacción ya fue procesada por [otro usuario]") y se refresca el listado, en vez de permitir un doble procesamiento.
2.5 ⚠️ NUEVO (2026-07-25): la comisión es información restringida — solo Reportes y el Dashboard de Supervisor
Regla de negocio confirmada por el cliente: el monto de la comisión CIS de una transacción no se muestra en ningún lugar operativo del sistema — ni en el listado de Transacciones, ni en el detalle de una transacción, ni en el modal de confirmación de pago/cancelación. Se muestra únicamente en:
- Reportes (estado de situación contable, agregados — sección 6 del funcional).
- Dashboard, pero solo para el rol Supervisor (no para Backoffice ni cualquier otro rol que entre al Dashboard).
Por qué importa más que un cambio visual: esto no se resuelve solo ocultando el campo en el frontend — si el backend sigue devolviendo fee/comision en la respuesta de la API para cualquier usuario, alcanza con abrir las DevTools del navegador para verlo igual. La restricción tiene que aplicarse en el backend, condicionando qué campos incluye la respuesta según el rol del usuario que hace el request — el frontend ocultando el campo es una capa extra, no la protección real.
Alcance de la restricción — qué SÍ sigue visible:
- ABM Países (donde el Admin configura el % de comisión editable por país) — esto es configuración del sistema, no una "revelación" de la comisión de una transacción puntual. Se asume que sigue visible/editable para Admin sin cambios. A confirmar con el cliente si esta lectura es correcta o si también hay que restringir esta pantalla.
Módulos afectados (a auditar y corregir):
GET /api/transaccionesyGET /api/transacciones/{id}— el campo de comisión no debe venir en la respuesta salvo que el usuario sea Supervisor consultando desde el contexto de Reportes/Dashboard.- Listado de Transacciones (columna "Comisión") — sacar para todos los roles excepto el caso de uso de Reportes.
- Detalle de Transacción — sacar el dato de comisión de la vista.
- Modal de confirmación de pago/cancelación (el "recibo") — sacar la fila de comisión por completo, no mostrarla ni siquiera al Supervisor en este flujo puntual (la regla es "Reportes y Dashboard", no "donde sea que el Supervisor esté parado").
3. User Flows
3.1 Login (MVP1: solo usuario/password — SSO Google/Microsoft queda para Fase 2)
El usuario del sistema es el mail. El login con SSO Google y SSO Microsoft/O365 (el cliente ya usa Microsoft 365 con dominio propio) queda confirmado como Fase 2, fuera del MVP1.
3.2 Flujo core — Backoffice gestiona el pago de una transacción
Actualizado 2026-07-25 — ver 2.4: el PDV no viene con la transacción, se asigna al resolverla.
3.3 Flujo — Cancelación bidireccional
Actualizado 2026-07-25: mismo fix que 3.2 — re-chequeo de estado + PDV asignado recién acá.
3.4 Flujo — Supervisor carga un asiento de prefondeo
3.5 Flujo — Admin gestiona un ABM (patrón genérico: Países / Usuarios / Estaciones / Configuración)
3.6 Flujo — Admin edita la matriz de Roles y Permisos (con dependencia entre toggles)
3.7 Flujo — Admin asigna roles multipaís / multi-PDV a un usuario
4. Diagramas de Actividad (procesos multi-componente)
4.1 Ingesta de transacción — WebApp → Soterex, disparada por cron (SendRequest)
Confirmado por el cliente: la WebApp es quien llama a tokenC2P y SendRequest, mediante un cron cada 30 minutos, para tomar las transacciones pendientes que Soterex tiene registradas.
Corrección 2026-07-25: el PDV nunca se asigna en este paso — Soterex no lo informa y a esta altura es imposible saberlo. La transacción queda disponible en la bolsa compartida del país. Ver sección 2.4.
4.2 Pago de transacción — Backoffice → WebApp → Soterex
Corrección 2026-07-25: se agrega el re-chequeo de estado con lock justo antes de confirmar (varios Backoffice de distintos PDVs comparten la misma bolsa del país, así que la colisión es esperable, no un caso raro) y la asignación de PDV recién al resolver. Ver sección 2.4.
4.3 Cancelación — Backoffice → WebApp → Soterex (y caso Soterex-iniciado, pendiente de definición)
5. Secuencias de Pantalla
Login:
1. /login → Solo usuario/password en MVP1 (usuario = mail)
2. /dashboard → Home con indicadores generales, filtrado por los países/PDVs asignados al usuario
Gestión de transacción (Backoffice):
1. /transacciones → Listado. Pendientes (ACCEPTED): bolsa compartida por país, sin filtro de PDV
(todavía no tienen uno). Resueltas (PAID/CANCELLED): sí filtrables por PDV, país y fecha.
2. /transacciones/:id → Detalle (datos, monto, comisión, MTCN, estado, historial)
3. /transacciones/:id → Acción: Cambiar a PAID / Cancelar — re-chequeo de estado justo antes de
confirmar; si otro usuario ya la resolvió, error claro + refresco del listado (sección 2.4)
4. /transacciones/:id → Confirmación (graba PDV + usuario en ese momento) + actualización de
saldo de prefondeo (pool por país) / alerta de saldo insuficiente
Carga de Prefondeo (Supervisor):
1. /prefondeo → Listado histórico de asientos por país (pool único, no por PDV)
2. /prefondeo/nuevo → Formulario de nuevo asiento (país, monto, fecha)
3. /prefondeo → Confirmación, saldo del país actualizado
Reportes (Supervisor / Admin):
1. /reportes/situacion → Estado de situación contable: formato estándar con todos los tipos de movimiento + resumen por cada request
2. /reportes/dashboard → Cantidad de pagados con filtro de rango de fecha, por PDV, por país; comparativa país vs país y PDV vs varios PDVs; ranking de PDVs; totalizadores por país
Administración (Admin):
1. /admin/usuarios → ABM Usuarios (incluye mail de notificación, con posibilidad de más de un mail por usuario/estación, y notificaciones editables)
2. /admin/paises → ABM Países, incluye % de comisión editable por país
3. /admin/estaciones → ABM Estaciones/PDV. Identificador: código interno de sucursal. Resto de campos habituales (nombre, país, dirección, responsable) + mail(es) de notificación editables
4. /admin/configuracion → Timeout de sesión: valor global por defecto, con override editable por rol y por usuario
5. /admin/auditoria → Logs de movimientos y logins (acceso: Supervisor y Admin)
6. /admin/roles-permisos → Grilla Módulo x Rol x Leer/Escribir/Borrar, con dependencia Borrar→Escribir
7. /admin/asignacion-roles → Por usuario: País + Rol (+ PDVs si es Supervisor/Backoffice); un usuario puede tener múltiples asignaciones6. Preguntas Abiertas (a resolver antes de aprobar el PRD)
Campos faltantes en SendRequest — 📌 QUEDA PENDIENTE (no bloqueante, a definir más adelante): el Excel actual incluye "fecha de nacimiento" y "número de registro de extranjero" que no están en el spec del PDF (
SendRequestv1.4). El cliente decidió (2026-07-24) dejarlo pendiente de averiguar y no bloquear el avance del análisis por esto. Queda anotado para retomar antes de cerrar el PRD o, a más tardar, antes de que backend-dev defina el modelo de datos de la transacción.Contradicción push vs. cron/pull— ✅ RESUELTO (2026-07-24): confirmado por el cliente que la WebApp llama aSendRequestdesde un cron cada 30 minutos (modelo pull, no webhook-push de Soterex). Queda actualizada en las secciones 3.3, 4.1 y 4.3.2b. Sigue abierta (⚠️ bloqueante para el architect): si la WebApp es quien llama a
tokenC2P,SendRequestyCancelhacia Soterex, yNotificationses el único canal WebApp → Soterex confirmado, ¿cómo llega a la WebApp una cancelación iniciada por Soterex? Opciones a confirmar con el cliente: (a) el mismo cron de 30 min que trae transacciones nuevas también trae cancelaciones marcadas por Soterex en esa respuesta, (b) existe un endpoint adicional no documentado en este PDF para consultar cancelaciones, o (c) en la práctica Soterex nunca cancela por su cuenta y la bidireccionalidad es solo conceptual (a validar).Regla de comisión— ✅ RESUELTO (2026-07-24): la comisión es editable por país (no global, ni por PDV, ni por tipo de transacción). Se configura enABM Países.Alcance del saldo de prefondeo— ✅ RESUELTO (2026-07-24): es un pool único por país (no por PDV/estación individual). El reporting de la pregunta #11 igual permite ver el consumo desagregado por PDV, aunque el saldo/fondo en sí se administra a nivel país.Quién puede cambiar estado a PAID y quién puede cancelar— ✅ RESUELTO (2026-07-24): confirmado que es editable, gobernado por la matriz de Roles y Permisos configurable (sección 2). No es una regla fija de negocio. Queda el seed inicial documentado en la tabla 2.1 (con ⚠️ porque el seed exacto por defecto aún no fue confirmado, pero eso ya no bloquea el análisis — es solo un valor de configuración inicial).5b. Sigue abierta (menor): si la dependencia adicional Escribir requiere Leer (sugerida por el Product Owner) debe aplicarse igual que Borrar→Escribir. No bloqueante.
Formato de reportes contables— ✅ RESUELTO (2026-07-24): debe ser un formato estándar que refleje todos los tipos de movimiento (transacciones y asientos de prefondeo) con un resumen de cada request. (Sigue pendiente, no bloqueante: si necesita exportación a Excel/PDF — a confirmar con ui-engineer/backend-dev en la siguiente etapa.)Datos de la entidad Estación/PDV— ✅ RESUELTO (2026-07-24): el identificador es el código interno de sucursal. Además de los campos habituales (nombre, país, dirección, responsable), se agrega mail de notificaciones, con soporte para más de un mail por estación, y las notificaciones deben ser editables (se puede configurar cuáles eventos disparan mail a cuáles direcciones).Timeout de sesión— ✅ RESUELTO (2026-07-24): modelo de 3 niveles — valor global por defecto, con posibilidad de override por rol y override por usuario (el más específico prevalece).Alcance de SSO— ✅ RESUELTO (2026-07-24): el cliente hoy usa Microsoft 365 con dominio propio, pero para el MVP1 el login es solo usuario/contraseña (usuario = mail). SSO Google y SSO Microsoft/O365 quedan confirmados para una fase posterior, no MVP1.Acceso a logs de auditoría— ✅ RESUELTO (2026-07-24): acceso para Supervisor y Admin (no exclusivo de Admin).Definición de indicadores del dashboard— ✅ RESUELTO (2026-07-24): cantidad de transacciones pagadas con filtro de rango de fechas, por PDV y por país; comparativa entre países; comparativa de un PDV contra varios PDVs; ranking de PDVs; totalizadores por país. (Reemplaza a la idea original de "velocity" — no se pidió tiempo promedio a PAID/CANCELLED, sino estos indicadores de volumen y comparación.)Idempotencia de SendRequest— ✅ RESUELTO (2026-07-24): el cliente confirmó que la validación nativa de la API (error 2001 "Duplicate transaction number") es suficiente, no se necesita lógica adicional en la webapp.Aislamiento multi-país— ✅ RESUELTO (2026-07-24): los usuarios pueden ser multipaís — un mismo usuario puede tener rol Admin en un país y Supervisor o Backoffice/PDV en otro. Un Supervisor puede estar a cargo de más de un PDV. Todo esto debe ser editable desdeABM Asignación de Roles Multipaís/PDV(sección 2.3).
13b. Nueva pregunta derivada (⚠️ abierta, menor): ¿un Supervisor puede estar a cargo de PDVs de más de un país a la vez, o sus PDVs asignados siempre pertenecen al mismo país en el que tiene el rol Supervisor? Se asumió esto último por simplicidad, a confirmar.
Qué PDV se graba si el usuario tiene más de uno asignado (o ninguno, ej. Admin)— ✅ RESUELTO PARCIALMENTE (2026-07-25): opción (a) implementada — "PDV activo" explícito (role_assignments.default_station_id), configurable por asignación, con prioridad sobre el PDV único del alcance. No cambia qué puede leer el usuario (Admin sigue viendo todo el país), solo qué PDV se graba al resolver. Confirmado con Admin: quedó configurado enGT-CAP-001(Ciudad de Guatemala — Central) a pedido del cliente, tras detectar en uso real que pagar como Admin dejaba la transacción sin PDV asignado. Sigue abierto (menor, no bloqueante): Backoffice/Supervisor con 2+ PDVs y sin PDV activo configurado todavía caen ennullal resolver — el mecanismo ya existe, falta decidir si se les configura un default también o se les pide elegir al resolver.Nota (2026-07-27): una sesión distinta había reescrito este punto como si siguiera abierto, sin el mecanismo ya implementado — restaurado acá; el contenido de esa reescritura (Backoffice con 2+ PDVs sin default) ya estaba cubierto por el "Sigue abierto" de arriba, no era una pregunta nueva.
Resumen — solo quedan bloqueantes reales para el PRD:
- #2b (mecanismo de cancelación iniciada por Soterex) — bloqueante para el architect.
- #13b (alcance país de los PDVs de un Supervisor) — menor, no bloqueante.
- #1, #5b, #6 (exportación) — quedan como pendientes menores, no bloqueantes, a resolver en paralelo con el PRD.
7. Señales de Handoff (siguiente paso: PRD + Backlog)
- → architect: estructura del sitemap, diagramas de actividad (el mecanismo WebApp→Soterex vía cron de 30 min ya está confirmado; queda bloqueante la Pregunta Abierta #2b sobre cómo llega una cancelación iniciada por Soterex), modelo multi-país con roles multipaís/multi-PDV editables (sección 2.3), comisión editable por país, prefondeo como pool por país, necesidad de log/auditoría completo, y arquitectura de login preparada para agregar SSO Google/Microsoft en Fase 2 aunque el MVP1 sea solo usuario/contraseña.
- → backend-dev: modelo de datos de permisos (Módulo x Rol x Leer/Escribir/Borrar, con dependencia Borrar→Escribir), modelo de asignación Usuario × País × Rol × [PDVs], los 4 contratos de API de Soterex (
tokenC2P,SendRequest,Cancel,Notifications), lógica de generación de MTCN secuencial único, lógica de descuento de prefondeo (pool por país) y bloqueo por saldo insuficiente, entidad Estación/PDV con código interno de sucursal como identificador y múltiples mails de notificación editables, timeout de sesión en 3 niveles (global/rol/usuario). - → ui-engineer: lista de pantallas de la sección 5 (Screen Sequences) como cola de producción, estados visuales de transacción (ACCEPTED/CANCELLED/PAID), alertas de saldo insuficiente y de error de actualización, diseño del componente de grilla de permisos L/E/B con su regla de dependencia, y diseño de la pantalla de asignación de roles multipaís/PDV por usuario.
- → security: manejo de JWT (tokenC2P), diseño de auth preparado para agregar SSO Google/Microsoft en Fase 2 (MVP1 = solo usuario/password), timeout de sesión configurable en 3 niveles, logs de auditoría de logins (visibles para Supervisor y Admin).
Este documento corresponde al Paso 1 (Análisis Funcional) de la metodología del agente Product Owner. El Paso 2 (PRD + Backlog) se redactará una vez resuelta la Pregunta Abierta #2b (único bloqueante real restante), y se guardará en doc/plans/ y como PRD vinculado a este análisis.

