🏗️ NestJS Clean Architecture CRUD Generator
Stop writing boilerplate. Generate production-grade, strictly-typed NestJS modules following Clean Architecture, Domain-Driven Design (DDD), and CQRS from a single YAML file.
Define your entity, run one command, and get a fully structured module with domain logic, CQRS handlers, TypeORM persistence, DTO validation, Swagger documentation, and REST controllers.
✨ Features
| Feature | Description |
|---|---|
| 🏛️ Clean Architecture | Strict domain / application / infrastructure / presentation layering. |
| ⚡ CQRS | Separate Commands & Queries with dedicated Handlers. |
| 🔗 All 4 Relations | many-to-one, one-to-many, one-to-one, many-to-many with proper FK ownership. |
| 🧩 Aggregates (DDD) | Parent validation, cascade enforcement, and auto-generated nested read routes. |
| 🔄 PUT vs PATCH | Strict separation between full Replace and partial Update. |
| 📊 Production Lists | Built-in Pagination, Whitelisted Filtering, and Sorting (v3). |
| 📄 Swagger & Validation | Auto-generated class-validator DTOs and @nestjs/swagger decorators. |
| 🗂️ Module Manifest | .generator.manifest.json tracks every generated module for easy retrieval. |
| 📦 Bulk Generation | Point at a folder of YAMLs and generate your entire domain at once. |
| 🔒 Idempotent | Safe re-runs; never duplicates imports in app.module.ts. |
📥 Installation
Install globally using pipx (recommended for CLI tools) or pip:
pipx install nestjs-clean-gen
# or
pip install nestjs-clean-gen
---
## 🚀 Quick Start
### 1. Define your entity in YAML
```yaml
# modules/comment.yml
module: comments
parent: posts # Marks this as an aggregate child of 'posts'
entity:
name: Comment
table: comments
fields:
- name: text
type: string
sortable: true # Allow sorting by this field
- name: postId
type: uuid
filterable: true # Allow filtering by this field
- name: authorId
type: uuid
filterable: true
relations:
# Aggregate parent (must be cascade + non-nullable)
- name: post
type: many-to-one
target: Post
targetModule: posts
foreignKey: postId
nullable: false
onDelete: cascade
# Standard association
- name: author
type: many-to-one
target: User
targetModule: users
foreignKey: authorId
nullable: false
onDelete: restrict
operations:
- create
- list
- get
- update
- delete
2. Generate
# Generate a single module
python -m generator.structure.cli modules/comment.yml --src src/
# Bulk generate an entire folder
python -m generator.structure.cli modules/ --src src/ --force
3. Enjoy your API 🎉
| Method | Endpoint | Description |
|---|---|---|
POST |
/comments |
Create a comment |
GET |
/comments |
List all (supports ?page=1&limit=10&sortBy=text) |
GET |
/comments?postId=<uuid> |
Filter by foreign key |
GET |
/comments/:id |
Get one comment |
PATCH |
/comments/:id |
Partial update |
PUT |
/comments/:id |
Full replace |
DELETE |
/comments/:id |
Delete |
GET |
/posts/:postId/comments |
Nested aggregate read route (auto-generated) |
📖 YAML Configuration Reference
Field Types & List Options
| Type | TS Type | TypeORM | Validator | List Options |
|---|---|---|---|---|
string |
string |
varchar |
@IsString |
sortable, filterable |
number |
number |
integer |
@IsNumber |
sortable, filterable |
boolean |
boolean |
boolean |
@IsBoolean |
filterable |
date |
Date |
timestamptz |
@IsDateString |
sortable, filterable |
uuid |
string |
uuid |
@IsUUID |
filterable |
Note: id, createdAt, and updatedAt are managed automatically and are sortable by default.
Relationships
many-to-one (Owning side - holds the FK)
- name: author
type: many-to-one
target: User
targetModule: users
foreignKey: authorId
nullable: false
onDelete: restrict # restrict | cascade | set-null | no-action
one-to-many (Inverse side)
- name: comments
type: one-to-many
target: Comment
targetModule: comments
mappedBy: author # Must match the child's many-to-one relation name
one-to-one (Owning side - FK is marked UNIQUE)
- name: profile
type: one-to-one
target: Profile
targetModule: profiles
foreignKey: profileId
nullable: true
onDelete: set-null
many-to-many (Junction table)
- name: tags
type: many-to-many
target: Tag
targetModule: tags
joinTable: post_tags
joinColumn: post_id
inverseJoinColumn: tag_id
💻 CLI Usage
python -m generator.structure.cli <path> [options]
Arguments:
<path>: Path to a single.ymlfile, or a directory for bulk generation.
Options:
| Flag | Default | Description |
|---|---|---|
--src |
src |
Root directory where modules are generated. |
--templates |
templates |
Directory containing the .tpl template files. |
--app-module |
<src>/app.module.ts |
Path to app.module.ts for auto-registration. |
--project-root |
. |
Where .generator.manifest.json is stored. |
--force |
False |
Overwrite existing generated files. |
--dry-run |
False |
Validate and print output without writing files. |
--fail-fast |
False |
Stop bulk generation on the first error. |
🗂️ The Module Manifest
Every successful generation upserts an entry into .generator.manifest.json at the project root.
Commit this file to Git. It serves as the team-visible inventory of everything the generator has produced, preventing modules from "popping out of nowhere" and enabling future cross-module validation.
🧠 Generator Architecture
The generator is a modular Python package. Templates (.tpl files) are edited directly, and the Python code handles parsing, validation, and rendering.
generator/
├── structure/
│ ├── cli.py # Entry point (single + bulk)
│ ├── config_loader.py # YAML loading + aggregate validation
│ ├── generator.py # Orchestrates file writing
│ ├── context.py # Builds the template context
│ ├── output_mapper.py # Template → output path mapping
│ ├── manifest.py # .generator.manifest.json upsert
│ ├── app_module_updater.py # Idempotent app.module.ts registration
│ ├── fields/ # Field builder package
│ │ ├── normalization.py # normalize fields/relations
│ │ ├── types.py # ts_type, typeorm_type
│ │ ├── domain.py # entity/command/handler builders
│ │ ├── dto.py # DTO + validator + swagger builders
│ │ ├── orm.py # ORM columns + imports
│ │ ├── mapping.py # domain ↔ ORM field mapping
│ │ └── registry.py # build_field_context orchestrator
│ └── relations/ # Relation builders
│ ├── many_to_one.py
│ ├── one_to_many.py
│ ├── one_to_one.py
│ ├── many_to_many.py
│ └── registry.py # relation dispatcher
└── templates/ # .tpl template sources (edit these directly!)
🗺️ Roadmap
- v1: Clean Architecture CRUD, CQRS, TypeORM, 4 Relation Types.
- v2: Aggregates, Nested Reads, Manifest, Bulk Generation, Idempotent Registration.
- v3: Pagination, Whitelisted Filtering, Sorting.
📄 License
This project is licensed under the AGPL-3.0 License.
Enterprise / Commercial Use: If you wish to use this generator in proprietary, closed-source products without the AGPL open-source obligations, a commercial license is available. Please contact the maintainer for details.
Built to eliminate boilerplate so you can focus on your domain.
Metadata
Release files for nestjs-clean-gen 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nestjs_clean_gen-1.0.2.tar.gz | 59.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nestjs_clean_gen-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 113.3 kB
Release files / nestjs_clean_gen-1.0.2.tar.gz
| Download URL | nestjs_clean_gen-1.0.2.tar.gz |
|---|---|
| Size | 59.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9ddbf3357f6a0bba027102b33c0ccc5395a2b33eea4f638a13bd3ab5c9268b0c
|
|
BLAKE2b-256 checksum How to use checksums |
4ddb45bb53eed775bb7dead6293bc74d65f5dc4d94d9369e599df390b6eafb1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.18.1 {"ci":null,"cpu":"x86_64","distro":{"id":"trixie","libc":{"lib":"glibc","version":"2.41"},"name":"Debian GNU/Linux","version":"13"},"implementation":{"name":"CPython","version":"3.13.5"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.5.7 9 Jun 2026","python":"3.13.5","system":{"name":"Linux","release":"6.12.111+deb13-amd64"}} HTTPX2/2.13.1
|
Release files / nestjs_clean_gen-1.0.2-py3-none-any.whl
| Download URL | nestjs_clean_gen-1.0.2-py3-none-any.whl |
|---|---|
| Size | 53.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d30f4dce37e8cdc8e04b9c7171b403cf7e70f4f4b910a140ffdefccdc025a2da
|
|
BLAKE2b-256 checksum How to use checksums |
a192f8e69243e3e57c97a875f50e16fb9c12e377472fdcb16d64079047709e3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.18.1 {"ci":null,"cpu":"x86_64","distro":{"id":"trixie","libc":{"lib":"glibc","version":"2.41"},"name":"Debian GNU/Linux","version":"13"},"implementation":{"name":"CPython","version":"3.13.5"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.5.7 9 Jun 2026","python":"3.13.5","system":{"name":"Linux","release":"6.12.111+deb13-amd64"}} HTTPX2/2.13.1
|