NestJS GraphQL-Struktur
Wo jede Datei in einer NestJS GraphQL (Code-First) Anwendung hingehört und wie jede Datei funktioniert. Dieses Skill ist ein Platzierungs- und Anatomie-Leitfaden: Es beantwortet „In welchen Ordner gehört diese Datei?“, „Wofür ist diese Datei verantwortlich?“ und „Wie verbinden sich Module, um Felder und Beziehungen aufzulösen?“. Es umfasst die grundlegende Strukturlandkarte sowie dateispezifische Regeln für Module, Services, Resolver (Query, Mutation, Subscription und Field), Inputs und Args, Paginierung, Entitäten (Mongoose-Schema-Best Practices für gemeinsame Typen), Repository-only-Modell-Injektion, Models/Mapper, Repositories, Mongoose-Diskriminatoren, abgeleitete Felder, Provider, Loader, Events, Hintergrundjobs, Authentifizierung, Exceptions, benutzerdefinierte Skalare, Konfiguration, gemeinsame Bausteine, Infrastruktur-Setup sowie die Namens-, Test- und Lint-Konventionen.
Es ist bewusst vom Skill nestjs-best-practices getrennt. Dieser Skill behandelt Framework-Verhalten (Dependency-Injection-Tiefe, Sicherheit, Leistung, Fehlerbehandlung, Microservices, DevOps); dieser hier behandelt Struktur und Modulkomposition. Wo sie sich überschneiden (Feature-Module, zirkuläre Abhängigkeiten), betrachtet dieses Skill sie durch eine Platzierungslinse und verweist für die Verhaltenstiefe auf den anderen Skill.
Dieses Skill behandelt sowohl Strukturregeln (wo eine Datei lebt) als auch Modulauflösungsregeln (wie Module zur Laufzeit verbunden werden – z. B. Auflösung zirkulärer Abhängigkeiten). Modulauflösungsregeln befinden sich in den Abschnitten 2 und 3.
Wann anwenden
Beziehen Sie sich auf diese Richtlinien, wenn:
- Entscheiden, wo eine neue Datei in einer NestJS GraphQL-Codebasis hingehört
- Entwerfen oder Überprüfen eines Feature-First-Verzeichnislayouts
- Gerüsten eines neuen Feature-Moduls und seiner Dateien
- Entscheiden, wie polymorphe Dokumente (Mongoose-Diskriminatoren) modelliert und ihr GraphQL-Typ automatisch veröffentlicht werden
- Entscheiden, wo ein Mongoose-Modell injiziert werden darf – und den Datenbankzugriff hinter einem Repository halten
- Entscheiden, ob ein Wert in der Datenbank gespeichert oder beim Lesen abgeleitet werden soll
- Herausarbeiten, wie ein Modul ein Feld oder eine Beziehung auflöst, die in einem anderen Modul lebt
- Lösen von Verbindungsproblemen zwischen Modulen (zirkuläre Abhängigkeiten, fehlende Exporte)
Regelkategorien nach Priorität
| Priorität | Kategorie | Auswirkung | Präfix |
|---|---|---|---|
| 1 | Anwendungsstruktur | KRITISCH | struct- |
| 2 | Module & Bootstrap | KRITISCH | module- |
| 3 | Beziehungen & Kreuzmodul | KRITISCH | relations- |
| 4 | Services | HOCH | service- |
| 5 | GraphQL-Resolver | HOCH | resolver- |
| 6 | GraphQL-Typen & Inputs | HOCH | type- |
| 7 | Datenzugriff | MITTEL-HOCH | data- |
| 8 | Konfiguration, Common & Infra | MITTEL | infra- |
| 9 | Konventionen & Tests | MITTEL | conventions- |
Kurzreferenz
1. Anwendungsstruktur (KRITISCH)
struct-auth-feature- Authentifizierung in einem eigenen Feature-Modul haltenstruct-canonical-layout- Kanonische Anwendungsstrukturstruct-feature-decomposition- Ein Feature in Sub-Module aufteilen, wenn es wächststruct-file-placement-table- Dateiplatzierungstabellestruct-module-kinds- Domain-Features von App-Level-Modulen unterscheidenstruct-schema-artifact- Das generierte Schema-Artefakt lokalisieren und Richtlinien festlegen
2. Module & Bootstrap (KRITISCH)
module-bootstrap- main.ts und app.module.ts schlank haltenmodule-export-policy- Nur die öffentliche API des Features exportieren (seine Services)module-feature-module- Die Feature-Modul-Datei
3. Beziehungen & Kreuzmodul (KRITISCH)
relations-avoid-circular- Zirkuläre Modulabhängigkeiten auflösenrelations-dataloader- Beziehungen mit einem Pro-Request-DataLoader bündelnrelations-events- Module mit Events entkoppelnrelations-field-resolvers- Beziehungen mit @ResolveField auflösenrelations-owning-module- Ein Beziehungsfeld in das Modul legen, das seine Daten besitzt
4. Services (HOCH)
service-background-jobs- Queue-Prozessoren und geplante Jobs beim Feature behaltenservice-external-providers- Drittanbieter-Clients in providers/ behaltenservice-interfaces-tokens- Service-Verträge und Injektions-Token in interfaces/ deklarierenservice-single-responsibility- Mehrere fokussierte Services pro Modulservice-small-focused-methods- Service-Methoden klein und fokussiert halten
5. GraphQL-Resolver (HOCH)
resolver-computed-fields- Felder auf dem Typ deklarieren; berechnete im Resolver auflösenresolver-organization- Resolver nach Rolle in resolvers/ aufteilenresolver-per-type- Eine Resolver-Datei pro Typ, der Feld-Resolver hatresolver-subscriptions- Subscription-Resolver in resolvers/ mit PubSub in infra/ ablegen
6. GraphQL-Typen & Inputs (HOCH)
type-args- @Args-Klassen in dto/ definierentype-inputs- GraphQL-Inputs in dto/ definierentype-pagination- Listenabfragen mit einem gemeinsamen Page-Typ paginierentype-polymorphic-discriminators- Diskriminierte Dokumente als Interface oder Union veröffentlichentype-unions-interfaces- Union- und Interface-Typen bei den Typen des Moduls platzieren
7. Datenzugriff (MITTEL-HOCH)
data-derived-fields- Abgeleitete Felder berechnen; nicht speicherndata-discriminators- Polymorphe Subtypen mit Diskriminatoren modellierendata-entity-mongodb- MongoDB-Entitäten in entities/ ablegendata-model-injection- Ein Modell nur im Repository injizierendata-models-mappers- models/ und mappers/ trennen, wenn die API von der Speicherung abweichtdata-mongoose-schema- Mongoose-Schema-Best Practices für gemeinsame Typendata-repository- Datenzugriff in repositories/ halten
8. Konfiguration, Common & Infra (MITTEL)
infra-common-types- Gemeinsame Typen in common/types/ ablegeninfra-common- Gemeinsame Bausteine in common/ ablegeninfra-config- Typisierte Konfiguration in config/ ablegeninfra-custom-scalars- Benutzerdefinierte Skalare in common/scalars/ implementiereninfra-database- Datenbank-Setup und Migrationen in infra/database/ ablegeninfra-directives- Schema-Direktiven in common/directives/ ablegeninfra-exceptions- Exceptions in exceptions/ ablegeninfra-graphql- GraphQL-Setup in infra/graphql/ ablegeninfra-seeds- Seed-Skripte in infra/database/seeds/ ablegeninfra-shared-module- Ein SharedModule für querschnittliche Services verwenden
9. Konventionen & Tests (MITTEL)
conventions-barrels-aliases- Barrels und Pfad-Aliase bewusst verwendenconventions-cli-generator- Den Nest-CLI-Generator verwenden, dann anpassenconventions-constants-enums- Konstanten und Enums außerhalb von Klassendateien haltenconventions-module-boundaries- Modulgrenzen mit Lint erzwingenconventions-naming- Datei- und Klassenbenennungskonventionenconventions-test-fixtures- Test-Fixtures, Factories und Helfer in test/ ablegenconventions-testing- Testdateiplatzierung
Verwendung
Beginnen Sie mit der Basisstrukturregel und lesen Sie dann die Regel für die spezifische Dateiart, an der Sie arbeiten.
Regeldateien befinden sich unter rules/:
rules/struct-canonical-layout.md
rules/_sections.md
Jede Regeldatei enthält:
- Zweck und Platzierung (wo die Datei lebt und wie sie benannt wird)
- Verantwortlichkeiten und Anti-Verantwortlichkeiten
- Ein falsches Beispiel mit Erklärung
- Ein korrektes Beispiel mit Erklärung
Vollständiges kompiliertes Dokument
Den vollständigen Leitfaden mit allen erweiterten Regeln in einem einzigen Dokument finden Sie unter AGENTS.md.