From 0e7106f30c4d155171c9caadee077e392528b9fb Mon Sep 17 00:00:00 2001 From: David Date: Thu, 17 Sep 2026 22:29:38 +0200 Subject: [PATCH] Refactor documentation for project architecture and guidelines - Updated "Ficha del proyecto UECKO.md" to clarify architectural boundaries and continuity rules. - Revised "README.md" to enhance structure and clarify sources of truth for documentation. - Improved "backend.md" with clearer definitions of responsibilities and architectural layers. - Streamlined "convenciones.md" to emphasize naming conventions and TypeScript best practices. - Enhanced "datos-persistencia.md" to specify persistence rules and data integrity measures. - Updated "frontend.md" to define frontend rules and state management practices. - Refined "testing.md" to clarify testing levels and validation processes. - Revised "vision-general.md" to outline system architecture and module boundaries more clearly. --- AGENTS.md | 1381 +---------------------- docs/Ficha del proyecto UECKO.md | 17 +- docs/README.md | 44 +- docs/arquitectura/backend.md | 63 +- docs/arquitectura/convenciones.md | 58 +- docs/arquitectura/datos-persistencia.md | 45 +- docs/arquitectura/frontend.md | 49 +- docs/arquitectura/testing.md | 46 +- docs/arquitectura/vision-general.md | 42 +- 9 files changed, 185 insertions(+), 1560 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d85379b..61bba47 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,131 +1,20 @@ # AGENTS.md -## Ámbito +## Ámbito y objetivo -Estas instrucciones se aplican a todo el monorepo, salvo que exista un archivo `AGENTS.md` más específico en un subdirectorio. +Estas instrucciones se aplican a todo el monorepo, salvo que un `AGENTS.md` descendiente las concrete o restrinja sin duplicarlas innecesariamente. -Los archivos `AGENTS.md` descendientes pueden añadir, concretar o restringir reglas para su ámbito. +Trabajar mediante cambios correctos, mínimos, comprobables, seguros, coherentes con la arquitectura y fáciles de revisar y mantener. Priorizar claridad y explicitud frente a abstracción prematura. -No deben duplicar innecesariamente las reglas de este documento. +## Entorno ---- - -## Objetivo - -Trabajar sobre el proyecto mediante cambios: - -* correctos; -* mínimos; -* comprobables; -* coherentes con la arquitectura existente; -* seguros; -* fáciles de revisar; -* fáciles de entender y mantener. - -Antes de modificar código, revisar las implementaciones y patrones existentes en el área afectada. - -No introducir un patrón nuevo cuando ya exista una solución equivalente y adecuada dentro del proyecto. - ---- - -## 1. Principios generales - -Antes de realizar cambios: - -1. Inspeccionar el código relevante. -2. Comprender la implementación y el flujo actual. -3. Buscar patrones equivalentes dentro del repositorio. -4. Identificar el alcance real de la tarea. -5. Consultar la documentación normativa relevante. -6. Evitar suposiciones que puedan verificarse directamente. -7. Determinar cómo se validará el cambio antes de implementarlo cuando la tarea sea relevante. - -Aplicar de forma pragmática: - -* SOLID; -* Clean Code; -* DRY; -* KISS; -* YAGNI; -* SSOT; -* Fail Fast; -* programación defensiva; -* inmutabilidad cuando resulte adecuada; -* idempotencia; -* principio de menor privilegio; -* observabilidad en APIs y servicios. - -Estos principios no justifican por sí solos una refactorización o abstracción nueva. - -Priorizar: - -```text -claridad y explicitud - > -abstracción prematura -``` - -Preferir: - -* cambios mínimos y focalizados; -* soluciones explícitas; -* reutilización de abstracciones existentes; -* coherencia con el proyecto frente a buenas prácticas genéricas; -* evidencia comprobable frente a especulación; -* simplicidad frente a generalización prematura. - -No introducir capas, adaptadores, factories, genéricos, eventos, contenedores DI u otras abstracciones sin una necesidad real y actual. - ---- - -## 2. Entorno de desarrollo - -### Stack principal - -* Node.js 24.x -* TypeScript -* PNPM -* Turborepo -* ExpressJS -* React -* MariaDB -* Sequelize v6 -* Zod v4 -* Biome - -### Entorno esperado - -```text -Sistema operativo: WSL2 Ubuntu 24.04 -Ruta canónica del repositorio: /home/david/dev/uecko-control-tiempos -Runtime: Node.js 24.x -Gestor de paquetes: pnpm 11.25.0 -``` - -Todos los comandos de desarrollo deben ejecutarse dentro de WSL2 usando Linux y `bash`. - -Trabajar sobre el entorno canónico salvo que la tarea requiera expresamente otro. - -No utilizar como entorno de desarrollo: - -* Windows; -* PowerShell; -* rutas UNC; -* `\\wsl$\...`; -* unidades Windows o de red; -* rutas bajo `/mnt/c`; -* copias antiguas del repositorio; -* workspaces alternativos; - -salvo que la tarea lo requiera expresamente. - -Abrir y manipular el repositorio mediante su ruta Linux real: +Trabajar en WSL2 Ubuntu mediante Linux y `bash`, usando la ruta canónica: ```text /home/david/dev/uecko-control-tiempos ``` -Antes de una tarea de código relevante, comprobar como mínimo: +Antes de una tarea de código relevante, ejecutar: ```bash pwd @@ -135,1254 +24,84 @@ node --version pnpm --version ``` -Se espera: +El entorno objetivo es Node.js 24.x y PNPM 11.25.0. Si no coincide, identificar la causa antes de modificar código. No usar Windows, PowerShell, rutas UNC, `/mnt/c`, copias antiguas ni workspaces alternativos salvo petición expresa. No cambiar runtime, gestor de paquetes ni `packageManager` como efecto colateral. -```text -Repositorio: /home/david/dev/uecko-control-tiempos -Sistema: Linux bajo WSL2 -Node.js: 24.x -PNPM: 11.25.0 -``` +## Secretos y configuración local -Si el entorno no coincide con el definido por el proyecto, identificar la causa antes de modificar código. +No exponer, copiar en respuestas, registrar ni versionar secretos, credenciales, claves, tokens, contraseñas o cadenas de conexión. No modificar configuración local salvo que la tarea lo requiera expresamente. -No cambiar versiones de runtime, gestores de paquetes o configuración del entorno como efecto colateral de una tarea no relacionada. +## Antes de modificar código -La versión de PNPM declarada mediante `packageManager` en el `package.json` raíz es vinculante. +Para cambios no triviales: -No modificar `packageManager` como consecuencia incidental de otra tarea. +1. Inspeccionar el código y flujo relevantes. +2. Identificar módulos, contratos, consumidores, dependencias, persistencia, tests, documentación y efectos laterales afectados. +3. Buscar patrones equivalentes antes de crear una abstracción, clase, servicio, hook, componente, mapper, repositorio, schema, tipo o mecanismo de validación. +4. Localizar la causa raíz de un bug; no aplicar fixes especulativos. +5. Determinar alcance y validación antes de implementar cuando corresponda. ---- +Reutilizar o extender soluciones existentes cuando sean adecuadas. No crear abstracciones solo para eliminar una duplicación pequeña y local. -## 3. Secretos y configuración local +## Control del alcance -Los archivos locales de configuración que puedan contener secretos no deben: +Modificar solo lo necesario. No realizar refactors, renombrados, movimientos, reformateos masivos, limpiezas, cambios de API, actualizaciones de dependencias o configuración global ajenos a la tarea. Informar de problemas adicionales y no corregirlos salvo que bloqueen el objetivo o estén incluidos expresamente. -* mostrarse innecesariamente; -* copiarse completos a respuestas; -* incluirse en logs; -* versionarse accidentalmente. +## Documentación normativa -Nunca exponer: +Antes de modificar un área, consultar el documento aplicable y no violar sus límites: -* contraseñas; -* tokens; -* API keys; -* claves privadas; -* secretos; -* cadenas de conexión completas; -* credenciales. +- [Visión general](docs/arquitectura/vision-general.md): módulos, dependencias y composición. +- [Backend](docs/arquitectura/backend.md): capas, contratos HTTP, casos de uso, dominio, errores y seguridad. +- [Convenciones](docs/arquitectura/convenciones.md): TypeScript, naming, async, comentarios, dependencias y documentación. +- [Datos y persistencia](docs/arquitectura/datos-persistencia.md): ORM, transacciones, integridad, migraciones e histórico. +- [Frontend](docs/arquitectura/frontend.md): estado, formularios, UI, accesibilidad e i18n. +- [Testing](docs/arquitectura/testing.md): cobertura y estrategia de validación. +- [Flujo de trabajo](docs/guias/flujo-chatgpt-codex.md) y [cierre de tareas](docs/guias/cierre-de-tareas.md): procedimiento operativo. +- [Ficha del proyecto](docs/Ficha%20del%20proyecto%20UECKO.md): contexto e invariantes funcionales disponibles. -No modificar archivos de configuración local salvo que la tarea lo requiera expresamente. +No afirmar que una regla, tecnología o arquitectura esté implementada si no existe evidencia en el repositorio. ---- +## Dependencias y seguridad -## 4. Auditar antes de implementar +No añadir ni actualizar dependencias sin necesidad real y justificada; comprobar primero alternativas existentes, mantenimiento, compatibilidad e impacto. No modificar lockfiles incidentalmente ni añadir supresiones de análisis sin justificación. -Para cambios no triviales, inspeccionar la implementación existente antes de modificarla. +Validar entradas externas, preservar autorización, aislamiento de datos y controles de seguridad definidos en la documentación normativa. Aplicar siempre el principio de menor privilegio. -Determinar, cuando corresponda: +## Validación -* puntos de entrada; -* módulos afectados; -* flujo funcional; -* flujo de dominio y aplicación; -* persistencia; -* contratos públicos; -* consumidores; -* dependencias; -* tests; -* documentación relevante; -* efectos laterales. +Usar primero la validación más acotada que aporte evidencia suficiente. Consultar los scripts reales antes de ejecutarlos; no inventar comandos. Preferir el workspace afectado cuando baste y validación global para cambios transversales. -Para bugs, localizar la causa raíz antes de aplicar una corrección. +Añadir o actualizar tests cuando cambie comportamiento observable. Informar exactamente de los comandos ejecutados y sus resultados. Distinguir fallos introducidos, preexistentes, ajenos al área y validaciones no ejecutadas; no atribuir ni ocultar fallos sin evidencia. -No aplicar fixes especulativos únicamente porque hagan desaparecer un error. +## Refactors, legacy y archivos generados ---- +Un refactor preserva comportamiento salvo indicación expresa. Para uno grande: auditar, identificar consumidores, dividir en fases y validar entre ellas. -## 5. Buscar patrones existentes primero +Antes de eliminar legacy, buscar referencias en todo el monorepo y revisar imports, rutas, entry points, composition roots, DI, modelos, repositorios, mappers, tests, scripts y documentación. Eliminar solo lo demostrado como no utilizado y documentar referencias residuales justificadas. -Antes de crear una nueva: +No modificar manualmente archivos generados; utilizar su procedimiento oficial y no incluir artefactos no relacionados. -* abstracción; -* clase; -* servicio; -* hook; -* componente; -* mapper; -* repositorio; -* utilidad; -* schema; -* tipo; -* tipo de error; -* capa arquitectónica; -* mecanismo de validación; +## Git -buscar si ya existe una solución equivalente en el repositorio. - -Preferir reutilizar o extender patrones existentes cuando sean adecuados. - -No duplicar funcionalidad sin justificación. - -Tampoco crear una abstracción nueva únicamente para eliminar una duplicación pequeña y local. - ---- - -## 6. Control del alcance - -Modificar únicamente lo necesario para completar la tarea solicitada. - -No realizar automáticamente: - -* refactors ajenos a la tarea; -* renombrados no relacionados; -* movimientos de archivos innecesarios; -* reformateos masivos; -* corrección de warnings no relacionados; -* actualización de dependencias; -* cambios de configuración global; -* cambios en APIs públicas; -* limpieza general del repositorio. - -Si se detectan problemas adicionales: - -1. indicar que existen; -2. explicar si afectan a la tarea; -3. no corregirlos salvo que bloqueen el trabajo o estén incluidos explícitamente en el alcance. - ---- - -## 7. Arquitectura general - -El backend sigue: - -* DDD pragmático; -* Clean Architecture; -* arquitectura hexagonal. - -Separación obligatoria: - -```text -Domain - no conoce Application ni Infrastructure - -Application - depende de Domain, contratos y Core - no conoce Express, Sequelize ni modelos ORM - -Infrastructure - depende de Application, Domain y Core -``` - -No se permite: - -* `Domain -> Application`; -* `Domain -> Infrastructure`; -* `Application -> Infrastructure`; -* importar infraestructura interna de otro módulo; -* compartir repositorios entre módulos; -* utilizar Service Locator; -* introducir DI implícita o mágica. - -Preservar: - -* dirección de dependencias; -* límites de módulo; -* límites de dominio; -* encapsulación; -* contratos públicos; -* límites transaccionales; -* aislamiento de datos; -* controles de seguridad. - -El composition root de cada módulo debe construir explícitamente sus dependencias. - -Antes de modificar una frontera arquitectónica, identificar productores, consumidores y efectos derivados. - -La documentación arquitectónica específica del proyecto prevalece sobre estas reglas resumidas. - -### Invariantes funcionales del proyecto - -Respetar además: - -* aplicación y datos deben permanecer separados; -* una actualización no puede destruir ni sobrescribir información histórica; -* los datos deben sobrevivir a cambios de versión; -* los cambios estructurales de datos deben realizarse mediante mecanismos controlados; -* las migraciones deben preservar información existente; -* ninguna evolución debe exigir reintroducción manual de históricos; -* las operaciones relevantes deben mantener trazabilidad; -* Oficina Comercial y Oficina Técnica son módulos funcionales diferenciados; -* cada módulo es propietario de los datos que genera; -* un módulo no debe modificar datos propiedad de otro sin permiso expreso; -* los identificadores de presupuesto y OF procedentes de Factuges son identificadores maestros externos; -* la aplicación no debe inventar, sustituir ni reutilizar esos identificadores. - ---- - -## 8. Documentación normativa - -La documentación normativa constituye la fuente de verdad para arquitectura, contratos e invariantes del producto. - -No duplicar innecesariamente su contenido en `AGENTS.md`. - -Referencias arquitectónicas normativas: - -```text -- docs/architecture/backend-architecture.md -- docs/architecture/dependency-injection.md -- docs/architecture/http-request-flow.md -- docs/architecture/dto-guidelines.md -- docs/architecture/testing-guidelines.md -``` - -Referencias funcionales: - -```text -- Respaldo_Arquitectura_Tecnica_Aplicacion_v1.1.md -- Documento funcional de Oficina Comercial -- Documento funcional de Oficina Técnica -``` - -Las rutas deben ajustarse a la ubicación real de dichos documentos en el repositorio. - -Las reglas incluidas en este `AGENTS.md` funcionan principalmente como instrucciones operativas. - ---- - -## 9. Idioma y convenciones de nombres - -* Código e identificadores en inglés. -* Comentarios y TSDoc en castellano. -* Documentación en castellano. -* Ficheros y directorios en `kebab-case`. -* Clases, tipos e interfaces en `PascalCase`. -* Variables, funciones y métodos en `camelCase`. -* Constantes globales en `UPPER_SNAKE_CASE` solo cuando realmente sean constantes globales. -* Mantener prefijo `I` para interfaces cuando el área existente ya utilice esa convención. - -Las convenciones existentes en cada área prevalecen frente a introducir una variación aislada. - ---- - -## 10. TypeScript - -Preservar la seguridad de tipos. - -### Imports de tipos - -Usar imports explícitos mediante `import type` para dependencias utilizadas exclusivamente como tipos: - -```ts -import type { UniqueID } from "@repo/rdx-ddd"; -import type { Result } from "@repo/rdx-utils"; -``` - -No usar referencias inline en código fuente ordinario: - -```ts -// No permitido -companyId: import("@repo/rdx-ddd").UniqueID; -``` - -Reglas: - -* usar `import type { ... } from "..."` para toda dependencia utilizada exclusivamente como tipo; -* mantener imports de tipos en la cabecera del fichero; -* separar imports de tipos y runtime cuando sea claro hacerlo; -* no introducir imports de runtime para símbolos usados solo como tipos; -* permitir tipos inline únicamente en `.d.ts`, module augmentation, código generado o casos excepcionales técnicamente justificados. - -### Seguridad de tipos - -* Evitar `any`. -* Usar `unknown` cuando el tipo todavía no sea conocido. -* No usar type assertions salvo que exista una garantía verificable que el compilador no pueda inferir. -* Evitar `!` salvo que la invariante esté demostrada localmente. -* Preferir tipos semánticos frente a primitivas genéricas. -* Modelar conjuntos cerrados mediante unions o enums existentes. -* Mantener exhaustividad en `switch` para conjuntos cerrados. -* No introducir `default` cuando oculte casos no contemplados que puedan comprobarse exhaustivamente. -* No duplicar tipos derivados de schemas Zod. -* No utilizar `Partial` cuando el schema o tipo de entrada ya modele explícitamente la opcionalidad. -* Mantener inmutabilidad cuando no exista necesidad real de mutación. - -No modificar contratos públicos sin revisar previamente productores y consumidores. - -Al modificar: - -* DTOs; -* schemas; -* APIs; -* eventos; -* modelos persistidos; -* tipos compartidos; - -revisar su uso completo. - ---- - -## 11. `Result`, `Maybe` y `Collection` - -Usar los patrones del proyecto: - -* `Result` para operaciones que pueden fallar; -* `Maybe` para ausencia semántica; -* `Collection` para conjuntos de objetos del mismo tipo cuando el dominio requiera comportamiento propio. - -No sustituirlos por: - -* excepciones; -* `null`; -* arrays; -* tipos ad hoc; - -cuando el patrón correspondiente sea aplicable. - -No utilizar excepciones para representar flujo de negocio esperado salvo que el diseño concreto del módulo lo establezca expresamente. - -Los errores esperables deben modelarse mediante contratos explícitos. - ---- - -## 12. Zod y DTOs - -Zod es la fuente única de verdad para los contratos HTTP. - -Reglas: - -* inferir tipos mediante `z.infer`; -* no duplicar DTOs mediante interfaces manuales equivalentes; -* cada endpoint debe disponer de DTOs de request y response; -* reutilizar subschemas únicamente cuando sean estables y realmente compartidos; -* no mezclar validación de transporte con lógica de negocio; -* evitar `.default()` en DTOs de negocio salvo necesidad justificada; -* evitar `.transform()` en DTOs de negocio salvo necesidad justificada; -* diferenciar explícitamente: - - * campo omitido; - * `null`; - * cadena vacía; - * colección vacía; -* utilizar schemas semánticos para: - - * UUID; - * fechas; - * timestamps; - * porcentajes; - * importes; - * cantidades; -* los valores decimales exactos no deben viajar como `number`. - -No mantener una interfaz manual que reproduzca exactamente un schema Zod. - ---- - -## 13. Flujo de entrada backend - -Para el flujo habitual: - -```text -RequestDTO - ↓ -UseCase({ dto, context }) - ↓ -InputMapper - ↓ -Value Objects / Props -``` - -`RequestMapper -> Command` es opcional. - -Solo debe utilizarse cuando exista una adaptación HTTP real, por ejemplo: - -* combinar `body`, `params` y `query`; -* adaptar estructuras de transporte; -* resolver diferencias reales entre transporte y aplicación. - -No crear `RequestMapper` únicamente para renombrar campos que Application volverá a transformar. - ---- - -## 14. Casos de uso - -Los casos de uso deben: - -* orquestar; -* gestionar transacciones cuando corresponda; -* delegar responsabilidades específicas en servicios de aplicación; -* devolver `Result`; -* construir respuestas mediante builders o mappers de salida. - -No deben: - -* contener lógica HTTP; -* utilizar Express; -* utilizar Sequelize directamente; -* utilizar modelos ORM; -* construir agregados directamente desde DTOs HTTP; -* asumir responsabilidades propias de repositorios; -* asumir responsabilidades propias de controllers; -* asumir responsabilidades propias de infraestructura. - ---- - -## 15. Servicios de aplicación - -Preferir servicios: - -* pequeños; -* explícitos; -* con una responsabilidad concreta; -* nombrados según su función real. - -Evitar nombres genéricos como: - -* `Manager`; -* `GenericService`; -* `CommandService`; -* `BaseRepository`; -* `Helper` sin semántica concreta. - -No convertir un servicio de aplicación en un contenedor genérico de lógica no relacionada. - ---- - -## 16. Repositorios - -* Cada repositorio gestiona un agregado o una responsabilidad concreta. -* Sequelize no debe salir de Infrastructure. -* Los repositorios deben usar mappers de persistencia. -* No crear repositorios base genéricos sin necesidad demostrada. -* Los repositorios no se comparten entre módulos. -* No exponer repositorios como API pública de un módulo. -* Mantener aislamiento por `companyId` y `branchId` cuando corresponda. - -No utilizar modelos Sequelize como contratos públicos. - ---- - -## 17. Mappers de persistencia - -Utilizar un mapper bidireccional por agregado: - -```ts -toPersistence(); -toDomain(); -``` - -El mapper es responsable de traducir entre: - -* representación de dominio; -* representación persistida. - -Infrastructure debe reconstruir entidades mediante `rehydrate()`. - -No introducir lógica de negocio nueva dentro del mapper. - ---- - -## 18. `create()` y `rehydrate()` - -Mantener separadas ambas operaciones. - -```text -create() - - creación funcional - valida invariantes - puede fallar - devuelve Result -``` - -```text -rehydrate() - - reconstrucción desde persistencia - no valida reglas de creación - no genera eventos - no devuelve Result -``` - -Reglas: - -* Infrastructure utiliza `rehydrate()`. -* Application y Domain utilizan `create()` para instancias nuevas. -* `update()` no utiliza `create()` ni `rehydrate()`. -* Los Value Objects no tienen `rehydrate()`. -* Los Value Objects se reconstruyen mediante `create()`. - -No utilizar `create()` para reconstruir automáticamente una entidad ya válida almacenada en persistencia. - ---- - -## 19. Comunicación entre módulos - -Los módulos únicamente deben colaborar mediante servicios públicos explícitos. - -No exponer entre módulos: - -* repositorios; -* modelos Sequelize; -* mappers internos; -* servicios de escritura internos; -* detalles de Infrastructure. - -No importar Infrastructure interna de otro módulo. - -Cada módulo debe mantener su propio composition root. - -Las dependencias entre módulos deben ser explícitas. - ---- - -## 20. Snapshots y builders de respuesta - -Los schemas Zod definen el contrato de salida. - -Los snapshot builders materializan ese contrato. - -Reglas: - -* tipar el builder mediante el DTO inferido del schema exacto; -* no crear interfaces `I*Snapshot` que dupliquen un DTO; -* el builder debe ser determinista; -* el builder no debe contener lógica de negocio; -* puede transformar `Maybe` a `null`; -* puede transformar Value Objects a primitivas; -* puede transformar enums internos a valores del contrato; -* no puede acceder a repositorios; -* no puede acceder a Infrastructure; -* si cambia el schema, el builder debe producir un error de compilación si deja de satisfacer el contrato. - ---- - -## 21. Comentarios - -Los comentarios deben aportar información que el código no expresa por sí solo. - -Deben explicar cuando corresponda: - -* por qué existe una decisión; -* qué riesgo evita; -* qué contrato debe respetarse; -* qué efectos laterales son relevantes; -* qué error se evita; -* qué invariantes existen; -* qué limitaciones no son evidentes. - -No deben limitarse a traducir el código a lenguaje natural. - -Documentar con TSDoc las APIs públicas cuando aporte información sobre: - -* propósito; -* parámetros; -* valor devuelto; -* errores; -* efectos laterales; -* invariantes; -* restricciones. - -Después de un refactor, actualizar o eliminar comentarios obsoletos. - ---- - -## 22. Documentación del proyecto - -La documentación: - -* se redacta en castellano; -* reside en `/docs`; -* utiliza Markdown; -* utiliza nombres de fichero en castellano. - -Reglas de estilo: - -* lenguaje claro; -* frases directas; -* evitar ambigüedad; -* evitar frases rebuscadas o innecesariamente largas; -* evitar tecnicismo innecesario; -* utilizar terminología técnica cuando sea necesaria para ser preciso; -* no convertir documentación en una transcripción del código; -* evitar párrafos densos cuando una explicación más breve sea suficiente. - -Priorizar explicar: - -```text -qué hace el sistema -por qué existe una regla -qué comportamiento debe esperarse -qué restricciones deben respetarse -``` - -No duplicar documentación. - -Cuando exista un documento autoritativo, actualizarlo en lugar de crear otro equivalente. - ---- - -## 23. Manejo de errores - -Seguir la estrategia de errores existente. - -No: - -* ocultar errores silenciosamente; -* transformar fallos en resultados exitosos para continuar; -* sustituir errores específicos por errores genéricos sin motivo; -* utilizar logging como sustituto del tratamiento de errores; -* ignorar promesas rechazadas; -* ocultar excepciones inesperadas. - -Preservar contexto suficiente para diagnosticar fallos sin exponer información sensible. - -Usar errores tipados y predecibles. - -Mantener contratos de error estables. - -Mapear errores de Domain y Application a HTTP en Infrastructure. - -No devolver: - -* SQL; -* stack traces; -* detalles internos; -* información sensible. - ---- - -## 24. Operaciones asíncronas - -El proyecto aplica: - -```text -lint/complexity/noVoid -``` - -Está prohibido utilizar `void` para descartar una promesa. - -No generar: - -```ts -void handleDuplicate(); -void handleDownload(); -void asyncOperation(); -``` - -Toda `Promise` debe gestionarse explícitamente. - -### Esperar - -```ts -await operation(); -``` - -### Devolver - -```ts -return operation(); -``` - -### Gestionar explícitamente el fallo - -```ts -operation().catch(handleUnexpectedError); -``` - -La última opción solo procede en operaciones deliberadamente no bloqueantes. - -Reglas: - -* no eliminar `void` dejando una promesa flotante; -* no utilizar `.catch(() => undefined)` para silenciar errores; -* antes de convertir un callback a `async`, comprobar su contrato; -* si el contrato exige `void`, encapsular la operación y gestionar explícitamente el error; -* no utilizar `void` como mecanismo para indicar intención. - ---- - -## 25. Integridad de datos - -Cuando se modifique persistencia o lógica transaccional, comprobar: - -* atomicidad; -* consistencia; -* rollback; -* concurrencia; -* aislamiento; -* integridad referencial; -* compatibilidad con datos existentes. - -No asumir que una escritura satisfactoria implica que la operación funcional completa haya terminado correctamente. - -Cuando una invariante crítica pueda garantizarse también en base de datos, aplicar esa protección además de la validación de aplicación cuando resulte razonable. - -Preservar especialmente: - -* usuarios; -* expedientes; -* OF; -* tareas; -* imputaciones de tiempo; -* errores; -* históricos; -* registros de actividad; -* configuraciones funcionales; -* trazabilidad. - -No eliminar físicamente información con histórico cuando corresponda desactivarla. - ---- - -## 26. Seguridad - -Aplicar el principio de menor privilegio. - -No: - -* introducir secretos en el repositorio; -* registrar datos sensibles; -* confiar automáticamente en identificadores enviados por el cliente; -* confiar en permisos enviados por el cliente; -* interpolar manualmente SQL. - -Validar toda entrada externa. - -Usar consultas parametrizadas y APIs seguras de Sequelize. - -Revisar: - -* autenticación; -* autorización; -* aislamiento tenant; -* permisos; -* contexto autenticado. - -Validar autorización además de autenticación. - -No confiar en identificadores de compañía enviados por el cliente sin contrastarlos con el contexto autenticado. - -Mantener aislamiento multiempresa en todas las consultas y mutaciones. - ---- - -## 27. Idempotencia - -Aplicar idempotencia en operaciones que puedan repetirse. - -Especialmente revisar: - -* comandos repetibles; -* peticiones reenviadas; -* reintentos de infraestructura; -* operaciones de creación; -* integraciones; -* migraciones; -* procesos de actualización. - -Una repetición accidental no debe producir efectos duplicados cuando la semántica de la operación requiera idempotencia. - ---- - -## 28. Base de datos y Sequelize - -* Mantener nombres de tablas y columnas coherentes con las convenciones existentes. -* No introducir modelos Sequelize fuera de Infrastructure. -* No permitir acceso directo a modelos Sequelize desde Application o Domain. -* Ejecutar operaciones agregadas dentro de una transacción cuando deban ser atómicas. -* Diseñar migraciones idempotentes cuando corresponda al procedimiento del proyecto. -* No eliminar columnas, tablas o datos legacy sin auditoría previa. -* No confiar exclusivamente en validaciones de aplicación cuando una invariante crítica pueda reforzarse en base de datos. -* No utilizar `JSON.stringify` para detectar cambios de dominio. -* Comparar Value Objects semánticamente mediante primitivas o métodos de igualdad apropiados. -* Preservar compatibilidad con datos existentes. - -Sequelize no debe convertirse en parte de contratos públicos. - ---- - -## 29. Frontend - -Mantener según los patrones existentes: - -* React; -* TanStack Query; -* TanStack Table; -* React Hook Form; -* Zod; -* shadcn/ui; -* Tailwind; -* i18n. - -Reglas: - -* no duplicar estado remoto en estado local sin necesidad; -* mantener operaciones de servidor en TanStack Query; -* centralizar query keys según la convención existente; -* invalidar o actualizar caché explícitamente después de mutaciones; -* no introducir efectos para derivar estado calculable durante render; -* evitar componentes monolíticos; -* extraer responsabilidades cuando exista una frontera semántica clara; -* no extraer componentes triviales que solo oculten JSX; -* mantener accesibilidad; -* contemplar estados: - - * `disabled`; - * `loading`; - * `empty`; - * `error`; -* no eliminar acciones no disponibles si la UX requiere mostrarlas deshabilitadas; -* mantener traducciones en `es` y `en` al añadir textos visibles; -* no insertar textos directamente cuando el área utilice i18n; -* utilizar `tabular-nums` en columnas monetarias cuando corresponda; -* preservar comportamiento responsive. - ---- - -## 30. APIs - -* Usar errores tipados y predecibles. -* Mantener contratos de error estables. -* Mapear errores de Domain y Application a HTTP en Infrastructure. -* Aplicar idempotencia en operaciones repetibles. -* Validar autorización antes de acceder o modificar datos. -* Mantener aislamiento tenant. -* No confiar en identificadores de compañía proporcionados por el cliente sin verificar el contexto autenticado. -* Registrar información suficiente para diagnosticar fallos sin exponer información sensible. -* No devolver detalles internos. - ---- - -## 31. Dependencias - -No añadir ni actualizar dependencias salvo necesidad real. - -Antes de añadir una dependencia: - -1. comprobar si el proyecto ya proporciona funcionalidad equivalente; -2. justificar por qué es necesaria; -3. evaluar mantenimiento; -4. evaluar compatibilidad; -5. revisar impacto en bundle o runtime. - -No modificar lockfiles innecesariamente. - -No actualizar PNPM como efecto colateral de otra tarea. - -No añadir supresiones de: - -* TypeScript; -* Biome; -* ESLint; -* otras herramientas de análisis; - -sin justificar el motivo. - ---- - -## 32. Tests - -Añadir o actualizar tests cuando cambie comportamiento observable. - -Preferir tests de: - -* comportamiento; -* contratos; -* invariantes; -* casos límite; - -frente a detalles accidentales de implementación. - -En bugs, añadir test de regresión cuando sea viable. - -Cubrir cuando corresponda: - -* caso válido; -* caso inválido; -* límites; -* errores; -* idempotencia; -* autorización; -* concurrencia. - -Mantener tests deterministas. - -No utilizar esperas arbitrarias. - -No desactivar tests para conseguir una suite verde. - ---- - -## 33. Estrategia de validación - -Usar primero la validación más acotada que aporte evidencia suficiente. - -Orden habitual: - -```text -test específico -↓ -tests del módulo / paquete -↓ -typecheck del módulo -↓ -lint del módulo -↓ -integration tests -↓ -E2E -↓ -validación global -``` - -Preferir: - -```bash -pnpm --filter typecheck -pnpm --filter lint -pnpm --filter test -``` - -cuando la validación del workspace resulte suficiente. - -Ejecutar validación global cuando el cambio afecte: - -* paquetes compartidos; -* contratos públicos; -* configuración transversal; -* varios módulos; -* infraestructura común. - -Antes de finalizar, ejecutar según corresponda: - -```bash -pnpm typecheck -pnpm lint -pnpm test -``` - -Y cuando sea aplicable: - -```bash -pnpm check -pnpm build -``` - -No ejecutar validaciones globales costosas si una comprobación dirigida aporta evidencia suficiente, salvo que el riesgo lo justifique. - -Informar exactamente de los comandos ejecutados. - -No considerar completada una tarea con errores conocidos de: - -* typecheck; -* lint; -* tests; -* build; - -salvo que el usuario haya limitado expresamente el alcance. - ---- - -## 34. Fallos preexistentes - -Distinguir claramente: - -* fallos causados por el cambio actual; -* fallos preexistentes; -* fallos ajenos al área modificada; -* validaciones no ejecutadas. - -No atribuir un fallo existente al cambio sin evidencia. - -No declarar un fallo como preexistente sin haberlo comprobado cuando la distinción resulte relevante. - -No ocultar fallos de: - -* compilación; -* typecheck; -* lint; -* tests; -* build. - ---- - -## 35. Comandos - -Usar herramientas y scripts propios del repositorio. - -Antes de ejecutar comandos, revisar: - -* `package.json`; -* scripts; -* configuración; -* workspaces; -* documentación. - -No inventar comandos si pueden obtenerse directamente del repositorio. - -### Instalación - -```bash -N/A — obtener del package.json/documentación del repositorio -``` - -### Desarrollo - -```bash -N/A — obtener del package.json/documentación del repositorio -``` - -### Tests - -```bash -pnpm test -``` - -### Typecheck - -```bash -pnpm typecheck -``` - -### Lint - -```bash -pnpm lint -``` - -### Check - -```bash -pnpm check -``` - -### Build - -```bash -pnpm build -``` - -Los comandos anteriores deben utilizarse únicamente si existen como scripts reales del repositorio. - -Preferir comandos acotados al workspace cuando sean suficientes. - ---- - -## 36. Refactors - -Un refactor debe preservar comportamiento salvo indicación expresa en contrario. - -No mezclar refactors amplios con cambios funcionales sin necesidad. - -Para refactors grandes: - -1. auditar el estado actual; -2. identificar referencias y consumidores; -3. definir fases; -4. ejecutar cambios incrementales; -5. validar entre fases; -6. eliminar legacy únicamente cuando se haya demostrado que ya no es necesario. - ---- - -## 37. Eliminación de código legacy - -Antes de eliminar código aparentemente obsoleto: - -1. buscar referencias en todo el monorepo; -2. revisar imports; -3. revisar rutas; -4. revisar entry points; -5. revisar composition roots; -6. revisar DI; -7. revisar modelos; -8. revisar repositorios; -9. revisar mappers; -10. revisar tests; -11. revisar scripts; -12. revisar documentación. - -Clasificar las referencias como: - -* activas; -* legacy no cableado; -* migraciones; -* documentación; -* tests; -* falsos positivos. - -Eliminar únicamente aquello demostrado como no utilizado. - -Ejecutar después: - -* typecheck relevante; -* lint relevante; -* tests relevantes. - -Documentar cualquier referencia residual y el motivo de conservarla. - ---- - -## 38. Archivos generados - -No modificar manualmente archivos generados salvo que el proyecto lo requiera. - -Cuando un cambio necesite regenerarlos, utilizar el procedimiento oficial. - -No incluir artefactos generados no relacionados con la tarea. - ---- - -## 39. Higiene Git - -Mantener cambios pequeños y revisables. - -Preferir una unidad lógica por conjunto de cambios. - -Antes de finalizar: +Mantener cambios pequeños y revisables. Antes de finalizar ejecutar: ```bash git status --short git diff ``` -Revisar el diff para detectar: +Revisar cambios accidentales, formato, código temporal, logs, artefactos generados, secretos y lockfiles. No hacer commits, pushes, resets destructivos ni reescribir historial sin petición expresa. -* modificaciones no relacionadas; -* cambios accidentales de formato; -* código temporal; -* logs de depuración; -* archivos generados inesperados; -* secretos; -* cambios en lockfiles no justificados. +## Cierre e informe -No reescribir historial ajeno a la tarea. +Una tarea es completa solo cuando el objetivo y alcance están cubiertos, la arquitectura se respeta, las validaciones relevantes aportan evidencia, no hay cambios accidentales y se declaran limitaciones reales. Usar los estados `COMPLETA`, `PARCIAL` o `BLOQUEADA` según la guía de cierre. -No realizar: +En tareas relevantes, informar de: estado, diagnóstico o causa raíz, cambios, decisiones relevantes, archivos principales, comandos de validación, resultados y riesgos o pendientes. -* commits; -* pushes; -* resets destructivos; -* modificaciones de historial; +## Fuente de verdad y precedencia -salvo petición expresa o flujo explícito del proyecto. +Para instrucciones operativas, prevalecen: requisito explícito de la tarea, `AGENTS.md` más cercano, `AGENTS.md` superiores, este fichero, guías operativas y convenciones existentes. ---- +Para producto y arquitectura, prevalecen: requisitos vigentes, documentación normativa, contratos e invariantes establecidos, tests de comportamiento intencionado, implementación, documentación auxiliar y suposiciones. -## 40. Criterios de finalización - -Una tarea solo debe marcarse como completa cuando: - -* se haya implementado el comportamiento solicitado; -* se respete la arquitectura; -* el alcance solicitado esté cubierto; -* las validaciones relevantes se hayan ejecutado; -* los errores introducidos por el cambio estén resueltos; -* no existan cambios accidentales; -* se hayan indicado las limitaciones conocidas. - -Estados: - -```text -COMPLETA -PARCIAL -BLOQUEADA -``` - -Si una validación requerida no puede realizarse, indicarlo. - -No afirmar que algo: - -* compila; -* funciona; -* pasa tests; -* está corregido; -* está validado; - -sin evidencia. - ---- - -## 41. Informe final - -Al terminar una tarea relevante, indicar: - -1. **Estado:** COMPLETA / PARCIAL / BLOQUEADA -2. **Diagnóstico o causa raíz** -3. **Cambios realizados** -4. **Decisiones relevantes** -5. **Archivos principales modificados** -6. **Comandos de validación ejecutados** -7. **Resultado de las validaciones** -8. **Riesgos o pendientes reales** - -Evitar informes excesivamente largos para tareas sencillas. - ---- - -## 42. Fuente de verdad - -Cuando exista información contradictoria, no asumir automáticamente qué fuente es correcta. - -### Instrucciones operativas - -Orden general: - -1. requisitos explícitos de la tarea; -2. `AGENTS.md` más cercano al archivo modificado; -3. `AGENTS.md` de niveles superiores; -4. este `AGENTS.md` raíz; -5. convenciones existentes en el área; -6. preferencias generales del agente. - -### Comportamiento e invariantes del producto - -Orden general: - -1. requisitos explícitos y vigentes del producto; -2. documentación normativa vigente; -3. contratos públicos e invariantes establecidas; -4. tests que expresen comportamiento intencionado; -5. implementación actual; -6. documentación auxiliar; -7. contexto de conversaciones; -8. suposiciones. - -Los tests no deben considerarse automáticamente correctos cuando contradigan de forma evidente una fuente normativa vigente. - -Un `AGENTS.md` no debe utilizarse para invalidar silenciosamente una regla funcional o arquitectónica normativa. - -Si código, tests y documentación discrepan de forma relevante, investigar la discrepancia antes de modificar comportamiento. - ---- - -## 43. Regla de precedencia - -En caso de conflicto entre instrucciones operativas: - -1. instrucciones explícitas del usuario para la tarea actual; -2. `AGENTS.md` más cercano al archivo modificado; -3. `AGENTS.md` de niveles superiores; -4. este `AGENTS.md` raíz; -5. convenciones existentes del área; -6. preferencias generales del agente. - -Una instrucción de nivel inferior puede concretar o restringir otra superior dentro de su ámbito. - -La documentación normativa gobierna: - -* comportamiento funcional; -* arquitectura; -* contratos; -* invariantes del producto. - -Si una instrucción contradice: - -* arquitectura normativa; -* una invariante crítica; -* una regla de seguridad; -* un contrato público establecido; - -investigar y señalar el conflicto antes de introducir el cambio. +No usar `AGENTS.md` para contradecir silenciosamente documentación normativa. Ante discrepancias relevantes entre código, tests y documentación, investigarlas y señalar el conflicto antes de cambiar comportamiento. diff --git a/docs/Ficha del proyecto UECKO.md b/docs/Ficha del proyecto UECKO.md index 25563e3..7961d7e 100644 --- a/docs/Ficha del proyecto UECKO.md +++ b/docs/Ficha del proyecto UECKO.md @@ -56,7 +56,7 @@ La aplicación y la base de datos deben mantenerse separadas conceptualmente: * la aplicación contiene interfaz, lógica de negocio, pantallas, navegación y funcionalidades; * la base de datos contiene usuarios, perfiles, permisos, presupuestos, expedientes, OF, estados, tareas, tiempos, errores, comentarios, trazabilidad e históricos. -**Reglas arquitectónicas importantes:** +**Límites arquitectónicos y de continuidad:** * El programa y los datos deben permanecer separados. * Una actualización de la aplicación no puede sobrescribir ni eliminar información operativa o histórica. @@ -70,6 +70,8 @@ La aplicación y la base de datos deben mantenerse separadas conceptualmente: * Los cambios relevantes deben poder probarse en un entorno Beta antes de aplicarse a Producción. * El desarrollador no debe operar directamente sobre datos de Producción fuera de los mecanismos previstos por la aplicación. +Las reglas técnicas que materializan estos límites se definen en los documentos de [arquitectura](arquitectura/), especialmente [visión general](arquitectura/vision-general.md), [backend](arquitectura/backend.md) y [datos y persistencia](arquitectura/datos-persistencia.md). + ## 5. Convenciones relevantes * Los perfiles se definen por puesto o función y se reutilizan entre las personas que desempeñen ese puesto. @@ -147,9 +149,14 @@ N/A Principales documentos que deben consultarse antes de tomar decisiones: -* `Respaldo_Arquitectura_Tecnica_Aplicacion_v1.1.md` — Arquitectura técnica y reglas comunes de la aplicación. -* Documento funcional de Oficina Comercial. -* Documento funcional de Oficina Técnica. +* [Visión general de arquitectura](arquitectura/vision-general.md). +* [Arquitectura backend](arquitectura/backend.md). +* [Arquitectura de datos y persistencia](arquitectura/datos-persistencia.md). +* [Arquitectura frontend](arquitectura/frontend.md). +* [Convenciones del proyecto](arquitectura/convenciones.md). +* [Estrategia de testing](arquitectura/testing.md). + +El respaldo técnico y los documentos funcionales de Oficina Comercial y Oficina Técnica citados anteriormente no están disponibles en este repositorio. Cuando se incorporen, deberán declararse aquí como referencias normativas con su ruta real. ## 8. Restricciones importantes @@ -191,4 +198,4 @@ Este nivel representa antigüedad y adaptación al entorno UECKO, no una calific Las actualizaciones deben generar un registro técnico independiente del histórico funcional, incluyendo fecha y hora, usuario, versión anterior, versión nueva, resultado y, cuando proceda, restauración posterior. -Mientras no exista integración automática con Factuges, los números de presupuesto y OF pueden incorporarse manualmente o mediante importación, manteniendo siempre Factuges como sistema de origen de dichos identificadores. \ No newline at end of file +Mientras no exista integración automática con Factuges, los números de presupuesto y OF pueden incorporarse manualmente o mediante importación, manteniendo siempre Factuges como sistema de origen de dichos identificadores. diff --git a/docs/README.md b/docs/README.md index 5714733..21a7b07 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,37 +1,37 @@ # Documentación del proyecto -Este directorio contiene la documentación técnica y operativa del proyecto. +Este directorio reúne la documentación técnica, funcional y operativa del proyecto. Cada tema debe tener una fuente de verdad principal; los demás documentos deben enlazarla sin duplicarla. + +## Dónde consultar cada regla + +- Arquitectura, contratos y convenciones técnicas: [`arquitectura/`](arquitectura/). +- Restricciones funcionales estables del producto: [`Ficha del proyecto UECKO.md`](Ficha%20del%20proyecto%20UECKO.md). +- Decisiones duraderas: [`adr/`](adr/). +- Procedimiento de trabajo y cierre: [`guias/`](guias/). +- Estado de iniciativas largas: [`trabajo/`](trabajo/). ## Estructura ```text docs/ -├── architecture/ +├── README.md +├── Ficha del proyecto UECKO.md ├── adr/ -├── work/ -├── guides/ -└── README.md +├── arquitectura/ +├── guias/ +└── trabajo/ ``` -### `architecture/` +### Documentos normativos -Documentación estable sobre la arquitectura y las reglas generales del sistema. +Las reglas de arquitectura, contratos, persistencia, frontend, convenciones y testing se definen respectivamente en los documentos de `arquitectura/`. La ficha define el contexto e invariantes funcionales transversales disponibles en el repositorio. -### `adr/` +### Guías y plantillas -Decisiones arquitectónicas o técnicas relevantes y duraderas. +Las guías describen procedimientos operativos; no sustituyen las normas de arquitectura. Las plantillas de `adr/` y `trabajo/` no establecen reglas por sí mismas. -### `work/` +## Mantenimiento -Estado de trabajos largos, migraciones, refactors o iniciativas en curso. - -### `guides/` - -Procedimientos operativos y guías para desarrolladores. - -## Principios - -- Evitar duplicar información. -- Mantener una única fuente de verdad por tema. -- Actualizar la documentación cuando cambien decisiones o contratos relevantes. -- No documentar detalles triviales que ya se expresen claramente en el código. +- Redactar la documentación en castellano y Markdown. +- Actualizar el documento normativo aplicable cuando cambie una decisión, contrato o invariante. +- No documentar detalles triviales ya expresados con claridad por el código. diff --git a/docs/arquitectura/backend.md b/docs/arquitectura/backend.md index ca3a398..cdca42c 100644 --- a/docs/arquitectura/backend.md +++ b/docs/arquitectura/backend.md @@ -2,63 +2,46 @@ ## Objetivo -Definir la estructura, responsabilidades y reglas principales del backend. +Definir responsabilidades, contratos y límites del backend. La dirección general de dependencias está en [visión general](vision-general.md). -## Organización +## Capas y composición -[Capas, módulos, bounded contexts o estructura principal.] +Domain no conoce Application ni Infrastructure. Application depende de Domain, contratos y Core; no conoce Express, Sequelize ni modelos ORM. Infrastructure depende de Application, Domain y Core. -## Flujo de entrada +Cada módulo construye explícitamente sus dependencias en su composition root. No se permite Service Locator, DI implícita o mágica ni importar Infrastructure interna de otro módulo. -[Request → aplicación → dominio → persistencia → respuesta.] +## Entrada, DTOs y contratos HTTP -## Responsabilidades +Zod es la fuente única de verdad de los contratos HTTP. Los tipos se infieren mediante `z.infer` y no se mantienen interfaces manuales equivalentes. Cada endpoint dispone de DTOs de request y response; los decimales exactos no viajan como `number`. -### Entrada / API +Los schemas expresan semánticamente UUID, fechas, timestamps, porcentajes, importes y cantidades. Deben distinguir campo omitido, `null`, cadena vacía y colección vacía. No se mezclan validación de transporte y lógica de negocio; `.default()` y `.transform()` solo se usan en DTOs de negocio cuando estén justificados. -[Responsabilidades.] +El flujo habitual es: -### Aplicación +```text +RequestDTO → UseCase({ dto, context }) → InputMapper → Value Objects / Props +``` -[Responsabilidades.] +`RequestMapper → Command` es opcional y solo procede ante una adaptación HTTP real, como combinar `body`, `params` y `query`. No se crea solo para renombrar campos que Application volverá a transformar. -### Dominio +## Application y Domain -[Responsabilidades.] +Los casos de uso orquestan, gestionan transacciones cuando corresponde, delegan en servicios de aplicación, devuelven `Result` y construyen respuestas mediante builders o mappers de salida. No contienen lógica HTTP, ORM, modelos Sequelize ni responsabilidades de controller, repositorio o Infrastructure; tampoco construyen agregados directamente desde DTOs HTTP. -### Infraestructura +Los servicios de aplicación son pequeños, explícitos y de responsabilidad concreta. Se evitan nombres genéricos como `Manager`, `GenericService`, `CommandService`, `BaseRepository` o `Helper` sin semántica. -[Responsabilidades.] +Se usan los patrones del proyecto: `Result` para operaciones que pueden fallar, `Maybe` para ausencia semántica y `Collection` cuando el dominio requiere comportamiento propio para un conjunto homogéneo. Los fallos de negocio esperables no se representan mediante excepciones, `null`, arrays ni tipos ad hoc cuando corresponda uno de esos patrones. -## Casos de uso +`create()` representa creación funcional: valida invariantes, puede fallar y devuelve `Result`. `rehydrate()` reconstruye persistencia válida: no valida creación, no genera eventos y no devuelve `Result`. Infrastructure usa `rehydrate()`; Application y Domain usan `create()` para instancias nuevas. `update()` no usa ninguna de las dos, y los Value Objects se reconstruyen con `create()`. -[Convenciones y responsabilidades.] +## Repositorios, mappers y respuestas -## Servicios +Cada repositorio gestiona un agregado o responsabilidad concreta, no se comparte entre módulos ni se expone como API pública. Los detalles de ORM permanecen en Infrastructure. Los mappers de persistencia e invariantes de almacenamiento se definen en [datos y persistencia](datos-persistencia.md). -[Convenciones y responsabilidades.] +Los snapshot builders materializan el DTO de salida exacto y se tipan con el tipo inferido del schema. Son deterministas, sin lógica de negocio ni acceso a repositorios o Infrastructure; pueden transformar `Maybe` en `null`, Value Objects en primitivas y enums internos en valores del contrato. No se crean interfaces `I*Snapshot` que dupliquen DTOs. -## Repositorios +## Errores, seguridad y API -[Reglas y límites.] +Los errores esperables son tipados y predecibles. Domain y Application se mapean a HTTP en Infrastructure sin exponer SQL, stack traces, detalles internos ni información sensible. No se ocultan fallos, no se convierten en éxito para continuar y el logging no sustituye su tratamiento. -## Persistencia - -[ORM, mappers, modelos, transacciones.] - -## Errores - -[Estrategia de errores y mapeo.] - -## Transacciones - -[Reglas de atomicidad y rollback.] - -## Seguridad - -[Autenticación, autorización, tenancy, validación.] - -## Referencias - -- [ADR relacionado] -- [Documento relacionado] +Toda entrada externa se valida. La autorización se verifica además de la autenticación; no se confía en permisos, compañía o identificadores enviados por el cliente sin contrastarlos con el contexto autenticado. Las consultas y mutaciones preservan aislamiento multiempresa. La idempotencia se aplica a operaciones repetibles según su semántica. diff --git a/docs/arquitectura/convenciones.md b/docs/arquitectura/convenciones.md index 8818050..8bf7631 100644 --- a/docs/arquitectura/convenciones.md +++ b/docs/arquitectura/convenciones.md @@ -1,55 +1,33 @@ # Convenciones del proyecto -## Objetivo +## Idioma y naming -Centralizar convenciones generales que afecten a todo el repositorio. +- Código e identificadores en inglés; comentarios, TSDoc y documentación en castellano. +- Ficheros y directorios en `kebab-case`. +- Clases, tipos e interfaces en `PascalCase`; variables, funciones y métodos en `camelCase`. +- `UPPER_SNAKE_CASE` solo para constantes globales reales. +- Mantener el prefijo `I` para interfaces cuando el área existente lo use. -## Idioma +Las convenciones existentes del área prevalecen sobre introducir una variación aislada. -- Código e identificadores: [definir] -- Comentarios: [definir] -- Documentación: [definir] +## TypeScript -## Naming +Preservar la seguridad de tipos. Usar `import type` para símbolos utilizados exclusivamente como tipos y mantenerlos en la cabecera; no usar imports runtime innecesarios ni referencias inline salvo en `.d.ts`, module augmentation, código generado o casos técnicamente justificados. -- Ficheros: [convención] -- Directorios: [convención] -- Clases / tipos: [convención] -- Variables / funciones: [convención] -- Constantes: [convención] +Evitar `any`; usar `unknown` cuando el tipo no se conozca. Las assertions y non-null assertions solo proceden con una garantía verificable que TypeScript no pueda inferir. Preferir tipos semánticos, unions o enums existentes y `switch` exhaustivos; no añadir `default` si ocultaría casos comprobables. No duplicar tipos derivados de schemas Zod, ni usar `Partial` cuando el contrato modele la opcionalidad explícitamente. Mantener inmutabilidad cuando no sea necesaria la mutación. -## Estructura de carpetas +Al cambiar DTOs, schemas, APIs, eventos, modelos persistidos o tipos compartidos, revisar todos sus productores y consumidores. -[Convenciones principales.] +## Comentarios y TSDoc -## Tipado +Los comentarios explican decisiones, riesgos, contratos, efectos laterales, invariantes o limitaciones no evidentes; no traducen el código. Documentar con TSDoc APIs públicas cuando aporte propósito, parámetros, retorno, errores, efectos o restricciones. Tras un refactor se actualizan o eliminan comentarios obsoletos. -[Reglas principales.] +## Asincronía y errores locales -## Validación +La regla `lint/complexity/noVoid` prohíbe usar `void` para descartar promesas. Toda promesa se espera, se devuelve o gestiona explícitamente con un manejador de error. No dejar promesas flotantes ni silenciar errores con `.catch(() => undefined)`; si un callback debe devolver `void`, encapsular la operación y gestionar su fallo. -[Reglas principales.] +## Dependencias y documentación -## Errores +No añadir ni actualizar dependencias salvo necesidad real: comprobar alternativa existente, justificarla, evaluar mantenimiento, compatibilidad e impacto de bundle o runtime. No modificar lockfiles ni versiones de PNPM incidentalmente, ni introducir supresiones de análisis sin justificación. -[Reglas principales.] - -## Async - -[Reglas principales.] - -## Imports - -[Reglas principales.] - -## Dependencias - -[Reglas para añadir o actualizar dependencias.] - -## Git - -[Convenciones relevantes.] - -## Documentación - -[Convenciones de actualización y SSOT.] +La documentación vive en `/docs`, usa Markdown y nombres en castellano. Debe ser clara, directa y no duplicar fuentes de verdad. Actualizar el documento autoritativo aplicable antes de crear otro equivalente. diff --git a/docs/arquitectura/datos-persistencia.md b/docs/arquitectura/datos-persistencia.md index 1257b20..8bb835d 100644 --- a/docs/arquitectura/datos-persistencia.md +++ b/docs/arquitectura/datos-persistencia.md @@ -2,45 +2,40 @@ ## Objetivo -Definir las reglas de persistencia, integridad y evolución de datos. +Definir las reglas de persistencia, integridad y evolución de datos. MariaDB y Sequelize son tecnologías objetivo documentadas; este documento no afirma su instalación efectiva. -## Base de datos +## Límites de persistencia -[Motor, versión y configuración relevante.] +Sequelize y sus modelos permanecen en Infrastructure; no forman contratos públicos ni se acceden desde Domain o Application. Cada repositorio gestiona un agregado o responsabilidad concreta y usa un mapper bidireccional por agregado: -## Modelado +```ts +toPersistence(); +toDomain(); +``` -[Convenciones para tablas, columnas, claves y relaciones.] +El mapper traduce representación de dominio y persistida, sin añadir lógica de negocio. Infrastructure reconstruye entidades mediante `rehydrate()`. -## Persistencia +## Transacciones e integridad -[ORM, repositorios y mappers.] +Las operaciones agregadas se ejecutan en transacción cuando deben ser atómicas. Al modificar persistencia o lógica transaccional se comprueban atomicidad, consistencia, rollback, concurrencia, aislamiento, integridad referencial y compatibilidad con datos existentes. Una escritura satisfactoria no garantiza por sí sola que haya terminado la operación funcional completa. -## Transacciones +Las invariantes críticas se refuerzan también en base de datos cuando resulte razonable. Las consultas y mutaciones preservan el aislamiento por `companyId` y `branchId` cuando corresponda y usan consultas parametrizadas o APIs seguras de Sequelize. -[Reglas de atomicidad.] +## Concurrencia e idempotencia -## Integridad +Las operaciones repetibles —comandos, peticiones reenviadas, reintentos, creaciones, integraciones, migraciones y actualizaciones— deben ser idempotentes cuando su semántica lo requiera. Una repetición accidental no produce efectos duplicados. -[Constraints, foreign keys, invariantes críticas.] +No usar `JSON.stringify` para detectar cambios de dominio; los Value Objects se comparan semánticamente mediante primitivas o métodos de igualdad apropiados. -## Concurrencia +## Migraciones e histórico -[Locks, versionado, idempotencia, etc.] +Los cambios estructurales se realizan mediante mecanismos controlados. Las migraciones preservan datos e histórico, no exigen reintroducción manual de información y son idempotentes cuando el procedimiento lo requiera. No eliminar columnas, tablas o datos legacy sin auditoría previa. -## Migraciones +Las actualizaciones no destruyen ni sobrescriben datos operativos o históricos. Antes de un cambio estructural debe existir copia de seguridad recuperable; cuando corresponda, la actualización realiza copia automática y permite restauración o rollback sin depender de conocimientos técnicos del usuario Máster. Las migraciones y actualizaciones quedan registradas. Los cambios relevantes se validan en Beta antes de Producción. -[Estrategia de migraciones.] - -## Índices y rendimiento - -[Convenciones y criterios.] - -## Datos legacy - -[Reglas para compatibilidad y eliminación.] +No se elimina físicamente información con histórico cuando proceda desactivarla, incluidos tareas y grupos funcionales. Deben preservarse usuarios, expedientes, OF, tareas, imputaciones, errores, históricos, actividad, configuraciones y trazabilidad. ## Referencias -- [ADR relacionado] -- [Documento relacionado] +- [Ficha del proyecto UECKO](../Ficha%20del%20proyecto%20UECKO.md) +- [Arquitectura backend](backend.md) diff --git a/docs/arquitectura/frontend.md b/docs/arquitectura/frontend.md index a53bc5f..2c321c4 100644 --- a/docs/arquitectura/frontend.md +++ b/docs/arquitectura/frontend.md @@ -2,51 +2,18 @@ ## Objetivo -Definir la estructura y las reglas generales del frontend. +Definir las reglas de frontend. React, TanStack Query, TanStack Table, React Hook Form, Zod, shadcn/ui y Tailwind son tecnologías objetivo documentadas; este documento no afirma su instalación efectiva. -## Organización +## Estado y datos remotos -[Aplicaciones, módulos, features, pages, components, hooks, etc.] +Las operaciones de servidor permanecen en TanStack Query. No duplicar estado remoto en estado local sin necesidad; las query keys siguen la convención existente y, tras mutaciones, la caché se invalida o actualiza explícitamente. No introducir efectos para derivar durante render estado que pueda calcularse directamente. -## Estado +## Formularios y componentes -### Estado remoto +Los formularios usan React Hook Form y Zod conforme a los patrones existentes. Los componentes evitan responsabilidad monolítica: se extraen responsabilidades cuando exista una frontera semántica clara, no para ocultar JSX trivial. Usar shadcn/ui y Tailwind según los patrones del área. -[Herramienta y reglas.] +## UI, accesibilidad e internacionalización -### Estado local +La interfaz contempla estados `disabled`, `loading`, `empty` y `error`, conserva acciones no disponibles deshabilitadas cuando la UX requiera mostrarlas y preserva comportamiento responsive y accesibilidad. -[Reglas.] - -## Formularios - -[Convenciones de formularios y validación.] - -## Componentes - -[Reutilización, sistema de diseño y composición.] - -## Navegación - -[Routing y layouts.] - -## UI / UX - -[Patrones visuales, loading, empty, error, disabled, responsive.] - -## Internacionalización - -[Convenciones i18n.] - -## Accesibilidad - -[Reglas mínimas.] - -## Errores - -[Manejo de errores de UI y API.] - -## Referencias - -- [ADR relacionado] -- [Documento relacionado] +Los textos visibles se mantienen en `es` y `en` cuando el área use i18n; no se insertan directamente en ese caso. Las columnas monetarias usan `tabular-nums` cuando corresponda. diff --git a/docs/arquitectura/testing.md b/docs/arquitectura/testing.md index de474e3..5c9233c 100644 --- a/docs/arquitectura/testing.md +++ b/docs/arquitectura/testing.md @@ -4,52 +4,26 @@ Definir qué se prueba, dónde y con qué nivel de profundidad. -## Niveles - -### Unitarios - -[Qué deben cubrir.] - -### Integración - -[Qué deben cubrir.] - -### E2E - -[Qué deben cubrir.] - ## Criterios -- Validar comportamiento observable. -- Evitar depender de detalles internos irrelevantes. -- Añadir regresión para bugs cuando sea viable. -- Mantener tests deterministas. +Los tests priorizan comportamiento observable, contratos, invariantes y casos límite sobre detalles accidentales de implementación. Cuando cambie comportamiento observable se añaden o actualizan pruebas; los bugs incorporan una regresión cuando sea viable. -## Fixtures y datos de prueba +Cubrir según corresponda casos válidos e inválidos, límites, errores, idempotencia, autorización y concurrencia. Los tests deben ser deterministas, sin esperas arbitrarias y no se desactivan para obtener una suite verde. -[Convenciones.] +## Niveles -## Mocks - -[Cuándo y cómo usarlos.] +Las pruebas unitarias cubren comportamiento de unidades y reglas aisladas. Las de integración cubren la colaboración entre componentes y persistencia cuando corresponda. Las E2E cubren flujos completos relevantes. La selección es proporcional al riesgo, alcance y capas afectadas. ## Validación por cambio +La evidencia se obtiene primero mediante la comprobación más acotada suficiente: + ```text -tests específicos -→ tests del módulo -→ typecheck -→ lint -→ integración -→ E2E -→ validación global +test específico → tests del módulo o paquete → typecheck del módulo → lint del módulo → integración → E2E → validación global ``` +La validación global procede ante paquetes compartidos, contratos públicos, configuración transversal, varios módulos o infraestructura común. El procedimiento de cierre y el informe de resultados se definen en la [guía de cierre](../guias/cierre-de-tareas.md). + ## Fallos preexistentes -[Cómo distinguirlos y documentarlos.] - -## Referencias - -- [ADR relacionado] -- [Documento relacionado] +Distinguir fallos causados por el cambio, fallos preexistentes, fallos ajenos al área y validaciones no ejecutadas. No atribuir un fallo a una categoría sin evidencia ni ocultar errores de compilación, typecheck, lint, tests o build. diff --git a/docs/arquitectura/vision-general.md b/docs/arquitectura/vision-general.md index 854eeb7..c8d06ba 100644 --- a/docs/arquitectura/vision-general.md +++ b/docs/arquitectura/vision-general.md @@ -2,38 +2,40 @@ ## Objetivo -Describir la arquitectura general del sistema y sus principales límites. +Definir los límites arquitectónicos transversales del sistema, sin detallar la implementación interna de cada capa. -## Sistema +## Sistema y módulos -[Descripción breve del producto y su propósito.] +La aplicación gestiona tiempos, tareas, actividad, incidencias y procesos de Oficina Comercial y Oficina Técnica. Ambos son módulos funcionales diferenciados y cada uno es propietario de los datos que genera. -## Principales módulos o áreas +Los módulos pueden consultar información ajena cuando sea necesario, pero solo colaboran mediante servicios públicos explícitos. No se comparten repositorios, modelos ORM, mappers internos, servicios internos de escritura ni detalles de Infrastructure. Un módulo no modifica datos propiedad de otro sin permiso expreso. -- [Módulo 1] -- [Módulo 2] -- [Módulo 3] +## Estilo y límites -## Relaciones principales +El backend sigue DDD pragmático, Clean Architecture y arquitectura hexagonal. Se priorizan claridad y explicitud frente a abstracción prematura; esos principios no justifican crear capas, adaptadores, factories, genéricos, eventos o contenedores de DI sin una necesidad actual. -[Describir dependencias y comunicación entre módulos.] +La dirección general de dependencias es: -## Límites arquitectónicos +```text +Domain + no conoce Application ni Infrastructure -- [Regla 1] -- [Regla 2] -- [Regla 3] +Application + depende de Domain, contratos y Core + no conoce Express, Sequelize ni modelos ORM -## Flujos principales +Infrastructure + depende de Application, Domain y Core +``` -[Describir los flujos más importantes a alto nivel.] +Cada módulo mantiene su propio composition root, que construye explícitamente sus dependencias. No se permite Service Locator ni DI implícita o mágica. Antes de cambiar una frontera arquitectónica se deben identificar productores, consumidores y efectos derivados. -## Dependencias externas +## Límites transversales -- [Servicio / API / infraestructura] -- [Servicio / API / infraestructura] +La aplicación y los datos permanecen separados. Las actualizaciones y migraciones no pueden destruir, sobrescribir ni exigir reintroducir información histórica. Las reglas técnicas que materializan estos límites se definen en [datos y persistencia](datos-persistencia.md); los contratos de cada capa, en [backend](backend.md). ## Referencias -- [ADR relacionado] -- [Documento relacionado] +- [Ficha del proyecto UECKO](../Ficha%20del%20proyecto%20UECKO.md) +- [Arquitectura backend](backend.md) +- [Arquitectura de datos y persistencia](datos-persistencia.md)