Auditoria de robustez del codigo OPS

Fecha: 2026-05-09

Objetivo

Revisar el estado tecnico de OPS con tres maximas:

  1. Escalable.
  2. Fiable.
  3. Robusto.

Esta auditoria no propone funcionalidades nuevas. Propone ordenar el codigo para reducir fragilidad, facilitar cambios y evitar que cada mejora rompa otra zona.

Estado actual medido

  • server.js: 8605 lineas.
  • public/index.html: 9509 lineas.
  • schema.sql: 293 lineas.
  • Rutas Express en server.js: mas de 120 endpoints en un unico archivo.
  • UI principal: HTML, estado global, API client, renderizado, modales, assistant, tareas, skills, subagentes, docs, dispatch y templates en un unico archivo.
  • Verificacion actual: npm run verify:frontend compila scripts inline y valida tokens/enlaces basicos.
  • Backend: node --check server.js valida sintaxis, pero no hay tests unitarios o de contrato por dominio.

Diagnostico

OPS ya tiene piezas valiosas: autenticacion, workspaces, tareas, perfiles, skills, dispatch, auditoria, docs y preferencias. El problema principal no es falta de funcionalidad sino acumulacion.

El riesgo real es que el sistema crece mediante cambios locales sobre dos monolitos. Eso hace que:

  • sea dificil localizar responsabilidades;
  • aumente el riesgo de regresiones visuales y de estado;
  • se repitan validaciones;
  • los cambios pequenos toquen zonas demasiado amplias;
  • los errores de renderizado lleguen tarde;
  • sea costoso razonar sobre seguridad, permisos y workspace scope.

Riesgos principales

1. Monolito frontend

public/index.html mezcla:

  • estructura HTML inicial;
  • traducciones;
  • estado global;
  • API client;
  • router/sidebar;
  • preferencias;
  • assistant;
  • vistas admin;
  • tareas;
  • kanban;
  • skills;
  • subagentes;
  • recurrentes;
  • modales;
  • helpers de render.

Impacto:

  • cualquier cambio UI puede romper otra vista;
  • los handlers inline onclick dificultan refactor y pruebas;
  • el render con innerHTML masivo aumenta riesgo de errores y XSS accidental si falta esc;
  • no hay frontera clara entre vista, estado y API.

2. Monolito backend

server.js mezcla:

  • arranque Express;
  • auth;
  • workspace access;
  • auditoria;
  • credenciales;
  • agentes/perfiles;
  • tareas;
  • dispatch;
  • templates;
  • skills;
  • SaaS admin;
  • helpers de negocio;
  • SQL inline.

Impacto:

  • dificil probar dominios aislados;
  • dificil auditar permisos por ruta;
  • alto coste mental para modificar endpoints;
  • riesgo de inconsistencias en validacion y workspace scope;
  • muy dificil introducir tests sin separar responsabilidades.

3. Schema historico con compatibilidad acumulada

Hay migraciones incrementales correctas, pero el schema base y las migraciones mezclan etapas:

  • algunas tablas nacieron globales y luego recibieron workspace_id;
  • algunos UNIQUE(slug) historicos pueden limitar multiworkspace si no se han relajado;
  • parte de la integridad depende de codigo de aplicacion;
  • falta una verificacion automatica de invariantes de schema.

Impacto:

  • riesgo de comportamiento distinto entre local, staging y produccion;
  • riesgo de constraints antiguas que contradigan el modelo SaaS;
  • dificultad para saber si una instalacion esta realmente alineada.

4. Verificacion insuficiente para el tamano actual

La verificacion actual ayuda, pero no cubre:

  • endpoints criticos;
  • permisos por rol;
  • aislamiento workspace;
  • render real de vistas principales;
  • contratos API;
  • regresiones de modales;
  • dispatch y human gates como flujo completo.

Impacto:

  • los errores aparecen al usar la UI;
  • se arregla una cosa y se rompe otra;
  • cada despliegue genera ansiedad operativa.

Principios de refactor

  • No reescritura completa.
  • No funcionalidades nuevas durante el refactor.
  • Cambios pequenos, verificables y con rollback claro.
  • Extraer primero codigo estable, no codigo en plena mutacion.
  • Mantener endpoints y HTML publico funcionando durante cada fase.
  • Desplegar por fases con smoke tests antes de continuar.

Plan por fases

Fase 0: Guardrails antes de tocar

Objetivo: impedir que el sistema siga creciendo sin control.

Acciones:

  • anadir script verify:architecture;
  • medir lineas de server.js y public/index.html;
  • fallar si crecen por encima de un umbral salvo excepcion explicita;
  • comprobar que no aparecen nuevos onclick en zonas refactorizadas;
  • comprobar que no se anaden nuevas rutas directamente en server.js una vez exista server/routes.

