ADR-011 · Contabilidad in-house · módulo cis-admin/contable, no SaaS¶
Fecha: 2026-04-27 Source:
/srv/projects/cis/cis-plan/DECISIONS.md(do not edit here — re-split desde la fuente)
Contexto
VISION.md (línea 60) declaró desde el día cero: "❌ Construir nuestro propio ERP desde cero. Integramos contra Nubox/Defontana/Previred o hacemos puentes." La intuición era razonable — la regulación tributaria CL es ruidosa (F29 mensual IVA, F22 anual renta, libros DTE oficiales, CAFs timbrados, cesión de facturas, propuesta SII, etc.) y los SaaS chilenos cubren todo eso por $15-30 USD/mes.
Pero entre 2026-04-09 (cuando los datos tributarios reales migraron a cis_admin) y 2026-04-17 03:09 UTC, el camino terminó siendo el opuesto. Ya está construido y corriendo en producción:
- Plan de cuentas 5 niveles (
PlanCuentamodel +CUENTAS_DEFAULTcon 18 cuentas seed cubriendo Activo/Pasivo/Patrimonio/Ingreso/Gasto ·cis-admin/backend/app/api/v1/contable.py:54-84). - Doble partida (
Asiento+LineaAsientocon balance debe=haber enforced en código). - Estados financieros endpoints:
GET /contable/{estado-resultados,balance,libro-diario,libro-mayor,libro-ingresos-egresos}con filtros porempresa_id+periodo. Régimen Pro-Pyme 14D soportado. - DTE bridge (
POST /contable/recibir-dte+POST /contable/emit-dte) que delega alcis-sii-gateway(:8270) para emisión y registra Factura recibida + asiento automáticamente. - Poller intercambio@ (
scripts/intercambio_poller.py· systemd timer cada 10 min) que lee buzón Gmail intercambio@innovacionsantiago.cl, extrae XMLs DTE adjuntos, y POST-ea al endpoint S2S/contable/poller/recibir-dtecon dedup por Message-ID. - Multi-empresa desde el día uno (
empresa_iden cada modelo). - Audit trail (
log_actionpor cada operación contable).
Commit referencia: d89907b7 (2026-04-17). CHANNEL referencia: 2026-04-17 03:09 UTC. La decisión nunca tuvo ADR; se construyó porque era la salida más limpia para el caso concreto. Este ADR documenta esa decisión retroactivamente y la formaliza como dirección.
Alternativas consideradas
- (a) Nubox / Bsale / Toteat / Defontana (la posición original de VISION.md)
- Pro: cero mantenimiento del módulo contable, soporte SII oficial, soporte humano por chat, conformidad fiscal garantizada por el proveedor.
- Contra: $15-30 USD/mes recurrente por empresa (CIS hoy = 1 empresa, pero la plataforma debe escalar a N empresas multi-tenant — costo crece linealmente). Datos tributarios sensibles en infra de tercero. Integración con
cis-inbox/ pollerintercambio@requiere webhooks que esos SaaS NO ofrecen (los DTEs llegarían dos veces: a su sistema + al nuestro, sin convergencia automática). La definición de cuentas y plan contable está sujeta al UI del proveedor. -
Costo de exit: alto. Migrar de un SaaS contable después de 1+ años de asientos es no trivial.
-
(b) Híbrido — usar Nubox para emisión DTE + asientos in-house para reporting
- Pro: emisión de factura electrónica oficialmente certificada via PPP (proveedor habilitado SII).
-
Contra: dos fuentes de verdad para Factura, sincronización constante, doble costo (SaaS + dev). El emisor DTE in-house ya está parcialmente construido en
cis-sii-gateway(vía cis-sign + maullin/palena SOAP) — abandonarlo desperdicia el trabajo. -
(c) In-house puro ← elegida (de facto desde 2026-04-17)
- Pro: control total sobre el modelo contable. Integración nativa: el poller intercambio@ → asiento + factura es 1 sola transacción atómica en el mismo Postgres. Cero recurring SaaS. Cuando hay multi-tenant (1 plataforma → N empresas), el costo marginal por empresa es ~0. El plan de cuentas es código + migración → versionable.
- Contra: nosotros somos responsables de mantener al día las reglas SII (cambios de F29, formatos DTE, CAFs, cesión, propuesta SII). Riesgo: regulación cambia y nuestro código no se entera hasta que hay un DTE rechazado. Mitigación: monitoreo del watcher SII (ADR pendiente) detecta cambios en la carpeta tributaria y alerta.
Decisión
Opción (c): contabilidad in-house en el módulo cis-admin/backend/app/api/v1/contable.py. No usamos SaaS contable de terceros para CIS SpA ni para las empresas que la plataforma onboardee.
Para casos donde el cliente ya tiene una contabilidad histórica en Nubox/Bsale/Defontana, ofrecemos import (one-shot, vía CSV o API del proveedor) pero la fuente de verdad post-onboarding es nuestro módulo.
Razones canónicas
- Control fiscal CL completo — F29 mensual, F22 anual, libros DTE oficiales (diario, mayor, ingresos-egresos), todo armado contra el plan de cuentas que nosotros definimos. Sin "el campo X que el SaaS llama Y".
- Integración nativa con poller
intercambio@— el endpoint S2SPOST /contable/poller/recibir-dteregistra factura + asiento + dedup en una sola transacción. Con SaaS, el poller tendría que llamar a una API externa, manejar errores de red, reconciliar duplicados — fragilidad innecesaria. - Sin SaaS recurrente — costo marginal ≈ 0 por empresa adicional. Cuando la plataforma escale, esto importa.
- Datos sensibles bajo nuestro control — tributario es categoría especial bajo la nueva ley de protección de datos personales chilena. Tener los asientos en
cis_admin(vps-cis, controlado) elimina toda la superficie de tercero-procesador. - Sinergia con cis-sii-gateway — el gateway ya hace login con cert, scrape de carpeta, emisión DTE SOAP. La contabilidad in-house es el otro extremo del mismo flujo.
- Ya construido y funcional — reescribir hacia un SaaS sería negar el trabajo del 2026-04-17.
Consecuencias
- Positivo: stack contable es código nuestro, testeable (
tests/api/test_contable.py), evolucionable. Cero pago mensual por empresa. Integración con poller intercambio@ + cis-sii-gateway + cis-mailer es 1 transacción. - Negativo: nosotros somos responsables de mantener compliance SII al día. Cuando el SII cambia el formato del F29 (sucede 1-2 veces al año), tenemos que actualizar el código. Cuando aparezca propuesta SII (2027 estimado), tenemos que implementar el flujo de aceptación.
- Equipo: requiere consultoría con un contador para cierre anual hasta que tengamos confianza interna. Costo: ~$200K CLP/año por empresa para cierre + revisión F22. Aún así es < 12×$30USD = ~$340K/año por empresa de SaaS.
- Multi-empresa: el modelo
empresa_idya está en cada tabla. Cada nueva empresa onboardeada se siembra automáticamente con_ensure_plan_cuentas(empresa_id)(contable.py:90). - Compliance certificación SII — emisor DTE oficial requiere certificación del proveedor en SII (ya en proceso vía cert MIV en
cis-sign). Hasta certificarse, emisión DTE corre enSII_ENV=cert(maullin), no producción. - Riesgo regulatorio — mitigación parcial: el
sii_watch(ADR pendiente, cis-sii-gateway watcher 08:00 daily, ya activo desde 2026-04-27) detecta cambios en la carpeta tributaria y notifica a cis-inbox; cualquier divergencia con nuestros asientos genera ticket. - Reversibilidad — alta. Si en 2-3 años decidimos migrar a Nubox, nuestros asientos están en Postgres; export a CSV es 1 query. La elección no cierra puertas.
Relaciones
- Reemplaza la postura
❌ no construimos ERPdeclarada enVISION.md:60. Actualizar VISION.md acompaña este ADR (cambio de ❌ a "✅ construido in-house, módulo cis-admin/contable"). - Depende de:
cis-sii-gateway(emisión DTE + scrape carpeta) ycis-sign(firma cert). Ambos ya operativos. - Habilita: poller
intercambio@(corriendo cada 10 min), F29 prep automatizado (backlog), libros oficiales para SII (backlog), reporting financiero en/contabilidaddel frontend nuevo (Fase D de ADR-010). - No alinea con: el item 1 del parking-lot original (que era sobre cis-admin Django vs rewrite, no sobre contabilidad). El user en la sesión 2026-04-27 pidió "reemplaza al punto 1 del parking-lot" — la mejor lectura de eso es que el parking-lot histórico no captura la decisión de contabilidad in-house, y este ADR lo formaliza como decisión arquitectural canónica independiente del parking-lot.
Implementación: aplicada de facto en sesión 2026-04-17 (commit d89907b7). Este ADR la formaliza retroactivamente. Pendiente: actualizar VISION.md:60 a la nueva postura.