7.5 KiB
Instrucciones de Metis Desk
Alcance y entorno
Proyecto independiente de factuges-erp. Se conserva su estilo, no sus funcionalidades ni dependencias locales.
El repositorio vive en /home/david/dev/metis-desk, en WSL2 Ubuntu-24.04.
Ejecutar las herramientas del proyecto dentro de WSL con bash, nunca desde Windows, rutas UNC o /mnt/c.
Antes de modificar código: comprobar pwd, git status --short, node --version y pnpm --version.
Usar Node.js 24.x y la versión de PNPM fijada en package.json.
No imprimir, copiar ni versionar .env locales o secretos.
Convenciones
- 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; constantes globales en UPPER_SNAKE_CASE.
- Interfaces con prefijo I cuando el área ya siga esa convención.
- Documentación en /docs, con nombres de ficheros en castellano.
- Comentarios que expliquen decisiones, riesgos o contratos, nunca que repitan el código.
- Mantener es y en para textos de interfaz; no insertar literales en áreas con i18n.
- En las sentencia condicionales (if) Utiliza siempre llaves cuando el bloque contiene una sola intrucción.
Disciplina
Aplicar SOLID, Clean Code, DRY, KISS, YAGNI, SSOT, fail fast y programación defensiva. Priorizar claridad y explicitud frente a abstracción prematura. Cambios incrementales y acotados. No renombrar, reformatear o mover código ajeno a la tarea. No crear capas, factories, genéricos, eventos, contenedores DI ni repositorios base sin necesidad real. Justificar cada nueva dependencia. Preferir APIs nativas cuando basten. No añadir supresiones de TypeScript o Biome sin justificación. No eliminar legado sin buscar y clasificar sus referencias en todo el monorepo.
TypeScript y asincronía
- Importar tipos explícitamente con import type en la cabecera.
- No usar import("...").Tipo en código ordinario.
- Evitar any, assertions y non-null assertions salvo garantías verificables.
- Inferir DTOs de schemas Zod; no duplicarlos mediante interfaces.
- Usar unions para conjuntos cerrados y mantener switches exhaustivos.
- No usar Partial si el contrato ya representa la opcionalidad.
- No usar el operador void para descartar promesas.
- Toda promesa se espera, se devuelve o gestiona su error expresamente.
- No dejar promesas flotantes ni capturas que oculten fallos.
- Comprobar el contrato del callback antes de convertirlo a async.
- Usar Result para fallos de negocio y Maybe para ausencia semántica cuando se implementen esas operaciones.
- Collection solo cuando el conjunto necesite comportamiento de dominio; no introducir estos patrones sin consumidores.
Arquitectura y contratos
Las fuentes normativas se consultan, no se duplican:
- Capas del servidor
- Composición de módulos
- Flujo HTTP
- Contratos HTTP
- Pruebas
- Modelo DDD e identificadores
Seguridad y persistencia
- Menor privilegio y validación de toda entrada externa.
- Autenticación y autorización antes de acceder a datos de clientes.
- El cliente atendido no es el tenant de la empresa que presta soporte.
- Verificar siempre permisos y pertenencia; no confiar en companyId enviado por el navegador.
- No exponer SQL, stacks, datos sensibles o credenciales en respuestas ni logs.
- Registrar identificadores de petición y resultados suficientes para diagnosticar fallos.
- MariaDB y Sequelize v6 para persistencia; ORM exclusivamente en Infrastructure.
- Consultas parametrizadas, transacciones para cambios atómicos y restricciones en base de datos.
- Migraciones explícitas; no usar sync({ alter: true }) como sustituto.
- Toda entidad de negocio, incluidas las entidades internas de un agregado, tiene identidad UniqueID (UUID v7 para nuevas entidades), siguiendo factuges-erp.
- Declarar Value Objects, DomainEntity y AggregateRoot según docs/arquitectura/modelo-ddd-e-identificadores.md.
- Mantener semántica de create, rehydrate y update según la arquitectura.
- Comparar cambios de dominio semánticamente, no mediante JSON.stringify.
- Añadir idempotencia donde una repetición pueda producir efectos duplicados.
Frontend
React, TanStack Query, Tailwind y shadcn/ui (Base UI, estilo Vega). Los componentes compartidos viven en @repo/shadcn-ui. Incorporar TanStack Table y React Hook Form cuando haya consumidores. Estado remoto en TanStack Query; claves centralizadas e invalidación explícita después de mutaciones. No duplicar estado remoto ni usar efectos para derivar valores calculables durante render. Mantener accesibilidad y estados de carga, error, vacío y acciones deshabilitadas. Separar componentes por responsabilidades reales, sin fragmentar JSX trivial. Antes de crear o modificar pantallas, reconocer activamente patrones visuales y de interacción comunes entre ellas, así como componentes repetidos dentro de una misma pantalla. Aplicar soluciones coherentes a todos los casos equivalentes, conservando las necesidades propias de cada entidad. Reutilizar y extender la biblioteca visual existente antes de duplicar estructura, estilos o comportamiento. Extraer componentes compartidos cuando haya repetición real: cabeceras, listados, formularios modales, grupos de campos, selectores con alta, estados y ayuda contextual. Construir progresivamente una biblioteca visual básica con contratos claros, accesibilidad, textos traducibles y composición sencilla. Mantener los componentes genéricos independientes de entidades, DTO, consultas y endpoints de Metis Desk; el módulo consumidor aporta datos, textos y acciones. Documentar patrones y componentes en docs/componentes-de-interfaz.md y en el estándar correspondiente. Preparar esa independencia para poder agrupar o extraer posteriormente componentes en un paquete reutilizable en otras aplicaciones. Aprovechar @repo/shadcn-ui y crear abstracciones conforme aparezcan consumidores reales. Las pantallas de listado de entidades siguen el patrón de listados, reutilizando los componentes comunes de @repo/shadcn-ui. Los listados no muestran formularios de alta ni edición junto a los datos. El alta se inicia con un botón en la cabecera, a la derecha; formularios en modal shadcn/ui como norma general, con anchura y desplazamiento adaptados a su contenido. La edición se abre mediante una acción explícita, siguiendo el mismo criterio. Mantener foco, cierre por teclado, cancelación y errores dentro del formulario. Incluir ayuda contextual con finalidad, ámbito y ejemplos, sin rellenar los campos automáticamente. En formularios, colocar la ayuda en la parte inferior, inmediatamente antes del pie del modal con Guardar y Cancelar.
Validación y entrega
Ejecutar pnpm typecheck, pnpm lint, pnpm test, pnpm check y pnpm build en cambios transversales. Preferir comprobaciones dirigidas al paquete cuando sean suficientes. Añadir pruebas de comportamiento observable: válidos, inválidos, límites e idempotencia cuando corresponda. Tests deterministas, sin esperas arbitrarias ni desactivaciones. Informar cambios, archivos principales, comandos ejecutados, resultados y pendientes reales. No afirmar validaciones no ejecutadas ni ocultar fallos conocidos.
Precedencia: instrucciones actuales del usuario, AGENTS.md más cercano, este archivo y convenciones existentes.