Skip to main content

PyPI version Python 3.10+ License: AGPL v3

🏗️ 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 .yml file, 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)

Source distribution for nestjs-clean-gen 1.0.2
File Size Uploaded
nestjs_clean_gen-1.0.2.tar.gz 59.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nestjs-clean-gen 1.0.2
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page