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-adminlegacy 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
- (a) Django-only
- Descartar FastAPI+Next, mantener y extender Django (reutilizar su admin).
- Pro: menos código para mantener, Django admin ahorra 20+ CRUDs.
-
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.
-
(b) Next+FastAPI puro (rewrite) ← propuesta
- 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).
- 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.
-
Contra: hay que replicar el "poder de inspección" de Django admin. 4 semanas de trabajo según estimación Bloque 3.
-
(c) Híbrido coordinado
- Django para módulos "power features" (inspección ORM + admin UI + migrations), Next+FastAPI para UI de usuarios finales.
- Pro: no hay que reimplementar el admin Django.
- 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)
- 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).
- 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.
- Semana 3 — Cutover real: DNS
admin.innovacionsantiago.clapunta al nuevo Next, Django se apaga. ETL para cualquier diferencia residual via pg_dump → migration scripts one-off. - 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/pulsehoy 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). ActualizarCONTRACTS.mdpuertos internos al hacer el switch.