Detalle técnico · 26 de octubre de 2026
Remesas Patrimonio
Middleware B2B para bancos y cooperativas. Recibe un evento de remesa, aplica reglas de ahorro y scoring conductual y ejecuta detección de estructuración. No custodia fondos, no reemplaza el core y no procesa datos personales.
Estado: prototipo en sandbox; capacidades probadas contra la API del sandbox con datos sintéticos (SIMULADO). 3.er lugar en Innovatech, organizado por la Asociación Bancaria de Guatemala (ABG). No es una certificación de producción.
Calificación legal: el diseño busca que el middleware no custodie datos personales. La calificación como persona obligada debe confirmarla cada institución con su asesoría legal y el regulador. Este documento no emite conclusiones legales.
1. Alcance y estado
Remesas Patrimonio se monta entre el core de la institución y sus canales. El banco o la cooperativa conserva la relación con el cliente, el KYC y la decisión de reporte; el middleware opera con un identificador opaco y ejecuta reglas de ahorro, scoring conductual y detección AML.
Lo que este documento describe es el diseño y lo que el código permite verificar. No incluye precios, proyecciones de ingresos, métricas de clientes ni información de equipo. Tampoco afirma que el producto esté en producción.
Las cifras de negocio no forman parte de este detalle. La única cifra pública que se cita es el volumen de remesas a Guatemala en 2025, con su fuente, en la sección de fuentes.
2. Arquitectura y flujo
El flujo principal es webhook → cola/worker → API de ahorro de la institución. La respuesta HTTP no espera la resolución del depósito.
- La institución envía
POST /webhooks/remittance-receivedcon un payload mínimo{ external_user_id, remittance_id }, sin PII. El middleware valida OAuth2/JWT RS256. - El evento se persiste y se encola en BullMQ sobre Redis.
- El worker consulta la regla de ahorro, calcula el desvío, llama a la Savings API de la institución en modo API o marca el depósito como
PENDING_BATCHen modo batch. Después registra el evento conductual y actualiza el score. - Si el depósito falla, reintenta tres veces con backoff exponencial y lo mueve a la cola de fallos (
failed_jobs). - Los eventos de cumplimiento se publican por SSE para el panel administrativo.
El middleware no dispersa fondos ni presenta reportes por su cuenta. La llamada a la Savings API es idempotente y tiene timeout; la institución puede consultar el estado del depósito por un endpoint dedicado.
Componentes: API NestJS + Fastify, PostgreSQL 16, Redis + BullMQ y JWT RS256. Fuente: README.md y api/package.json.
3. Zero PII y privacidad por diseño
La tabla users contiene institution_id y external_user_id. El segundo es un identificador opaco generado por la institución después de su KYC. El mapeo entre ese identificador y la persona real ocurre dentro del banco.
El middleware no recibe nombres, DPI, direcciones, números de cuenta ni datos biométricos. El diseño reduce el perímetro de auditoría; no sustituye la evaluación de la institución ni la del regulador.
| Dato | ¿Se almacena en el middleware? |
|---|---|
Identificador opaco (external_user_id) | Sí |
| Montos, ventanas y marcas de tiempo | Sí |
| Nombre, DPI, dirección, cuenta o biometría | No |
| Mapeo a la persona real | No; permanece en el banco |
El aislamiento multi-institución usa OAuth2 Client Credentials con JWT RS256. El token incluye el claim institution_id, que se verifica en cada operación. El aislamiento se aplica en el guard de aplicación y en el filtro WHERE institution_id = ? de todas las consultas. No existe un superusuario transversal en el middleware.
Fuentes: api/prisma/schema.prisma (modelo User) y api/src/common.
4. KYC/AML delegado
El middleware no reemplaza ni duplica el KYC/AML de la institución. Se monta sobre él. El banco o la billetera digital es el único custodio de los datos personales y del proceso de conocimiento del cliente.
La plataforma opera con el identificador tokenizado que la institución entrega después de completar su KYC. La responsabilidad legal ante la SIB y la IVE permanece en la institución que tiene la relación contractual con el cliente.
El middleware no reporta directamente a la IVE/SIB. Expone alertas estructuradas y una verificación arquitectónica para que la institución las incluya en su propio reporte.
Límite explícito: “sin PII” no significa “sin obligaciones”. La institución conserva la identificación, la debida diligencia y el reporte. El middleware aporta evidencia técnica, no una conclusión legal.
5. Módulo de estructuración
El motor evalúa remesas entrantes por external_user_id en cuatro ventanas concurrentes: 1 hora, 24 horas, 7 días y 30 días. Cada ventana tiene su propio contador y sus propios umbrales. Fuente: api/src/aml-engine/aml-detection.service.ts:66-106.
| Ventana | Umbral individual | Mínimo de remesas | Umbral combinado | Alto riesgo por frecuencia | Alto riesgo por monto | Ventana de concentración |
|---|---|---|---|---|---|---|
| 1 h | Q9,000 | 3 | Q10,000 | 5 | Q50,000 | 1 h |
| 24 h | Q9,000 | 3 | Q10,000 | 5 | Q50,000 | 2 h |
| 7 días | Q9,000 | 5 | Q30,000 | 10 | Q100,000 | 24 h |
| 30 días | Q9,000 | 10 | Q50,000 | 20 | Q200,000 | 72 h |
Las remesas individuales iguales o superiores al umbral individual no cuentan para el patrón de estructuración; se evalúan por la vía de reporte que corresponda. El motor también calcula señales complementarias: cercanía al umbral (90% de Q9,000), número de cuentas de origen, desviación frente a la línea base (z-score), persistencia entre ventanas y sucesión rápida. La matriz de riesgo mapea el puntaje a LOW, MEDIUM, HIGH y CRITICAL. Fuente: las constantes del mismo servicio.
Configuración por institución: los valores por defecto se mezclan con la configuración propia de cada institución en structuring_config_overrides. Cada fila pertenece a una institución y el merge se hace por ventana; si no hay fila, se usan los valores por defecto. Fuentes: api/prisma/schema.prisma:768-839 y api/src/structuring/structuring-config.service.ts.
Deduplicación: un índice único parcial, structuring_alerts_active_unique, impide dos alertas activas para el mismo external_user_id y la misma ventana mientras el estado sea OPEN o INVESTIGATING. Fuente: api/prisma/migrations/20260705221000_add_window_label_and_partial_unique_index/migration.sql:50.
6. Flujo de alerta e investigación
- El motor registra la alerta en
structuring_alertscon ventana, montos, nivel y marcas de tiempo. - El panel recibe el evento por SSE (
structuring_alert). - El oficial de cumplimiento la toma:
OPEN→INVESTIGATING. - La cierra como
DISMISSED(falso positivo) o la escala aESCALATED_TO_RTS(reporte de transacción sospechosa). - Si decide aislar al usuario, usa
PATCH /v1/admin/compliance/users/:id/isolate. Los depósitos pendientes pasan aHOLD_FOR_COMPLIANCE; al levantar el aislamiento, se re-encolan en orden y con reintentos.
La decisión de aislar y la de reportar son humanas. El middleware no reporta por su cuenta y no ejecuta una acción de alto impacto sin esa decisión.
Fuentes: api/src/common/compliance/compliance-event-emitter.ts:104, api/src/admin/compliance-isolation.controller.ts:58-217 y api/prisma/schema.prisma:703-765.
7. Modos de integración
Los dos modos comparten el mismo webhook de entrada, la autenticación OAuth2/JWT RS256 y el motor de reglas. La bifurcación ocurre en el worker según savingsAuthType.
| Criterio | API en tiempo real | Batch SFTP + PGP |
|---|---|---|
savingsAuthType | API (por defecto) | SFTP_BATCH |
| Perfil | Core moderno con API REST, billeteras digitales y cooperativas en línea | AS/400, mainframe u otros cores legacy sin API REST |
| Procesamiento | Individual, en segundos | Por lotes, en ventanas nocturnas |
| Llamada a la Savings API | Sí, desde el worker | No; el depósito queda en PENDING_BATCH |
| Transferencia | JSON sobre HTTPS | CSV cifrado con PGP por SFTP |
| Estados | PENDING → PROCESSING → COMPLETED o FAILED | PENDING → PROCESSING → PENDING_BATCH → BATCHING → BATCHED → SENT_VIA_SFTP → COMPLETED o FAILED |
El pipeline batch genera el archivo a las 23:00 UTC y concilia la respuesta a las 06:00 UTC. El CSV contiene únicamente identificadores opacos y montos. La llave pública PGP de la institución cifra el archivo; la llave privada permanece en la institución. Fuentes: api/src/batch/batch-file-generator.service.ts, batch-pgp.service.ts, batch-sftp.service.ts, batch-reconciliation.service.ts y batch-cron.service.ts.
En ambos modos el middleware opera sin PII. El archivo batch no incluye nombres, DPI, números de cuenta ni datos biométricos; el mapeo a la persona real ocurre dentro del banco.
8. Despliegue y controles de seguridad
Hay tres opciones de despliegue, con el mismo código base, las mismas APIs y los mismos mecanismos de aislamiento:
- Multi-tenant en cloud: instancia compartida con aislamiento lógico por
institution_id. - Single-tenant en VPC: instancia, PostgreSQL y Redis dedicados, con VPC peering hacia la institución.
- On-premise: despliegue dentro de la infraestructura de la institución, con código auditable.
Este documento no incluye precios ni tiempos de integración.
Controles declarados en el diseño y el código:
- TLS 1.3, WAF, rate limiting por
client_idy allowlist de IP disponible. - OAuth2 Client Credentials con JWT RS256; claim
institution_id; guard de aplicación y filtro por institución en base de datos. - Idempotencia y timeout en la llamada a la Savings API; tres reintentos con backoff exponencial y cola de fallos.
- Auditoría de las transiciones de alerta y de las decisiones de aislamiento.
Estos controles describen el diseño y el código. No constituyen una certificación ISO 27001, SOC 2 ni una opinión legal.
9. Relación con el Decreto 15-2026
Esta matriz describe cómo se relaciona el diseño con temas del Decreto 15-2026 y con el enfoque basado en riesgo. No afirma satisfacción normativa ni sustituye una evaluación legal.
| Tema | Cómo se relaciona o apoya | Límite |
|---|---|---|
| Identificación del beneficiario final | Recibe un identificador opaco generado por la institución después de su KYC. | La identificación y el mapeo a la persona real son de la institución. |
| Enfoque basado en riesgo (GAFI, Recomendación 1) | Permite configurar umbrales por institución y por ventana sin redeploy. | La política de riesgo y su aprobación son de la institución. |
| Detección de operaciones inusuales y estructuración | Cuatro ventanas, señales complementarias y alertas con flujo de investigación. | La calificación y el reporte los decide la institución. |
| Conservación de registros | Marcas de tiempo en los eventos y retención configurable por institución. | La política de retención y el plazo legal los define la institución. |
| Secreto bancario y confidencialidad | Aislamiento multi-institución en aplicación y base de datos. | No sustituye los controles de acceso de la institución. |
| Reporte a la IVE/SIB | Alertas estructuradas y GET /v1/admin/privacy-status como evidencia técnica. | El reporte lo presenta la institución; el middleware no reporta. |
| Debida diligencia ampliada | Scoring conductual sobre datos transaccionales sin PII. | No sustituye el expediente KYC ni la decisión de la institución. |
| Sujeción obligada y registro | El diseño busca que el middleware no custodie datos personales. | La calificación como persona obligada debe confirmarla cada institución con su asesoría legal y el regulador. |
No se afirma que el producto satisfaga el Decreto ni que esté listo para la evaluación GAFILAT. Esas son determinaciones de la institución y del regulador.
10. Endpoints y documentación
La especificación publicada documenta más de 50 endpoints (según la especificación OpenAPI). La cuenta exacta puede variar entre la especificación y el código; por eso este documento no fija una cifra.
- Swagger UI (se abre en una pestaña nueva)
- Especificación OpenAPI en JSON (se abre en una pestaña nueva)
Endpoints de referencia:
POST /webhooks/remittance-received: entrada de la remesa.POST /auth/user-token: SSO de demostración para el receptor; no es un login real.PATCH /v1/admin/compliance/users/:id/isolate: aislamiento y retención de depósitos.GET /v1/admin/privacy-status: verificación arquitectónica de Zero PII.
Ejemplo de respuesta de GET /v1/admin/privacy-status (sandbox; valores ilustrativos):
{
"status": "clean",
"message": "No se almacenan datos personales (PII) en el middleware.",
"checkedTables": [
"users",
"institutions",
"savings_rules",
"remittance_events",
"savings_deposits",
"behavioral_events"
],
"piiFieldsFound": [],
"allFieldsAreHashesOrIds": true,
"lastVerified": "2026-10-26T00:00:00.000Z"
}
El ejemplo refleja la forma del DTO. No incluye banderas de “listo para GAFILAT” ni de “alineado” con el Decreto, porque el endpoint no emite una certificación legal.
11. Glosario
| Término | Definición |
|---|---|
| AML/CFT | Prevención de lavado de activos y financiamiento del terrorismo. |
| KYC | Conocimiento del cliente: identificación y debida diligencia que realiza la institución financiera. |
| Estructuración (pitufeo) | Fragmentación de operaciones para evitar umbrales de reporte o de control. |
external_user_id | Identificador opaco generado por la institución después de su KYC. No es un dato personal por sí mismo. |
| Zero PII | Diseño en el que el middleware no recibe ni almacena datos personales identificables. |
| IVE | Intendencia de Verificación Especial, autoridad de supervisión AML en Guatemala. |
| SIB | Superintendencia de Bancos de Guatemala. |
| GAFI / GAFILAT | Grupo de Acción Financiera Internacional y su capítulo para América Latina. |
| RTS | Reporte de transacción sospechosa. |
| SSE | Server-Sent Events: canal de eventos unidireccional del servidor al panel. |
12. Fuentes y límites
Fuente pública citada: US$25,530 millones en remesas a Guatemala en 2025, según Banguat, vía Prensa Libre (se abre en una pestaña nueva). Es un dato del país, no una métrica del prototipo.
Fuentes del repositorio: README.md, api/prisma/schema.prisma, api/src/aml-engine/aml-detection.service.ts, api/src/structuring/structuring-config.service.ts, api/src/admin/aml-admin.service.ts, api/src/admin/compliance-isolation.controller.ts, api/src/batch/*.ts y las migraciones de api/prisma/migrations/.
Límites: prototipo en sandbox con datos sintéticos; no hay métricas de clientes ni de producción; no se incluyen precios, mercado ni equipo; la calificación legal es de cada institución y del regulador; la cuenta de endpoints se expresa como “más de 50” porque la especificación y el código no coinciden en una cifra exacta.
Revisión: 26 de octubre de 2026.