Saltar a contenido

ADR-013 · Stack canónico para cis-admin (rewrite Next+FastAPI)

Fecha: 2026-04-22 Source: /srv/projects/cis/cis-plan/DECISIONS.md (do not edit here — re-split desde la fuente)


Mergeado 2026-04-29 desde ADRs-borrador-013-015-016.md (P0.3). Numeración renumerada 2026-04-27 (era ADR-010 en el borrador original; ese número fue tomado por el ADR-010 mergeado cis-admin · rewrite frontend a Vite+React+TS). Este ADR conserva una propuesta de alcance más amplio (decommission Django + cutover plan + 4 semanas) que NO está cubierta por el ADR-010 mergeado.

Contexto

Hoy coexisten 3 stacks en /srv/projects/cds/cis/cis-admin/:

Stack Entrada Puerto Rol actual
Django legacy manage.py + cds_admin.settings dev runserver / no systemd prod UI productivo HOY (usuarios lo usan)
FastAPI nuevo backend/run.py 8244 · 2 workers · cis-admin-backend.service API del admin, timers de Claudia v1
Next.js 16 frontend/next.config.mjs con rewrites a :8244 8245 · cis-admin-frontend.service UI nuevo, aún no reemplaza el Django

Ambos stacks apuntan al mismo Postgres cis_admin. Los modelos están duplicados en Django ORM y SQLAlchemy.

Backlog Bloque 3 (3.1 · 3.2) pide un ADR explícito antes de escribir código del rewrite. BACKLOG.md deja el parking-lot: "¿refactor Django in-place o rewrite FastAPI+Next.js?".

Datos relevantes

  • cds-admin legacy tiene 208 .py, 83 .tsx/.ts, 30+ models, 30+ API routers, 15+ services, 15+ frontend pages, 22+ systemd units (docs/architecture/CDS-ADMIN-INVENTORY.md).
  • Datos tributarios reales (F29, F22, facturas, obligaciones, declaraciones) ya viven en Postgres cis_admin — migraron desde vps-deploy.
  • El resto del ecosistema ya es Next.js + FastAPI: periodismo2, situacion, cis-inbox, indieweb-idea, cis-usaia, cis-platform, cis-claudia. Consistencia de ecosistema es una fuerza grande.
  • Django admin reemplaza bien un CRUD genérico inspector, pero mantener dos ORM sincronizados es deuda permanente (cada nuevo modelo toca 2 lugares, cada migration corre 2 veces).

Alternativas consideradas

  1. (a) Django-only
  2. Descartar FastAPI+Next, mantener y extender Django (reutilizar su admin).
  3. Pro: menos código para mantener, Django admin ahorra 20+ CRUDs.
  4. Contra: todo el ecosistema CIS restante es Next+FastAPI — cis-admin quedaría como bicho raro. No hay SSR moderno, los hooks de cis-auth (OIDC) y la stack de MCP/Claudia son más naturales en Python asyncio + Next app-router. El Django del legacy tiene 10+ años de deuda.

  5. (b) Next+FastAPI puro (rewrite)propuesta

  6. Apagar Django gradualmente. Next.js como único frontend, FastAPI :8244 → :8210 como único backend. El "power-admin" lo replicamos con una UI CRUD genérica en Next (formularios generados por schema).
  7. Pro: consistencia con el ecosistema, un solo ORM (SQLAlchemy async), un solo lugar donde agregar features. Claudia v2 naturalmente se integra por HTTP MCP (ADR-015). Migraciones via Alembic único. Stack familiar para cualquiera que haya tocado otro servicio del CIS.
  8. Contra: hay que replicar el "poder de inspección" de Django admin. 4 semanas de trabajo según estimación Bloque 3.

  9. (c) Híbrido coordinado

  10. Django para módulos "power features" (inspección ORM + admin UI + migrations), Next+FastAPI para UI de usuarios finales.
  11. Pro: no hay que reimplementar el admin Django.
  12. Contra: dos stacks sincronizados indefinidamente → el peor de los mundos. La "frontera" entre "power user" y "usuario final" se difumina con el tiempo y termina requiriendo features duplicadas en ambos lados.

Decisión propuesta

Opción (b): rewrite Next+FastAPI puro, apagar Django gradualmente.

Razones:

  • Consistencia del ecosistema > ahorro puntual. cis-admin es el hub operativo del CIS — si es distinto al resto de los servicios, es un roce constante para los agentes (Claudia + humanos + Claude Code) que navegan entre todos.
  • Un ORM elimina deuda permanente. Modelos Django y SQLAlchemy sobre el mismo schema producen bugs sutiles (naming, migrations, relationships).
  • Data ya migrada — pg_dump completo está hecho, no reimportamos. El rewrite toca código + UI, no datos.
  • Next.js 16 + FastAPI ya es el default (ADR-003 · "Stack mismo que illanes00").

Plan de cutover (4 semanas)

  1. Semana 1 — FastAPI expone API feature-parity con los 30+ routers del backend legacy. Next.js replica las 15 páginas frontend más usadas (Pareto).
  2. Semana 2 — Django pasa a modo read-only (serve pages para consultas, pero todos los writes ya van por FastAPI). Tests E2E contra el nuevo stack.
  3. Semana 3 — Cutover real: DNS admin.innovacionsantiago.cl apunta al nuevo Next, Django se apaga. ETL para cualquier diferencia residual via pg_dump → migration scripts one-off.
  4. Semana 4 — Decomm Django: borrar cds_admin/, manage.py, db.sqlite3. Condición de cierre: 0 tickets de soporte que citen el legacy durante la semana.

Dependencias previas

  • ADR-015 (Claudia v2) definido — los timers cis-admin-claudia-followup/heartbeat/pulse hoy disparan pipelines de Claudia v1 embebida; el rewrite requiere extraerlos.
  • cis-inbox /messages/{id}/assign + /approvals (plan §1.12 C) implementados — cis-admin depende de ellos.
  • Ventana de downtime acordada (objetivo: <15 min en cutover).

Consecuencias

  • Positivo: un solo stack, un solo ORM, integración natural con Claudia v2 (HTTP MCP) y resto del ecosistema. Nuevos features se escriben una sola vez.
  • Negativo: 4 semanas de trabajo bloqueando otras cosas del Bloque 3. Riesgo de perder alguna feature oscura del Django admin que nadie documentó.
  • Riesgo operacional: durante el cutover (semana 3) hay ventana corta donde el legacy está off pero el nuevo aún no captura 100% del flujo. Mitigar con rollback plan (DNS revert + Django on en <5 min).
  • Puertos: post-cutover :8210 + :8211 (ya reservados en CLAUDE.md). Actualizar CONTRACTS.md puertos internos al hacer el switch.