ConTodo ERP — Colección Consolidada de Diagramas de Arquitectura (Mermaid)
ConTodo ERP — Colección Consolidada de Diagramas (Mermaid)
Propósito. Este entregable reúne en un solo artefacto navegable los diagramas de arquitectura canónicos de ConTodo, el ERP SaaS multi-tenant cloud-native para PYMEs y medianas de Perú y LATAM (textiles, importadoras, comercializadoras, distribuidoras y manufactura ligera). No es una galería decorativa: cada diagrama es la representación normativa de una decisión ya tomada en los entregables de arquitectura de software (05), arquitectura AWS (06) y los documentos de dominio (contable, importaciones, textil, IA, BI, ciberseguridad). Sirve como mapa único para onboarding de ingenieros, revisión de arquitectura, due diligence técnica y materiales de venta enterprise.
Anti-overclaiming y gobierno. Los diagramas reflejan el estado acordado de la arquitectura, con sus decisiones reconciliadas (un solo
tenant_idBIGINT interno + UUID público; un solo bus de eventos outbox→EventBridge con CDC diferido; un solo contrato de API REST canónico + GraphQL BFF). Cuando un diagrama muestra una pieza diferida (CDC/Kafka, Redshift, Llama-VPC), se rotula explícitamente como Fase 2/3 para no confundir la aspiración con el MVP. Cualquier divergencia respecto a estos diagramas requiere un ADR nuevo aprobado por Solution Architect + CTO.
Índice de diagramas
| # | Diagrama | Notación Mermaid | Fuente primaria | Sección |
|---|---|---|---|---|
| 1 | C4 Nivel 1 — Contexto del sistema | C4Context | 05-arquitectura-software | §1 |
| 2 | C4 Nivel 2 — Contenedores | C4Container | 05 + 06 | §2 |
| 3 | Arquitectura de infraestructura AWS | flowchart | 06-arquitectura-aws | §3 |
| 4 | Modelo multi-tenant (defensa en profundidad) | flowchart | 05 §4.2 + 13 | §4 |
| 5 | Flujo de facturación electrónica SUNAT (CPE/OSE/CDR) | flowchart + sequenceDiagram | 03 + 05 | §5 |
| 6 | Flujo de importación y costeo nacionalizado | flowchart + stateDiagram | 05-importaciones | §6 |
| 7 | Flujo de producción textil (hilado→tejido→confección) | flowchart | 06-textil | §7 |
| 8 | Pipeline de datos / BI (medallón + CDC) | flowchart | 12-data-bi | §8 |
| 9 | Arquitectura de IA / MCP por tenant | graph + flowchart | 11-ia-automatizacion | §9 |
| 10 | Modelo de permisos RBAC + ABAC + SoD | graph + erDiagram | 13-ciberseguridad | §10 |
| 11 | Flujo de asientos contables (motor de plantillas) | flowchart + sequenceDiagram | 04-contable + 05 §5 | §11 |
| — | Mapa de bounded contexts (DDD) — apéndice | graph | 05 §3 | §12 |
Convención de tipos
tenant_iden los diagramas. El ADR-02 fijatenant_idcomo BIGINT interno (PK/FK/sharding/RLS) más un UUID público para identificadores expuestos en API. En los diagramas de RLS veráscurrent_setting('app.current_tenant')::bigint. El documento de IA (11) usa::uuiden su ejemplo histórico: aquí se normaliza a BIGINT para alinear con el ADR-02 (cierre de la contradicción C3/RT10 del debate técnico).
1. C4 Nivel 1 — Contexto del sistema
Qué muestra. La vista de mayor altitud: quién usa ConTodo y con qué sistemas externos conversa. Es el primer diagrama que ve un stakeholder no técnico o un evaluador de due diligence. Define la frontera del sistema (qué es ConTodo y qué no) y deja explícitas las dependencias regulatorias (SUNAT/OSE) y de negocio (bancos, pasarelas, LLM, e-commerce).
Lectura clave. La frontera deja claro que SUNAT/OSE no es "una integración más" sino el núcleo de confianza del producto: en Perú, un ERP que falla en CPE o SIRE es desechado de inmediato. Por eso la relación con SUNAT está marcada como bidireccional (emisión + declaración + sustento aduanero).
2. C4 Nivel 2 — Contenedores
Qué muestra. Cómo se descompone ConTodo en contenedores desplegables (procesos/almacenes con su propio runtime). Refleja el ADR-01 (modular monolith Rails sobre ECS Fargate, no microservicios) y el ADR-04 (un solo bus: outbox→EventBridge). La SPA React es estática en S3/CloudFront (ADR-05: sin SSR).
Lectura clave. Hay dos servicios de cómputo distintos (web On-Demand/Savings Plan y workers con cola critical On-Demand + colas Spot). El MCP Server se modela como contenedor lógico aparte porque es la única superficie LLM→datos y concentra el aislamiento por tenant (token scoped). La separación web/worker permite escalar la emisión fiscal sin tocar la latencia de la UI.
3. Arquitectura de infraestructura AWS
Qué muestra. El despliegue físico-lógico sobre AWS: VPC multi-AZ, borde (Route53→CloudFront→WAF→ALB), cómputo (ECS web + Sidekiq), datos (RDS Multi-AZ + Read Replica + Silo enterprise + Redis), y servicios transversales (Secrets Manager, EventBridge, CloudWatch/X-Ray, KMS, Backup cross-region). Refleja el ADR-03 (Shared Schema + RLS con Silo on-demand) y el RT1 (RDS Proxy obligatorio).
| Decisión visible | ADR / RT | Implicación |
|---|---|---|
| RDS Proxy entre ECS y RDS | RT1 / ADR-07 | Pooling + SET LOCAL transaccional; bloqueante de seguridad nº 1 |
Cola critical separada del Spot | RT6 | Un Spot interrumpido no deja un CPE/asiento a medias |
| Silo enterprise como RDS dedicada | ADR-03 / C7 | SKU Soberanía sin reescritura (connects_to Rails) |
us-east-1 primaria, DR us-west-2 | C1 | Costo; sa-east-1 solo para residencia enterprise |
| KMS a todos los stores | Seguridad | Cifrado at-rest por defecto; BYOK en SKU Soberanía |
4. Modelo multi-tenant — defensa en profundidad
Qué muestra. Las cinco capas concéntricas que impiden la fuga cross-tenant, del borde al motor. Cada capa falla cerrada (fail-closed). Es el control más crítico del producto: una fuga cross-tenant en un ERP contable sería un evento de extinción de marca.
| Capa | Mecanismo | Falla segura |
|---|---|---|
| 0 — HTTP | Middleware resuelve tenant; rechaza request sin tenant | 401/403 |
| 1 — Autorización | Pundit policy por módulo × sucursal × acción (RBAC + ABAC + SoD) | 403 |
| 2 — ORM | Tenantable default scope + asignación automática de tenant_id | Excepción si falta Current.tenant_id |
| 3 — Transacción | SET LOCAL app.current_tenant dentro de TX (no SET de sesión) | Sin TX → sin tenant |
| 4 — Motor (RLS) | Policy USING (tenant_id = current_setting('app.current_tenant')::bigint) | 0 filas (no fuga) |
| 5 — Datos | Shared Schema + RLS particionado; Silo dedicado on-demand | Aislamiento físico opcional |
Lectura clave (RT1). RDS Proxy en modo transaction multiplexa conexiones; si se usara SET de sesión en vez de SET LOCAL en TX, el contexto de un tenant podría filtrarse a otro request. Por eso el CI corre el test de aislamiento a través del pooler, no solo contra Postgres directo, y la policy RLS es default-deny cuando current_setting('app.current_tenant', true) es NULL.
5. Flujo de facturación electrónica SUNAT (CPE / OSE / CDR)
Qué muestra. El ciclo de vida de un Comprobante de Pago Electrónico (factura/boleta/NC/ND) desde la confirmación de venta hasta el CDR de SUNAT, con la arquitectura híbrida ComprobanteGateway (patrón Strategy: SEE propio nativo + OSE como fallback configurable por tenant). Cubre la generación UBL 2.1, firma XAdES-BES, envío, y manejo de los tres desenlaces de CDR (aceptado/rechazado/observado).
5.1 Modalidades de emisión y desenlaces del CDR
5.2 Secuencia transaccional (venta → CPE → contabilidad)
| Decisión visible | Fuente | Justificación |
|---|---|---|
ComprobanteGateway (Strategy) SEE propio + OSE fallback | 03 §3.2 | Evita lock-in y dependencia del uptime SUNAT |
Certificado .pfx en Secrets Manager (cifrado AEAD) | 13 §4 | Nunca en código; rotación gestionada |
Cola critical On-Demand con backoff | 05 §5.4 / RT6 | Emisión fiscal nunca sobre Spot |
| Conservación 5 años en S3 Object Lock WORM | 03 / 06 §6.3 | Art. 87 Código Tributario; nunca borrado físico |
| CPE alimenta propuesta SIRE RVIE | 03 §4 | SIRE reemplaza al PLE de ventas/compras |
6. Flujo de importación y costeo nacionalizado
Qué muestra. El proceso de importación como negocio de larga duración (60–120 días) con su máquina de estados, su canal de control SUNAT (verde/naranja/rojo), el prorrateo multi-base de gastos y el cálculo del costo unitario nacionalizado que valoriza el Kardex (NIC 2) y genera el asiento desdoblado.
6.1 Flujo end-to-end
6.2 Máquina de estados del expediente
| Regla de dominio (P0) | Implicación arquitectónica |
|---|---|
| Valor en aduana sobre CIF (OMC); FOB/EXW fuerzan flete+seguro antes de DAM | Bloqueo de valorización hasta DAM numerada |
| Van al costo: Ad-Valorem, ISC, antidumping, flete, seguro, agente, portuarios | Prorrateo multi-base por concepto (no "por unidades") |
| IGV/IPM/Percepción no van al costo (crédito/pago a cuenta) | Cuentas 40111/40113/40118; no inflan inventario |
| Asiento de nacionalización desdoblado (exterior/Aduanas/agente) | ImportNationalized con 3 contrapartidas + sustento DUA tipo doc 50 en RCE |
Hallazgo cuantitativo (ejemplo del doc). El costo unitario del ítem A resultó 34.8% mayor que el FOB convertido (S/ 101.11 vs S/ 75). Costear solo con FOB evapora ese margen — el dolor nº 1 que ConTodo resuelve frente a Excel y a competidores que tratan la importación como compra local.
7. Flujo de producción textil (hilado → tejido → confección)
Qué muestra. La cadena de transformación física de la vertical de lanzamiento, con sus tres fases, la merma acumulada por etapa, y el circuito de maquila como almacén-tercero. El costeo por Orden de Producción (MP/MOD/CIF) alimenta el Kardex y la contabilidad (circuito clase 6→9→23/71→21→69).
| Concepto del diagrama | Tratamiento en ConTodo |
|---|---|
| Merma acumulada en 4 etapas | 293 g de fibra para 220 g de tela neta (+33%); capturada vía %merma del BOM multinivel |
| Maquila | Almacén-tercero (no simple OC de servicio): no se pierde control del inventario valorizado en poder de terceros |
| Detracción confección | 12% sobre servicio; guía electrónica con motivo "traslado por transformación" (no es venta, no genera IGV débito) |
| Costeo OP | MP/MOD/CIF; ejemplo Polo Pima M/C = S/ 18.66 con estructura 67%/18%/15% |
| Merma anormal vs normal | Normal al costo; anormal a P&G; sustento técnico para deducción de Renta |
8. Pipeline de datos / BI (medallón + CDC)
Qué muestra. La arquitectura analítica: del OLTP al Data Warehouse vía capa medallón (bronze/silver/gold), transformación dbt, capa semántica (Cube/dbt metrics) y consumo (dashboard React, self-service, IA). Importante (ADR-04): en MVP y escala media el pipeline es batch nocturno dbt + DuckDB/S3 alimentado por el outbox; el CDC streaming (Debezium/Kafka/MSK) y Redshift son Fase 2/3, solo si se mide necesidad de latencia BI sub-5-min.
| Capa medallón | Rol | Beneficio |
|---|---|---|
| Bronze | Dato crudo append-only | Auditoría + reprocesamiento total (time-travel) |
| Silver | Limpieza, dedup, tipado | Calidad antes de modelar |
| Gold | Esquema estrella Kimball | Listo para consumo; conversión a PEN vía dim_tipo_cambio (SCD2) |
Lectura clave. La capa semántica Cube es contrato único de KPIs: el mismo EBITDA/margen sirve al dashboard y a la IA (NL2SQL), evitando que Finanzas y Ventas reporten cifras distintas y reduciendo alucinación del LLM. El test dbt de balance contable (Σ debe = Σ haber) hereda la integridad del OLTP al DW.
9. Arquitectura de IA / MCP por tenant
Qué muestra. La capa de IA con el MCP Server como única puerta LLM→datos (ningún LLM toca PostgreSQL directo), la estrategia multi-modelo enrutada por costo/latencia/privacidad, y el aislamiento por tenant (token scoped + RLS + whitelist de tools + redacción de outputs). Premisa: la IA asiste, no auto-commitea nada con efecto fiscal (human-in-the-loop).
9.1 Diagrama global de IA
9.2 Enrutador de modelos (LLM Router)
| Capa de aislamiento MCP | Control |
|---|---|
| Autenticación de sesión | El Copilot hereda la identidad del usuario; nunca service-account omnipotente |
| Token MCP scoped (≤5 min) | Codifica tenant_id, user_id, roles, branch_ids; validado en cada llamada |
| RLS PostgreSQL | SET LOCAL app.current_tenant; impide filtrado cruzado aunque haya bug de app |
| Whitelist de tools por rol | Un vendedor no ve payroll_query; tools de escritura fiscal solo crean borradores |
| Validación/redacción de outputs | PII de planillas y costos filtrados por rol antes de volver al LLM |
Lectura clave. Ninguna tool MCP confirma un PLE, envía a SUNAT o ejecuta un pago — es deliberado (human-in-the-loop, riesgo SUNAT). El forecast es estadístico (Prophet/LightGBM); el LLM solo explica y contextualiza, nunca produce el número crudo (anti-alucinación).
10. Modelo de permisos RBAC + ABAC + SoD
Qué muestra. El modelo de autorización: la unidad atómica es el permiso (recurso:acción), los roles los agrupan, los usuarios reciben roles dentro del scope de un tenant (y opcionalmente sucursal). Sobre RBAC se superponen políticas ABAC (sucursal propia, monto ≤ X, horario) y reglas SoD (segregación de funciones) validadas en tiempo de asignación.
10.1 Modelo conceptual de autorización
10.2 Entidades del modelo (ER)
| Rol base | Scope | Permiso representativo | Principio (SoD/ABAC) |
|---|---|---|---|
super_admin (plataforma) | Global ConTodo | Infra; sin datos de negocio salvo break-glass auditado | Mínimo privilegio + break-glass |
owner (tenant) | Tenant | Todo + gestión usuarios + facturación SaaS | Único que crea admins |
contador | Tenant | Contabilidad, EEFF, PLE/SIRE, asientos | Registra, no aprueba pagos |
tesorero | Tenant/sucursal | Tesorería, conciliación, aprobar pagos | Segregado de contador |
vendedor | Sucursal | Emitir CPE de su sucursal, CRM | ABAC sucursal + límite descuento |
almacenero | Almacén | Kardex movimientos; no ajuste valorizado | Ajuste de valor requiere contador |
auditor (read-only) | Tenant | Lectura total + audit log; cero escritura | Para revisores Big Four |
Reglas SoD codificadas (deny en asignación). compra:registrar + pago:aprobar (pago fraudulento); proveedor:crear + pago:aprobar (proveedor fantasma); planilla:calcular + planilla:aprobar (pago indebido); asiento:registrar + periodo:cerrar (ocultamiento de errores). El doble candado Pundit + RLS asegura que un bug de lógica de app no baste para filtrar datos.
11. Flujo de asientos contables (motor de plantillas)
Qué muestra. Cómo cualquier evento operativo (venta, compra, planilla, tesorería, producción, importación, depreciación) se convierte en un asiento de partida doble vía el motor de plantillas parametrizables (AccountingTemplate) — desacoplando la operación de la contabilidad y permitiendo que un contador (no un dev) ajuste mapeos. El cuadre Σ debe = Σ haber se garantiza por trigger en la base, no solo en la app.
11.1 Flujo del motor contable
11.2 Secuencia: venta confirmada → asiento idempotente
| Plantilla | Disparador | Debe / Haber |
|---|---|---|
SALE_INVOICE_CREDIT | Venta a crédito | D 12 Clientes / H 70 Ventas, H 4011 IGV |
SALE_COGS | Salida por venta | D 69 Costo ventas / H 20/21 Existencias |
PURCHASE_INVOICE | Factura compra | D 60 Compras, D 4011 IGV crédito / H 42 Proveedores |
IMPORT_NATIONALIZED | Ingreso nacionalizado | D 60/20, D 40 IGV/IPM/Percep / H 42 exterior, H 46 Aduanas, H 46 agente (desdoblado) |
WIP_TO_FG | Producción terminada | circuito clase 6→9→23/71→21→69 |
PAYROLL_ACCRUAL | Cierre de planilla | D 62 Gastos personal / H 41 Remun., H 40 Tributos, H 41 AFP |
DEPRECIATION | Corrida mensual | D 681 Depreciación / H 39 Deprec. acumulada |
DETRACTION | Detracción en cobro | D 1212 Detracciones / H 12 Clientes (parcial) |
Lectura clave. Tres garantías de integridad: (1) partida doble por trigger en la base (ningún path la salta); (2) inmutabilidad del asiento posted (se corrige con extorno/ajuste, exigencia PLE/SIRE); (3) idempotencia por event_id (los eventos at-least-once no producen asientos dobles). Las plantillas versionadas con dry-run son el foso competitivo frente a CONCAR/SISCONT, donde la lógica contable está cableada.
12. Apéndice — Mapa de bounded contexts (DDD)
Qué muestra. La descomposición del modular monolith en bounded contexts (un pack packwerk por context) con su flujo de eventos. La comunicación por defecto es asíncrona por eventos; solo IdentityAccess y Organization son dependencias síncronas permitidas en cualquier request.
13. Trazabilidad: diagrama ↔ decisión ↔ riesgo
| Diagrama | Decisión que normaliza (ADR) | Riesgo que mitiga |
|---|---|---|
| §1 Contexto C4 | Frontera del sistema; SUNAT como núcleo de confianza | Desalineación de alcance en due diligence |
| §2 Contenedores C4 | ADR-01 modular monolith; ADR-05 SPA sin SSR | Sobre-ingeniería con microservicios prematuros |
| §3 Infra AWS | ADR-03 Shared+RLS+Silo; RT6 cola critical On-Demand | RT6 Spot interrumpe job fiscal |
| §4 Multi-tenant | ADR-02 tenant_id BIGINT; ADR-07 SET LOCAL en TX | RT1 fuga cross-tenant vía pooler (crítico) |
| §5 Facturación SUNAT | ComprobanteGateway híbrido (Strategy) | Caída SUNAT/OSE; lock-in; pérdida de CPE (5 años) |
| §6 Importación | Asiento desdoblado; DUA tipo doc 50 en RCE | R5 cadena costo no cierra en el mayor |
| §7 Producción textil | Maquila como almacén-tercero | R2 textil fuga de material en talleres |
| §8 BI / Datos | ADR-04 outbox→batch; CDC diferido | RT3 doble pipeline; costo DW PYME |
| §9 IA / MCP | D2 MCP única interfaz; D4 human-in-the-loop | Alucinación; auto-commit fiscal; fuga IA cross-tenant |
| §10 RBAC/ABAC/SoD | Pundit deny-by-default + RLS + SoD | R01 IDOR/salto de tenant; fraude por colusión de funciones |
| §11 Asientos | Plantillas versionadas; partida doble por trigger; idempotencia | R2 asientos dobles; descuadre por concurrencia |
14. Conclusión
Esta colección no inventa arquitectura: cristaliza visualmente las decisiones ya reconciliadas en los entregables de software (05) y AWS (06) y en los documentos de dominio. Su valor para ConTodo es triple. (1) Onboarding: un ingeniero nuevo entiende el sistema completo —del contexto C4 al trigger de partida doble— en una sola lectura navegable. (2) Gobierno: cada diagrama es normativo y trazable a un ADR y a un riesgo, de modo que una desviación es detectable y discutible, no silenciosa. (3) Venta enterprise / due diligence: la defensa en profundidad multi-tenant (§4), el aislamiento de IA por tenant (§9) y el cumplimiento SUNAT (§5, §6, §11) son activos demostrables ante un comprador regulado o un auditor Big Four. Los once diagramas centrales más el apéndice DDD constituyen el plano único de ConTodo, listo para sostener tanto la primera línea de código como una sala de comité técnico.