- Created project overview document for UECKO application. - Added README file for project documentation structure. - Introduced template for architectural decision records (ADR). - Defined backend architecture guidelines. - Established conventions for project-wide consistency. - Documented data persistence architecture. - Outlined frontend architecture principles. - Developed testing strategy documentation. - Provided a general architecture overview. - Created guides for task closure and ChatGPT-Codex workflow. - Organized chat management guidelines for development projects. - Added template for current work status reporting.
1389 lines
32 KiB
Markdown
1389 lines
32 KiB
Markdown
# AGENTS.md
|
|
|
|
## Ámbito
|
|
|
|
Estas instrucciones se aplican a todo el monorepo, salvo que exista un archivo `AGENTS.md` más específico en un subdirectorio.
|
|
|
|
Los archivos `AGENTS.md` descendientes pueden añadir, concretar o restringir reglas para su ámbito.
|
|
|
|
No deben duplicar innecesariamente las reglas de este documento.
|
|
|
|
---
|
|
|
|
## 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:
|
|
|
|
```text
|
|
/home/david/dev/uecko-control-tiempos
|
|
```
|
|
|
|
Antes de una tarea de código relevante, comprobar como mínimo:
|
|
|
|
```bash
|
|
pwd
|
|
git rev-parse --show-toplevel
|
|
git status --short
|
|
node --version
|
|
pnpm --version
|
|
```
|
|
|
|
Se espera:
|
|
|
|
```text
|
|
Repositorio: /home/david/dev/uecko-control-tiempos
|
|
Sistema: Linux bajo WSL2
|
|
Node.js: 24.x
|
|
PNPM: 11.25.0
|
|
```
|
|
|
|
Si el entorno no coincide con el definido por el proyecto, identificar la causa antes de modificar código.
|
|
|
|
No cambiar versiones de runtime, gestores de paquetes o configuración del entorno como efecto colateral de una tarea no relacionada.
|
|
|
|
La versión de PNPM declarada mediante `packageManager` en el `package.json` raíz es vinculante.
|
|
|
|
No modificar `packageManager` como consecuencia incidental de otra tarea.
|
|
|
|
---
|
|
|
|
## 3. Secretos y configuración local
|
|
|
|
Los archivos locales de configuración que puedan contener secretos no deben:
|
|
|
|
* mostrarse innecesariamente;
|
|
* copiarse completos a respuestas;
|
|
* incluirse en logs;
|
|
* versionarse accidentalmente.
|
|
|
|
Nunca exponer:
|
|
|
|
* contraseñas;
|
|
* tokens;
|
|
* API keys;
|
|
* claves privadas;
|
|
* secretos;
|
|
* cadenas de conexión completas;
|
|
* credenciales.
|
|
|
|
No modificar archivos de configuración local salvo que la tarea lo requiera expresamente.
|
|
|
|
---
|
|
|
|
## 4. Auditar antes de implementar
|
|
|
|
Para cambios no triviales, inspeccionar la implementación existente antes de modificarla.
|
|
|
|
Determinar, cuando corresponda:
|
|
|
|
* 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.
|
|
|
|
Para bugs, localizar la causa raíz antes de aplicar una corrección.
|
|
|
|
No aplicar fixes especulativos únicamente porque hagan desaparecer un error.
|
|
|
|
---
|
|
|
|
## 5. Buscar patrones existentes primero
|
|
|
|
Antes de crear una nueva:
|
|
|
|
* abstracción;
|
|
* clase;
|
|
* servicio;
|
|
* hook;
|
|
* componente;
|
|
* mapper;
|
|
* repositorio;
|
|
* utilidad;
|
|
* schema;
|
|
* tipo;
|
|
* tipo de error;
|
|
* capa arquitectónica;
|
|
* mecanismo de validación;
|
|
|
|
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<T>` 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<typeof Schema>`;
|
|
* 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 <workspace> typecheck
|
|
pnpm --filter <workspace> lint
|
|
pnpm --filter <workspace> 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:
|
|
|
|
```bash
|
|
git status --short
|
|
git diff
|
|
```
|
|
|
|
Revisar el diff para detectar:
|
|
|
|
* modificaciones no relacionadas;
|
|
* cambios accidentales de formato;
|
|
* código temporal;
|
|
* logs de depuración;
|
|
* archivos generados inesperados;
|
|
* secretos;
|
|
* cambios en lockfiles no justificados.
|
|
|
|
No reescribir historial ajeno a la tarea.
|
|
|
|
No realizar:
|
|
|
|
* commits;
|
|
* pushes;
|
|
* resets destructivos;
|
|
* modificaciones de historial;
|
|
|
|
salvo petición expresa o flujo explícito del proyecto.
|
|
|
|
---
|
|
|
|
## 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.
|