Desarrollo
Cómo trabajar en el código: requisitos, comprobaciones, datos de prueba y recorridos e2e. Los
comandos de uso diario están también en CLAUDE.md y en la tabla de «Todos los comandos», abajo.
Requisitos
Sección titulada «Requisitos»- Node 22 o posterior. El repo es un workspace de npm con dos apps:
apps/server(Node + TypeScript) yapps/web(React + Vite). npm cien la raíz instala las dos.- Docker solo hace falta para probar la imagen. En Windows, Docker no construye desde una carpeta sincronizada en la nube: usa un clon fuera de ella o el CI.
Antes de abrir un PR
Sección titulada «Antes de abrir un PR»Desde la raíz, todo en verde:
npm test # server (tsx --test) y web (node --test)npm run typecheck # servernpm run lint # server y web, sin avisosnpm run format:check # Prettier (npm run format lo arregla)npm run licencias # ninguna dependencia con licencia incompatible con la AGPLnpx knip # sin archivos, exports ni dependencias sin usonpm run buildEs lo mismo que comprueba el CI. Los recorridos e2e no van en el CI: córrelos en local antes de cerrar una rama (ver abajo).
Datos de prueba
Sección titulada «Datos de prueba»El repo no lleva datos reales de ninguna empresa, persona, cliente ni oferta:
- Empresa:
apps/server/tests/fixtures/empresaEjemplo.ts(yapps/web/tests/fixtures/empresaEjemplo.mjspara la web) es «Analítica Ejemplo, S.L.», con un NIF de control válido y provincia 00, que no puede ser de nadie. - Personas: nombres ficticios en los tests («Ana García Pérez», «Luis Prueba»…) y «Persona A», «Persona B»… en los fixtures, con perfiles genéricos.
- Licitaciones: los fixtures de
apps/server/tests/licitaciones/fixtures/(comprobaciones/,cambios/,ofertas/,costes/,casoA.ts,casoB.ts,eval/casoG/…) son casos inventados (casoA…casoG) con la forma de una oferta de verdad. Los PDF de pliego, los DEUC y la página del expediente se generan en el propio test (fixtures/documentos/*.ts, conpdf-lib); solo los.atomde la PLACSP y el ejemplo oficial de la UE (fixtures/documentos/espd-referencia/) son documentos públicos. fixtures/perfilesGenericos.mjsquita lo que identifica a alguien (cargo exacto, titulaciones, certificaciones raras, años exactos, empresa, sedes y lugares) ynode tests/licitaciones/fixtures/generalizarFixtures.mjs(desdeapps/server) lo aplica a los fixtures. Es idempotente: en un árbol limpio no cambia nada.
Si añades un fixture, invéntalo; no copies una oferta, un pliego anotado ni un CV. La estructura de los tests y de sus fixtures está en apps/server/tests/README.md.
Recorridos e2e (Playwright)
Sección titulada «Recorridos e2e (Playwright)»npm run e2e -w @sobre-abierto/webHay dos bancos:
- fixtures (
apps/web/e2e/*.spec.js): la web responde desdeapps/web/e2e/datos/<caso>.json, sin servidor. Esos JSON se generan con las rutas del servidor sobre los fixtures de las comprobaciones:npm run e2e:datos -w @sobre-abierto/server. Regenéralos cuando cambien los fixtures o lo que devuelve una ruta. - servidor (
apps/web/e2e/*.spec.mjs): compila la web y arranca un servidor propio.
Accesibilidad
Sección titulada «Accesibilidad»e2e/accesibilidad.spec.js pasa @axe-core/playwright (reglas WCAG 2 A y AA) por las pantallas principales, el login,
la Biblioteca y las pestañas de Ajustes con datos en los fixtures, y
exige cero violaciones graves (serious y critical). También comprueba que la barra lateral se maneja con el
teclado y que el foco se ve. Si añades una pantalla importante, añádela a la lista PANTALLAS.
Capturas de referencia
Sección titulada «Capturas de referencia»e2e/visual.spec.js compara las pantallas clave con capturas de referencia y comprueba que no
hay desplazamiento horizontal a 400 px. Las referencias no están en el repo
(apps/web/e2e/*-snapshots/ está en .gitignore): dependen del sistema y de las fuentes de cada
máquina. La primera vez, genéralas en la tuya:
cd apps/webnpx playwright test e2e/visual.spec.js --project=fixtures --update-snapshots=allRevísalas a ojo (están en apps/web/e2e/visual.spec.js-snapshots/). Desde entonces,
npm run e2e -w @sobre-abierto/web compara contra ellas: un cambio de más de un 0,2 % de
píxeles falla. Si el cambio es a propósito, vuelve a generarlas con la misma orden y revísalas.
Estructura del repo
Sección titulada «Estructura del repo»apps/ server/ TypeScript, Express + Socket.io: API, login, proxy al dashboard de Hermes, el motor de la Biblioteca de Conocimiento (src/biblioteca), el núcleo de la plataforma (src/nucleo: agentes, MCP, cola de IA, colaboradores) y su dominio (src/dominios/licitaciones), todo en el mismo proceso web/ React + Vite: la interfazinfra/ Dockerfile imagen del monitor (web + server con biblioteca, núcleo y dominios) drive-sync/ sincronizador con Google Drive (rclone) hermes-init/ prepara el volumen de Hermes: skills propias, token, permisosdocs/ instalación, configuración, operación, arquitectura, MCP, memoria técnica y FAQDetalle técnico en Arquitectura; operación de una instalación en Operar.
Todos los comandos
Sección titulada «Todos los comandos»Node 22+. Un solo npm install en la raíz instala todas las apps (npm workspaces).
| Comando | Qué hace |
|---|---|
npm install |
Instala las dependencias de todas las apps |
npm run build |
Compila el server (apps/server/dist) y la web (apps/web/dist) |
npm run dev:server |
Server en :3110 con recarga (tsx); sirve la web compilada |
npm run dev:web |
Vite en :5173 con proxy al server, para trabajar en la web |
npm test |
Tests de todas las apps |
npm run typecheck |
Typecheck del server |
npm run lint |
ESLint de server y web (sin avisos; lo exige el CI) |
npm run format:check |
Comprueba el formato con Prettier (lo exige el CI). npm run format formatea todo el repo |
npx knip |
Archivos, exports y dependencias sin uso (configuración en la clave knip de package.json; no es una dependencia del repo). Debe salir limpio |
npm run docs:mcp -w @sobre-abierto/server |
Regenera docs/referencia/mcp.md (tools MCP y permisos) a partir del registro de tools. Un test falla si el archivo está desfasado |
npm run licencias |
Revisa la licencia de cada dependencia del package-lock.json y falla si alguna es incompatible con la AGPL (SSPL, BUSL, Commons Clause, no comercial, GPL-2.0 sin «o posterior», sin licencia). Lo exige el CI |
npm run e2e -w @sobre-abierto/web |
Recorridos e2e con Playwright, en dos bancos: servidor (*.spec.mjs: aviso de versión, 409 version_antigua, lotes) compila su propia web y arranca un servidor con datos temporales; fixtures (*.spec.js: lista, ficha, Comprobaciones) sirve el build con vite preview en :4173 y responde la API desde apps/web/e2e/datos (e2e/api.js), sin servidor ni Socket.io. Uno solo: npm run e2e -w @sobre-abierto/web -- --project fixtures. La primera vez, npx playwright install chromium. No entra en npm test ni en el CI de GitHub (a propósito): se lanza en local antes de dar por cerrada una rama |
npm run e2e:datos -w @sobre-abierto/server |
Regenera apps/web/e2e/datos/<oferta>.json (y los casoE.impacto.*.json) con las rutas reales sobre los fixtures de las comprobaciones de las 5 ofertas, en una base temporal y con el reloj en la hora de la captura. Falla sin escribir nada si una respuesta lleva un NIF de persona, un correo o un teléfono. Hay que lanzarlo cuando cambie una respuesta de la API que lean los recorridos |
Scripts de apps/server/scripts/
Sección titulada «Scripts de apps/server/scripts/»Ninguno hace falta para ejecutar la plataforma; son herramientas de desarrollo y de calidad. Todos trabajan sobre
bases temporales y fixtures sintéticos, y ninguno lee un .env ni toca datos reales.
| Script | Para qué |
|---|---|
npm run e2e:datos -w @sobre-abierto/server |
Regenera los datos de los e2e (respuestasE2E.ts). |
npm run docs:mcp -w @sobre-abierto/server |
Regenera docs/referencia/mcp.md (generarDocsMcp.ts). |
npm run demo:base -w @sobre-abierto/server -- [destino] |
Crea una base local nueva con las cinco ofertas de ejemplo, para recorrer la web a mano (baseDemo.ts). |
npm run banco:respuestas -w @sobre-abierto/server -- preparar|puntuar <dir> |
Banco de 30 respuestas libres del asistente de la oferta para medir un modelo; hacen falta 27 aciertos (bancoRespuestas.ts). |
npx tsx scripts/evalMemorias.ts --caso casoG |
Banco de pruebas de memorias: encola juicios ciegos por pares de un caso de tests/licitaciones/fixtures/eval/ y compara el veredicto con el esperado (evalMemorias.ts). |
npx tsx scripts/generarCpv.ts <cpv_2008.xml> |
Regenera src/datos/cpv.json con el vocabulario CPV oficial de la UE; solo hace falta si la UE publica otra versión (generarCpv.ts). |
Para desarrollo local, copia .env.dev.example a .env en la raíz y ajústalo.
Imágenes de Docker, compilando desde el código:
docker compose -f docker-compose.yml -f deploy/docker-compose.build.yml buildEn Windows con el repo dentro de OneDrive, Docker Desktop no puede leer los archivos que OneDrive guarda como marcadores (“unknown file mode”). Construye desde un clon fuera de OneDrive o deja que lo haga el CI.