# 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](docs/arquitectura/capas-del-servidor.md) - [Composición de módulos](docs/arquitectura/composicion-de-modulos.md) - [Flujo HTTP](docs/arquitectura/flujo-http.md) - [Contratos HTTP](docs/arquitectura/contratos-http.md) - [Pruebas](docs/arquitectura/pruebas.md) - [Modelo DDD e identificadores](docs/arquitectura/modelo-ddd-e-identificadores.md) ## 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. 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.