From c28de14af3f790ce35bc8340abeecb8d6561e9d3 Mon Sep 17 00:00:00 2001 From: David Arranz Date: Wed, 16 Sep 2026 13:34:31 +0200 Subject: [PATCH] =?UTF-8?q?A=C3=B1adir=20documentaci=C3=B3n=20detallada=20?= =?UTF-8?q?del=20proyecto=20y=20estructura=20del=20repositorio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agents.md | 237 ++++++++++++++++++++++++++++++++++++++++++ doc/ficha-proyecto.md | 225 +++++++++++++++++++++++++++++++++++++++ doc/readme.adoc | 0 3 files changed, 462 insertions(+) create mode 100644 agents.md create mode 100644 doc/ficha-proyecto.md mode change 100644 => 100755 doc/readme.adoc diff --git a/agents.md b/agents.md new file mode 100644 index 0000000..3ed8637 --- /dev/null +++ b/agents.md @@ -0,0 +1,237 @@ +# AGENTS.md + +## Alcance y seguridad + +Este repositorio es Presupuestador UECKO: una SPA para elaboración de presupuestos de mobiliario y una API REST para autenticación, catálogo, distribuidores, usuarios, perfiles, presupuestos y soporte. + +Antes de editar: + +1. Ejecuta `git status --short`. +2. Conserva los cambios existentes que no pertenezcan a la tarea. +3. Inspecciona el patrón del contexto, feature o componente equivalente antes de introducir una abstracción nueva. +4. No expongas ni copies secretos desde `stack.env`, archivos `.env` o configuraciones de entorno. + +No hagas commits, push, reset, rebase, instalaciones de dependencias, regeneración de lockfiles, migraciones ni operaciones Docker o de base de datos sin petición explícita. + +## Estructura + +- `client/`: SPA React 18 creada con Vite. +- `server/`: API REST Express, Passport y Sequelize. +- `shared/`: DTOs, entidades de valor, criterios de consulta, validadores y utilidades compartidas. +- `doc/readme.adoc`: especificación funcional e intención arquitectónica inicial. Contrasta siempre sus requisitos y endpoints con el código antes de asumir que están implementados. +- `dist/`: salida de build; no editar manualmente. +- `docker-compose.yml`, `Dockerfile.server`, `Caddyfile`: despliegue Docker/Caddy. + +El `package.json` raíz solo declara `shared` como workspace. `client` y `server` tienen paquetes y lockfiles propios. + +## Runtime y gestor de paquetes + +- Node.js: el raíz exige `>=18.19.0`; servidor exige `>=18`. +- TypeScript: `^5.5.4` en `client`, `server` y `shared`. +- Usa Yarn para los comandos existentes. Hay un `server/pnpm-lock.yaml` adicional: no lo elimines, regeneres ni deduzcas que pnpm es el gestor elegido sin una tarea específica. +- No hay versión de Node fijada mediante `.nvmrc`, `.node-version` o `.tool-versions`. +- El sistema operativo no está impuesto por el repositorio. + +## Arquitectura backend + +El backend está organizado por contextos bajo `server/src/contexts`: + +- `auth` +- `catalog` +- `profile` +- `sales` +- `support` +- `users` +- `common` + +En los contextos se repite la estructura: + +- `domain`: entidades, errores, interfaces de repositorio y reglas de dominio. +- `application`: casos de uso y servicios de aplicación. +- `infrastructure`: controladores Express, repositorios, mapeadores, modelos Sequelize y composición de dependencias. + +El flujo observable es: + +```text +routes Express -> middleware -> controller -> caso de uso/servicio -> repositorio/adaptador -> Sequelize/modelo +``` + +Mantén esta separación cuando el contexto existente la use. No conviertas una tarea local en una reestructuración arquitectónica. + +Las rutas API se montan en `/api/v1` desde: + +- `server/src/infrastructure/express/app.ts` +- `server/src/infrastructure/express/api/v1.ts` +- `server/src/infrastructure/express/api/routes/` + +Usa controladores, casos de uso, repositorios, mapeadores y DTOs ya existentes como referencia al extender un contexto. + +## Persistencia + +- Sequelize usa dialecto `mysql`; Docker suministra MariaDB mediante `mariadb:latest`. +- La configuración de conexión está en `server/src/config/environments/`. +- El adaptador principal está en `server/src/contexts/common/infrastructure/sequelize/SequelizeAdapter.ts`. +- Los modelos se localizan dinámicamente mediante el patrón `**/*.model.{js,ts}`. +- Las asociaciones de modelos se configuran después del registro. +- La configuración Sequelize usa convenciones `underscored`, timestamps, `utf8mb4` y `utf8mb4_unicode_ci`. +- Los repositorios y la infraestructura Sequelize son el lugar habitual para el acceso a persistencia; evita introducir consultas de base de datos en rutas o componentes. + +No hay migraciones ni seeds formales localizados. El arranque de `server/src/infrastructure/http/server.ts` ejecuta: + +```ts +sequelizeConn.sync({ force: false, alter: true }) +initStructure(...) +insertUsers() +``` + +Por ello, no inicies el backend, Docker Compose ni scripts de infraestructura contra una base de datos sin confirmar que la operación está dentro del alcance. No sustituyas este comportamiento por una estrategia de migraciones sin una tarea explícita. + +## Autenticación y autorización + +- Passport se configura en `server/src/contexts/auth/infrastructure/express/passport/`. +- Existen estrategias local por email y JWT. +- Las rutas autenticadas usan el middleware `checkUser`. +- Las operaciones administrativas usan middleware como `checkIsAdmin`; el acceso propio se controla con `checkAdminOrSelf` cuando corresponde. +- En frontend, autenticación se centraliza en `client/src/lib/hooks/useAuth/` y Axios añade la autorización desde `client/src/lib/axios/setupInterceptors.ts`. +- Las rutas de la SPA se protegen con `ProtectedRoute`. + +No confundas autenticación con autorización. Al añadir una ruta o mutación protegida, reutiliza el middleware y patrón de permisos más cercano. + +## Frontend + +- Punto de entrada: `client/src/main.tsx`. +- Providers globales: `client/src/App.tsx`. +- Rutas: `client/src/Routes.tsx`, mediante React Router y carga diferida. +- Features: `client/src/app/`. +- Componentes reutilizables: `client/src/components/`. +- Primitivas UI: `client/src/ui/`. +- Hooks, Context y utilidades: `client/src/lib/`. + +La comunicación HTTP se centraliza mediante: + +- `client/src/lib/axios/` +- `client/src/lib/hooks/useDataSource/` +- `DataSourceProvider` + +No introduzcas peticiones Axios directas desde componentes si el proveedor de datos y hooks existentes pueden expresar la operación. + +React Query gestiona datos remotos. Usa las claves de consulta de `client/src/lib/hooks/useQueryKey/KeyBuilder.ts` y los hooks existentes de `useDataSource` o del feature antes de crear claves o wrappers nuevos. + +Los formularios usan React Hook Form y componentes en `client/src/components/Forms/`. Para tablas, reutiliza `client/src/components/DataTable/`, los hooks relacionados y TanStack React Table. Para diálogos, botones y primitivas visuales, busca primero equivalentes en `components/` y `ui/`. + +La internacionalización se configura en `client/src/locales/i18n.ts`; los idiomas disponibles son `es`, `en` y `ca`, con español como fallback. Todo texto nuevo visible para usuarios debe seguir el patrón de traducciones existente cuando afecte a una zona internacionalizada. + +## Convenciones de código + +### Backend + +Patrones de nombres frecuentes: + +- Casos de uso: `*.useCase.ts` +- Controladores: `*.controller.ts` +- Repositorios: `*.repository.ts` +- Modelos: `*.model.ts` +- Mapeadores: `*.mapper.ts` +- Presentadores: `*.presenter.ts` + +Los DTO compartidos usan habitualmente nombres como `I..._Request_DTO` e `I..._Response_DTO`. + +La validación usa repetidamente Joi y `RuleValidator`, en DTOs, entidades y controladores. Sigue el patrón del endpoint o DTO equivalente. + +### Frontend + +- Componentes React: PascalCase. +- Hooks: prefijo `use`. +- Barrel exports: hay numerosos `index.ts`; manténlos cuando trabajes en directorios que ya los usen. +- Alias configurados: `@`, `@shared`, `@ui` y `@lib`. +- Hay mezcla de nombres en inglés y comentarios/UI en español. No impongas una normalización global dentro de cambios acotados. + +### Tipado + +TypeScript está en modo `strict` en cliente y servidor. El servidor mantiene `noImplicitAny: false` y ESLint permite `any`; el cliente lo reporta como advertencia. No amplíes `any` sin necesidad: prefiere tipos compartidos, DTOs, genéricos o `unknown` cuando el dato externo necesite validación. + +Mantén las comprobaciones explícitas de `null` y `undefined` en rutas y datos opcionales; `strictNullChecks` está activo en el servidor. + +## Errores y asincronía + +- El backend dispone de abstracciones de errores y respuesta HTTP bajo `server/src/contexts/common/infrastructure/express/`. +- Los controladores se ejecutan mediante `handleRequest` cuando el patrón del endpoint lo utiliza. +- Los errores de Axios se procesan en `client/src/lib/axios/setupInterceptors.ts`. +- React Query expone estados y errores a través de hooks; conserva el manejo de carga, error y mutación del feature equivalente. + +Usa `async`/`await` o devuelve explícitamente promesas según el patrón cercano. No ocultes errores de operaciones remotas ni introduzcas manejadores globales paralelos sin necesidad. + +## Testing y validación + +Jest y ts-jest están configurados en los tres paquetes. + +Pruebas localizadas: + +- Cliente: pruebas de tabla de catálogo y paginación. +- Shared: pruebas unitarias de entidades de valor y criterios de consulta. +- Servidor: no se localizaron pruebas bajo `server/src`. +- No se localizaron pruebas E2E ni configuración Cypress/Playwright. + +Ejecuta la validación más acotada y pertinente para el cambio. Los comandos reales son: + +```bash +# Tests +cd shared && yarn test +cd server && yarn test +cd client && yarn test + +# Lint +cd server && yarn lint +cd client && yarn lint + +# Build / comprobación TypeScript +cd server && yarn build +cd client && yarn build +``` + +No existe un script dedicado de typecheck ni de formato. El build de cliente elimina y recrea `dist/client`; no lo ejecutes si la tarea exige estrictamente no generar archivos. + +## Desarrollo y Docker + +```bash +# Desarrollo backend +cd server && yarn dev + +# Desarrollo frontend +cd client && yarn dev + +# Docker desde la raíz +yarn docker:rebuild +yarn docker:start +yarn docker:stop +yarn docker:restart +yarn docker:logs +yarn docker:build +yarn docker:ps +``` + +Docker Compose incluye Caddy, backend, MariaDB, phpMyAdmin y un servicio de espera de base de datos. El servicio frontend está comentado: Caddy sirve `dist/client` directamente y actúa como reverse proxy del backend. + +No reconstruyas contenedores, no levantes servicios y no ejecutes `docker compose down` como efecto colateral de cambios de código o revisiones. + +## Documentación y cambios funcionales + +Consulta antes de modificar funcionalidades de presupuestos: + +- `doc/readme.adoc`: alcance e intención funcional inicial. +- Rutas actuales en `server/src/infrastructure/express/api/routes/`. +- DTOs compartidos en `shared/lib/contexts/`. +- Feature frontend correspondiente bajo `client/src/app/`. +- Casos de uso y repositorios del contexto backend implicado. + +La especificación describe más capacidades de las que se observan necesariamente en rutas actuales. No implementes ni presupongas contratos, gestión completa de catálogo, pedidos o contratos solo porque aparezcan en la documentación de planificación. + +## Entrega + +Al finalizar una tarea: + +1. Resume los archivos modificados. +2. Indica las validaciones ejecutadas y su resultado. +3. Indica las validaciones no ejecutadas y por qué. +4. Señala cualquier inconsistencia relevante encontrada, sin modificarla fuera del alcance. +5. No incluyas secretos, tokens, contraseñas ni valores de entorno sensibles. diff --git a/doc/ficha-proyecto.md b/doc/ficha-proyecto.md new file mode 100644 index 0000000..822866e --- /dev/null +++ b/doc/ficha-proyecto.md @@ -0,0 +1,225 @@ +# Ficha del proyecto + +## 1. Identificación + +**Nombre del proyecto:** +Presupuestador UECKO (`uecko-presupuestador`, versión raíz `1.1.5`). + +**Objetivo principal:** +Aplicación web para que distribuidores creen, consulten, editen, dupliquen, envíen y descarguen presupuestos de mobiliario basados en un catálogo. Incluye autenticación, perfiles, gestión/listado de distribuidores y usuarios, generación de PDF de presupuestos y envío de incidencias. +Evidencia principal: `doc/readme.adoc`, `client/src/Routes.tsx`, `server/src/infrastructure/express/api/routes/`. + +**Estado actual:** +NO DETERMINADO. Hay configuración de despliegue, dominio de producción y variables de producción (`docker-compose.yml`, `Caddyfile`, `client/.env.production`), pero esto no acredita que esté actualmente desplegado ni que esté en mantenimiento. + +## 2. Repositorio + +**Repositorio principal:** +Ruta inspeccionada: `Z:\` (repositorio Git detectado). + +**Estructura general:** +Repositorio único con tres paquetes principales, no un monorepo de workspaces completo: + +- `client/`: SPA React/Vite. +- `server/`: API REST Express. +- `shared/`: contratos DTO, entidades de valor, utilidades y validaciones compartidas. + +El `package.json` raíz declara únicamente `shared` como workspace. `client` y `server` son paquetes independientes con sus propios lockfiles y comandos. + +## 3. Stack tecnológico + +**Backend:** + +- Node.js: `>=18.19.0` en raíz y `>=18` en `server/package.json`. La imagen Docker usa la etiqueta no fijada `node:lts-iron`. +- TypeScript: `^5.5.4` en `server/package.json`. +- Express: `^4.18.2`. +- Autenticación: Passport `^0.7.0`, estrategias local por email y JWT (`passport-local`, `passport-jwt`), JWT y bcrypt. +- ORM: Sequelize `^6.37.3`, con `sequelize-typescript` y `mysql2`. +- Validación: Joi, `@joi/date`, `@reis/joi-luxon`; validaciones distribuidas entre DTO, entidades y controladores. +- Logging: Morgan para solicitudes y Winston con rotación diaria. +- Generación de PDF: Puppeteer, Puppeteer Report y Handlebars. +- Documentación OpenAPI/Swagger: `express-openapi-validator` está declarado, pero no se localizó una especificación OpenAPI/Swagger ni uso observable de esta librería. + +**Frontend:** + +- TypeScript: `^5.5.4`. +- React y React DOM: `^18.2.0`. +- Vite: `^5.4.16`. +- Routing: React Router DOM `^6.26.0`, con `createBrowserRouter`. +- UI: configuración ShadCN/UI (`client/components.json`), componentes locales derivados de Radix UI y Radix UI como dependencia. +- Tailwind CSS: `^3.4.13`; PostCSS y `tailwindcss-animate`. +- Formularios: React Hook Form `^7.55.0`, `@hookform/resolvers` y Joi. +- Estado remoto: TanStack React Query `^5.51.23`; cliente Axios y proveedores mediante Context. +- Tablas: TanStack React Table `^8.20.1`. +- Internacionalización: i18next, react-i18next y detector de idioma; recursos `es`, `en` y `ca`. +- Otras bibliotecas relevantes: Axios, dnd-kit, React PDF, Recharts y Lucide. + +**Base de datos:** + +- Motor configurado por Sequelize: dialecto `mysql`. +- Servicio contenedorizado: imagen `mariadb:latest`; por tanto la versión de MariaDB no está fijada y `11.5` no puede confirmarse. +- Conexión mediante variables `MYSQL_*`; en producción el host previsto es el servicio `mariadb`. +- Migraciones: no se localizaron migraciones formales. +- Seeds: no se localizaron seeds formales. El servidor ejecuta inicialización propia mediante `initStructure()` e `insertUsers()` al arrancar. +- La sincronización Sequelize se ejecuta con `{ force: false, alter: true }`. + +**Testing:** + +- Infraestructura Jest/ts-jest declarada en los tres paquetes. +- Pruebas encontradas: 8 archivos de prueba: 2 en `client` y 6 en `shared`; no se localizaron pruebas bajo `server/src`. +- Testing Library está declarada en cliente; Supertest está declarado en servidor, sin pruebas de servidor localizadas. +- No hay evidencia de pruebas E2E con Cypress o Playwright. + +**Infraestructura / despliegue:** + +- Docker Compose con Caddy, MariaDB, backend, phpMyAdmin y un contenedor de espera de base de datos. +- Caddy sirve `dist/client` y actúa como reverse proxy HTTPS hacia el backend. +- El servicio frontend de Compose está comentado; el frontend se construye a `dist/client` y se monta directamente en Caddy. +- No se localizaron workflows de GitHub Actions, GitLab CI ni otra configuración CI/CD. +- Evidencia: `docker-compose.yml`, `Dockerfile.server`, `client/Dockerfile`, `Caddyfile`. + +## 4. Arquitectura + +**Estilo arquitectónico:** +Backend organizado por contextos funcionales y capas `domain` / `application` / `infrastructure`, sobre Express y Sequelize. Es razonable inferir una inspiración en puertos y adaptadores: hay interfaces de repositorio, casos de uso, adaptadores y mapeadores. No hay evidencia suficiente para afirmar cumplimiento uniforme de Clean Architecture o arquitectura hexagonal formal. + +**Organización principal:** + +- Backend: + - Contextos: `auth`, `catalog`, `profile`, `sales`, `support`, `users` y `common`. + - Las rutas Express construyen o invocan controladores. + - Los controladores delegan en casos de uso y servicios de aplicación. + - Los repositorios y modelos Sequelize residen en infraestructura. + - `common` aporta controladores base, errores HTTP, adaptador Sequelize, transacciones y utilidades compartidas. +- Frontend: + - Organización principal por funcionalidad en `client/src/app`: autenticación, catálogo, distribuidores, presupuestos, configuración y soporte. + - Componentes reutilizables en `components/`, UI base en `ui/`, hooks y proveedores en `lib/hooks/`. + - `shared/lib` contiene DTOs, entidades de valor, criterios de consulta y utilidades consumidos por cliente y servidor. + +**Reglas arquitectónicas importantes:** + +- Las rutas API se agrupan bajo `/api/v1` y aplican middleware de contexto común. +- Las rutas protegidas usan Passport y middleware `checkUser`; usuarios y distribuidores tienen controles adicionales para permisos administrativos o acceso propio. +- El acceso a base de datos se concentra predominantemente en adaptadores, repositorios y modelos de infraestructura Sequelize. +- Las llamadas HTTP del frontend se centralizan en el proveedor Axios y el `DataSourceProvider`. +- React Query maneja el estado remoto; los providers Context manejan autenticación, fuente de datos, tema y avisos de cambios sin guardar. +- El arranque del backend modifica potencialmente la estructura y datos de la base de datos mediante sincronización Sequelize e inicialización propia. + +## 5. Convenciones relevantes + +- Backend: nombres frecuentes `*.useCase.ts`, `*.controller.ts`, `*.repository.ts`, `*.model.ts`, `*.mapper.ts` y `*.presenter.ts`. +- Backend: los contextos usan directorios `domain`, `application` e `infrastructure`; los DTO compartidos suelen usar prefijos `I..._Request_DTO` e `I..._Response_DTO`. +- Backend: validación recurrente con Joi y `RuleValidator`; los controladores de listados validan parámetros de consulta. +- Backend: mapeadores separan entidades/modelos/DTO en varios contextos. +- Backend: TypeScript estricto está activado, pero `noImplicitAny` es `false` y ESLint permite explícitamente `any`. +- Frontend: componentes React en PascalCase; hooks con prefijo `use`; exports agrupados mediante múltiples `index.ts`. +- Frontend: alias `@`, `@shared`, `@ui` y `@lib` configurados para importaciones. +- Frontend: formularios construidos con React Hook Form y componentes de formulario reutilizables. +- Frontend: React Query usa una fábrica de claves (`KeyBuilder`); mutaciones y consultas se encapsulan habitualmente en hooks. +- Frontend: tablas reutilizables basadas en TanStack React Table y hooks asociados. +- Frontend: i18n se basa en detección del navegador y usa español como fallback. + +**Convenciones no uniformes detectadas:** + +- Hay lockfiles Yarn en raíz, cliente y servidor, pero también `server/pnpm-lock.yaml`; no existe campo `packageManager` que resuelva la ambigüedad. +- El root declara solo `shared` como workspace, aunque `client` y `server` son paquetes hermanos. +- Existen convenciones de capas sólidas en el backend, pero rutas y composición de dependencias presentan mezcla de factories, llamadas directas a controladores y funciones de contexto. +- Hay directorios y nombres de pruebas no homogéneos: `__test__`, `*.test.ts`, `*.test.tsx` y rutas con nombres de marcador. + +## 6. Comandos habituales + +**Instalación:** + +```bash +yarn install +cd shared && yarn install +cd ../server && yarn install +cd ../client && yarn install +``` + +**Desarrollo:** + +```bash +cd server && yarn dev +cd client && yarn dev +``` + +**Build:** + +```bash +cd server && yarn build +cd client && yarn build +``` + +**Tests:** + +```bash +cd shared && yarn test +cd server && yarn test +cd client && yarn test +``` + +**Typecheck:** + +No existe un script dedicado de typecheck. + +```bash +cd server && yarn build +cd client && yarn build +``` + +El build de servidor ejecuta `tsc`; el de cliente ejecuta `tsc` antes de Vite. + +**Lint:** + +```bash +cd server && yarn lint +cd client && yarn lint +``` + +**Formato:** + +NO DETERMINADO. Hay configuración Prettier en raíz, pero no se declara un script de formato. + +**Migraciones / seeds:** + +NO DETERMINADO como comandos. No se localizaron scripts ni herramientas de migración/seed declaradas. + +**Docker:** + +```bash +yarn docker:rebuild +yarn docker:start +yarn docker:stop +yarn docker:restart +yarn docker:logs +yarn docker:build +yarn docker:ps +``` + +## 7. Documentación de referencia + +- `doc/readme.adoc`: especificación funcional y arquitectónica inicial; describe requisitos, roles, modelo conceptual y diseño propuesto. Debe leerse como documento de intención, no como reflejo automático de la implementación. +- `package.json`, `server/package.json`, `client/package.json`, `shared/package.json`: fuente de verdad para scripts y dependencias declaradas. +- `docker-compose.yml`, `Dockerfile.server`, `Caddyfile`: referencia de despliegue local/servidor. +- `server/src/infrastructure/express/api/routes/`: contratos de rutas actualmente implementados. +- `server/src/config/environments/`: configuración de ejecución y conexión por entorno. + +## 8. Restricciones importantes + +- Node.js requiere como mínimo `18.19.0` según `package.json` raíz; servidor declara como mínimo Node 18. +- Las rutas API se sirven bajo `/api/v1`. +- El acceso a las rutas autenticadas exige JWT mediante Passport; varias operaciones de usuarios y distribuidores exigen permisos administrativos. +- La configuración de producción limita CORS a `https://presupuestos.uecko.com`. +- La aplicación cliente depende de `VITE_API_URL`. +- La persistencia usa dialecto MySQL a través de Sequelize; el despliegue Docker suministra MariaDB. +- El servidor puede alterar el esquema al iniciar debido a `sequelize.sync({ alter: true })`; no debe tratarse como un arranque sin efectos sobre la base de datos. +- Los idiomas configurados en cliente son español, inglés y catalán. + +## 9. Observaciones + +- Existe una separación real entre SPA, API y librería compartida, aunque los workspaces no abarcan todos los paquetes. +- El dominio implementado gira alrededor de autenticación, catálogo, presupuestos, distribuidores, perfil, usuarios y soporte. +- La documentación funcional describe también contratos y gestión del catálogo por fábrica, pero no toda esa funcionalidad se observa en las rutas implementadas; las decisiones deben contrastarse con código. +- Hay pruebas unitarias, pero su cobertura es limitada y no se localizaron pruebas de API ni E2E. +- No se localizaron CI/CD ni una especificación OpenAPI/Swagger usable. diff --git a/doc/readme.adoc b/doc/readme.adoc old mode 100644 new mode 100755