Estado inicial:

  • npm run verify:architecture queda como guardrail temporal.
  • npm run verify:all ejecuta sintaxis backend, frontend y arquitectura.
  • Limite temporal server.js: 8700 lineas, objetivo 1500.
  • Limite temporal public/index.html: 9700 lineas, objetivo 1500.
  • Limite temporal rutas inline en server.js: 132, objetivo 25.
  • Limite temporal scripts inline en public/index.html: 3, objetivo 1.
  • La verificacion frontend tambien compila scripts locales enlazados desde public/.

Criterio de salida:

  • npm run verify:frontend;
  • node --check server.js;
  • npm run verify:architecture.

Fase 1: Separar backend sin cambiar comportamiento

Objetivo: convertir server.js en un ensamblador.

Primeros modulos seguros:

  • server/config.js: constantes y env normalizada.
  • server/db.js: pool y helpers SQL basicos.
  • server/http.js: wrapper w, errores y respuestas comunes.
  • server/auth.js: sesiones, cookies, roles y usuarios.
  • server/workspaces.js: workspace actual y permisos.
  • server/audit.js: recordAuditEvent.

Despues:

  • server/routes/profiles.js;
  • server/routes/skills.js;
  • server/routes/tasks.js;
  • server/routes/dispatch.js;
  • server/routes/admin.js.

Criterio de salida:

  • endpoints iguales;
  • sin cambio de payloads;
  • smoke existente funcionando;
  • diff facil de revisar.

Fase 2: Separar frontend en modulos vanilla

Objetivo: no introducir framework todavia; solo modularizar.

Estructura propuesta:

  • public/js/api.js;
  • public/js/state.js;
  • public/js/i18n.js;
  • public/js/theme.js;
  • public/js/router.js;
  • public/js/views/subagents.js;
  • public/js/views/skills.js;
  • public/js/views/tasks.js;
  • public/js/views/templates.js;
  • public/js/views/admin.js;
  • public/js/components/modal.js;
  • public/js/components/table.js;
  • public/js/components/badges.js;

Regla:

  • cada vista exporta loadXView() y helpers privados;
  • los handlers nuevos se conectan con addEventListener;
  • innerHTML permitido solo en funciones de render controladas;
  • cualquier dato de usuario pasa por esc o por asignacion DOM segura.

Criterio de salida:

  • public/index.html baja progresivamente por debajo de 1500 lineas;
  • las vistas principales viven en modulos;
  • la verificacion frontend carga y compila todos los modulos.

Fase 3: Contratos y tests ligeros

Objetivo: detectar errores antes de abrir la UI.

Acciones:

  • tests de helpers puros con node:test;
  • tests de normalizacion de metadata de perfiles;
  • tests de permisos/workspace scope;
  • tests de contrato de endpoints criticos con fixtures;
  • smoke UI minimo para: tareas, subagentes, skills, recurrentes, preferencias.

Criterio de salida:

  • npm test existe;
  • cubre flujos que ya han fallado antes;
  • ningun refactor pasa sin tests basicos.

Fase 4: Invariantes de base de datos

Objetivo: que el sistema avise si el schema no corresponde al modelo operativo.

Acciones:

  • script verify:schema;
  • comprobar workspace_id NOT NULL en tablas operativas;
  • comprobar indices esperados;
  • comprobar constraints unicas compatibles con workspace;
  • comprobar existencia de migraciones aplicadas.

Criterio de salida:

  • local y produccion pueden verificarse con el mismo comando;
  • cualquier divergencia queda clara antes de desplegar.

Orden recomendado

  1. Crear guardrails de arquitectura.
  2. Extraer helpers frontend puros (esc, CSV, metadata profile, badges).
  3. Extraer vista de subagentes a modulo, porque esta activa y acaba de crecer.
  4. Extraer API client y estado global.
  5. Extraer backend de perfiles/skills.
  6. Anadir tests de metadata/permisos.
  7. Repetir por tareas y dispatch.

No hacer ahora

  • No meter React/Vite todavia.
  • No rehacer la UI entera.
  • No cambiar endpoints publicos.
  • No cambiar schema funcional salvo que una verificacion demuestre inconsistencia.
  • No anadir compatibilidad externa con otros agentes.
  • No mover todo de golpe.

Primer incremento recomendado

Crear verify:architecture y extraer helpers puros del frontend:

  • public/js/utils.js;
  • public/js/profile-metadata.js;
  • public/js/ui-badges.js.

Esto reduce riesgo sin tocar negocio. Despues se puede mover la vista de subagentes a public/js/views/subagents.js.

Estado 2026-05-09:

  • creado scripts/verify-architecture.js;
  • anadido npm run verify:architecture;
  • anadido npm run verify:all;
  • extraidos helpers puros a public/js/ops-utils.js;
  • public/index.html baja de 9509 a 9403 lineas;
  • scripts/verify-ops-frontend.js compila tambien scripts locales enlazados desde public/.

Definicion de hecho

Cada fase debe cerrar con:

  • sintaxis backend OK;
  • frontend verify OK;
  • smoke relevante OK;
  • diff pequeno;
  • documentacion actualizada;
  • tiempo anotado si se gestiona desde OPS;
  • despliegue solo despues de verificar localmente.