Estructura NestJS GraphQL
Dónde pertenece cada archivo en una aplicación NestJS GraphQL (code-first) y cómo funciona cada archivo. Esta habilidad es una guía de colocación y anatomía: responde "¿en qué carpeta va este archivo?", "¿de qué es responsable este archivo?" y "¿cómo se conectan los módulos para resolver campos y relaciones?". Cubre el mapa de estructura base más reglas por archivo para módulos, servicios, resolutores (query, mutation, subscription y field), inputs y args, paginación, entidades (mejores prácticas de esquema Mongoose para tipos compartidos), inyección de modelos solo en repositorios, modelos/mappers, repositorios, discriminadores de Mongoose, campos derivados, proveedores, loaders, eventos, trabajos en segundo plano, autenticación, excepciones, escalares personalizados, configuración, bloques comunes, configuración de infraestructura y las convenciones de nomenclatura, pruebas y lint.
Está deliberadamente separada de la habilidad nestjs-best-practices. Esa habilidad cubre el comportamiento del framework (profundidad de inyección de dependencias, seguridad, rendimiento, manejo de errores, microservicios, DevOps); esta cubre la estructura y la composición de módulos. Donde se superponen (módulos de funcionalidad, dependencias circulares), esta habilidad lo analiza desde una perspectiva de colocación y hace referencia cruzada a la otra habilidad para profundidad de comportamiento.
Esta habilidad cubre tanto las reglas de estructura (dónde vive un archivo) como las reglas de resolución de módulos (cómo se conectan los módulos en tiempo de ejecución, por ejemplo, resolución de dependencias circulares). Las reglas de resolución de módulos se encuentran en las Secciones 2 y 3.
Cuándo aplicar
Consulta estas pautas cuando:
- Decidas dónde pertenece un nuevo archivo en una base de código NestJS GraphQL
- Estés diseñando o revisando una estructura de directorios basada en funcionalidades (feature-first)
- Estés creando un nuevo módulo de funcionalidad y sus archivos
- Decidas cómo modelar documentos polimórficos (discriminadores de Mongoose) y publiques su tipo GraphQL automáticamente
- Decidas dónde se puede inyectar un modelo Mongoose — y mantengas el acceso a la base de datos detrás de un repositorio
- Decidas si un valor pertenece a la base de datos o debe derivarse al leerlo
- Estés determinando cómo un módulo resuelve un campo o relación que vive en otro módulo
- Estés resolviendo problemas de conexión entre módulos (dependencias circulares, exportaciones faltantes)
Categorías de reglas por prioridad
| Prioridad | Categoría | Impacto | Prefijo |
|---|---|---|---|
| 1 | Estructura de la Aplicación | CRÍTICO | struct- |
| 2 | Módulos y Bootstrap | CRÍTICO | module- |
| 3 | Relaciones y entre Módulos | CRÍTICO | relations- |
| 4 | Servicios | ALTO | service- |
| 5 | Resolutores GraphQL | ALTO | resolver- |
| 6 | Tipos e Inputs GraphQL | ALTO | type- |
| 7 | Acceso a Datos | MEDIO-ALTO | data- |
| 8 | Configuración, Comunes e Infra | MEDIO | infra- |
| 9 | Convenciones y Pruebas | MEDIO | conventions- |
Referencia Rápida
1. Estructura de la Aplicación (CRÍTICO)
struct-auth-feature- Mantener la Autenticación en Su Propio Módulo de Funcionalidadstruct-canonical-layout- Estructura Canónica de la Aplicaciónstruct-feature-decomposition- Dividir una Funcionalidad en Sub-Módulos Cuando Crecestruct-file-placement-table- Tabla de Colocación de Archivosstruct-module-kinds- Distinguir Funcionalidades de Dominio de Módulos a Nivel de Aplicaciónstruct-schema-artifact- Ubicar y Definir la Política del Artefacto de Esquema Generado
2. Módulos y Bootstrap (CRÍTICO)
module-bootstrap- Mantener main.ts y app.module.ts Delgadosmodule-export-policy- Exportar Solo la API Pública de la Funcionalidad (Sus Servicios)module-feature-module- El Archivo del Módulo de Funcionalidad
3. Relaciones y entre Módulos (CRÍTICO)
relations-avoid-circular- Resolver Dependencias Circulares de Módulosrelations-dataloader- Agrupar Relaciones con un DataLoader por Solicitudrelations-events- Desacoplar Módulos con Eventosrelations-field-resolvers- Resolver Relaciones con @ResolveFieldrelations-owning-module- Colocar un Campo de Relación en el Módulo que Posee Sus Datos
4. Servicios (ALTO)
service-background-jobs- Mantener Procesadores de Cola y Trabajos Programados con la Funcionalidadservice-external-providers- Mantener Clientes de Terceros en providers/service-interfaces-tokens- Declarar Contratos de Servicio y Tokens de Inyección en interfaces/service-single-responsibility- Múltiples Servicios Enfocados por Móduloservice-small-focused-methods- Mantener los Métodos del Servicio Pequeños y Enfocados
5. Resolutores GraphQL (ALTO)
resolver-computed-fields- Declarar Campos en el Tipo; Resolver los Calculados en el Resolutorresolver-organization- Dividir Resolutores por Rol en resolvers/resolver-per-type- Un Archivo de Resolutor por Tipo que Tenga Resolutores de Camporesolver-subscriptions- Colocar Resolutores de Suscripción en resolvers/ con PubSub en infra/
6. Tipos e Inputs GraphQL (ALTO)
type-args- Definir Clases @Args en dto/type-inputs- Definir Inputs de GraphQL en dto/type-pagination- Paginar Consultas de Lista con un Tipo de Página Compartidotype-polymorphic-discriminators- Publicar Documentos Discriminados como una Interfaz o Unióntype-unions-interfaces- Colocar Tipos de Unión e Interfaz con los Tipos del Módulo
7. Acceso a Datos (MEDIO-ALTO)
data-derived-fields- Calcular Campos Derivados; No Almacenarlosdata-discriminators- Modelar Subtipos Polimórficos con Discriminadoresdata-entity-mongodb- Colocar Entidades MongoDB en entities/data-model-injection- Inyectar un Modelo Solo en el Repositoriodata-models-mappers- Dividir models/ y mappers/ Cuando la API Difiera del Almacenamientodata-mongoose-schema- Mejores Prácticas de Esquema Mongoose para Tipos Compartidosdata-repository- Mantener el Acceso a Datos en repositories/
8. Configuración, Comunes e Infra (MEDIO)
infra-common-types- Colocar Tipos Compartidos en common/types/infra-common- Colocar Bloques Comunes en common/infra-config- Colocar la Configuración Tipificada en config/infra-custom-scalars- Implementar Escalares Personalizados en common/scalars/infra-database- Colocar la Configuración de la Base de Datos y Migraciones en infra/database/infra-directives- Colocar Directivas de Esquema en common/directives/infra-exceptions- Colocar Excepciones en exceptions/infra-graphql- Colocar la Configuración de GraphQL en infra/graphql/infra-seeds- Colocar Scripts de Semilla en infra/database/seeds/infra-shared-module- Usar un SharedModule para Servicios Transversales
9. Convenciones y Pruebas (MEDIO)
conventions-barrels-aliases- Usar Barriles y Alias de Ruta con Intenciónconventions-cli-generator- Usar el Generador CLI de Nest, Luego Ajustarconventions-constants-enums- Mantener Constantes y Enums Fuera de los Archivos de Claseconventions-module-boundaries- Aplicar Límites de Módulos con Lintconventions-naming- Convenciones de Nomenclatura de Archivos y Clasesconventions-test-fixtures- Colocar Fixtures, Fábricas y Ayudantes de Prueba en test/conventions-testing- Colocación de Archivos de Prueba
Cómo usar
Comienza con la regla de estructura base, luego lee la regla para el tipo de archivo específico en el que estés trabajando. Los archivos de reglas viven bajo rules/:
rules/struct-canonical-layout.md
rules/_sections.md
Cada archivo de regla contiene:
- Propósito y colocación (dónde vive el archivo y cómo se nombra)
- Responsabilidades y anti-responsabilidades
- Un ejemplo incorrecto con una explicación
- Un ejemplo correcto con una explicación
Documento Compilado Completo
Para la guía completa con todas las reglas expandidas en un solo documento, consulta AGENTS.md.