Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions specs/014-gen-crud-command/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Specification Quality Checklist: gen-crud-command

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-05-16
**Feature**: [spec.md](./spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

All checks passed! The specification is ready for the planning phase.
52 changes: 52 additions & 0 deletions specs/014-gen-crud-command/contracts/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Contract: `nfw gen crud` Command

This contract defines the CLI interface for the `nfw gen crud` command, parsing rules, and the expected integration with the NFramework generator engine.

## CLI Usage

```bash
nfw gen crud <ENTITY_NAME> [OPTIONS]
```

## Arguments

- `ENTITY_NAME` (Required): The PascalCase name of the entity for which to generate the CRUD operations (e.g., `Product`, `CustomerOrder`). Must be a valid C# identifier.

## Options

- `--no-api`: Skips generation of the Presentation layer Minimal API endpoint files.
- `--secured`: Adds authorization/security markers to the generated Command and Query classes.
- `--cached`: Adds caching markers to the generated Query classes.
- `--force`: Overwrites existing files in the target directories without prompting.
- `--no-input`: Disables interactive prompts. If required prerequisites (like the entity itself) are missing, or files exist and `--force` is not passed, the command fails fast.

## Interactive Prompts

If run in a TTY environment without `--no-input`:

1. **Missing Entity**: If the specified entity is not found in the domain layer:
- "Entity [ENTITY_NAME] not found. Create it now? (Y/n)"
2. **Missing Options**: If no feature flags are passed:
- "Generate API Endpoints? (Y/n)"
- "Include caching markers? (y/N)"
- "Include security markers? (y/N)"
3. **Existing Files**: If target files already exist:
- "Files for [ENTITY_NAME] already exist. Overwrite? (y/N)"

## Output Format

**Success (stdout)**:

```text
βœ“ Created Application/Features/Product/CreateProductCommand.cs
βœ“ Created Presentation.WebApi/Endpoints/Product/CreateProductEndpoint.cs
...
Generated CRUD for Product successfully in 1.42s.
```

**Error (stderr)**:

```text
Error: Entity 'Product' not found.
Run `nfw add entity Product` first, or run without --no-input to be prompted.
```
47 changes: 47 additions & 0 deletions specs/014-gen-crud-command/data-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Data Model: Generate CRUD Command

The `nfw gen crud` command orchestrates code generation but does not persist state itself. The "data model" here refers to the inputs required by the command and the structure of the generated output artifacts.

## CLI Command Inputs

| Input | Type | Description | Required |
| ------------- | ------- | ----------------------------------------------- | -------- |
| `entity_name` | String | The name of the target entity (e.g., `Product`) | Yes |
| `--no-api` | Boolean | Skips generating Presentation layer endpoints | No |
| `--secured` | Boolean | Adds security markers/attributes to handlers | No |
| `--cached` | Boolean | Adds caching behavior markers to handlers | No |
| `--force` | Boolean | Overwrites existing files without prompting | No |

## Orchestrated Artifacts (Generated Files)

The command generates a standard Clean Architecture vertical slice for the specified entity.

### Application Layer (`Application/Features/[Entity]/`)

- **DTOs**: `Create[Entity]Request.cs`, `Update[Entity]Request.cs`, `[Entity]Response.cs`
- **Commands**: `Create[Entity]Command.cs`, `Update[Entity]Command.cs`, `Delete[Entity]Command.cs`
- **Queries**: `Get[Entity]ByIdQuery.cs`, `List[Entity]sQuery.cs`
- **Handlers**: Corresponding `*Handler.cs` for all Commands and Queries

### Domain/Contract Layer (`Domain/Repositories/` or `Application/Contracts/`)

- **Repository Interface**: `I[Entity]Repository.cs`

### Presentation/Api Layer (`Presentation.WebApi/Endpoints/[Entity]/`)

- **Endpoints**: `Create[Entity]Endpoint.cs`, `Update[Entity]Endpoint.cs`, `Delete[Entity]Endpoint.cs`, `Get[Entity]ByIdEndpoint.cs`, `List[Entity]sEndpoint.cs` (Unless `--no-api` is passed)

## State Transitions (Interactive Mode)

1. **Start**: User runs `nfw gen crud <Entity>`
2. **Validation State**:
- Check if `<Entity>` exists in the domain layer.
- If missing: Prompt "Entity &lt;Entity&gt; not found. Create it now? (Y/n)". If yes, trigger entity generation. If no, abort.
3. **Check Existing State**:
- Check if feature folder / CRUD files already exist.
- If yes: Prompt "Files exist. Overwrite? (y/N)". If yes, set overwrite flag. If no, abort or skip existing.
4. **Options State**:
- Check if optional flags were provided.
- If missing: Prompt for options ("Generate API Endpoints?", "Include caching?", "Include security?").
5. **Generation State**: Execute template rendering for all required artifacts.
6. **End**: Report success and execution time.
78 changes: 78 additions & 0 deletions specs/014-gen-crud-command/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Implementation Plan: Generate CRUD Command

**Branch**: `main` | **Date**: 2026-05-16 | **Spec**: [src/nfw/specs/014-gen-crud-command/spec.md](./spec.md)

**Input**: Feature specification from `src/nfw/specs/014-gen-crud-command/spec.md`

## Summary

Implement the `nfw gen crud <ENTITY_NAME>` CLI command in Rust to orchestrate the rapid generation of DTOs, CQRS commands/queries, handlers, repository contracts, and API endpoints for a given entity. The command must operate in <2 seconds, support interactive and non-interactive workflows, and output fully compilable `.NET` code into standard NFramework clean architecture layers.

## Technical Context

**Language/Version**: Rust 1.85+ (CLI), C# 14/15 (.NET 11 target for generated code)

**Primary Dependencies**: `clap` (CLI argument parsing), `dialoguer` (interactive prompts), NFramework `nfw-templates`

**Storage**: Local Filesystem (Workspace directories)

**Testing**: `cargo test` (unit and integration tests), `dotnet build` (compilation validation of generated code)

**Target Platform**: CLI tool (Linux, macOS, Windows)

**Project Type**: CLI command extension

**Performance Goals**: <2 seconds execution time end-to-end

**Constraints**: Generated C# code must be strictly trimmable/Native AOT compatible per NFramework rules. Must fail fast in non-interactive mode.

**Scale/Scope**: Operates on a single entity at a time, generating ~15-20 files per run.

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

- **I. Clean Architecture First**: Passes. Generated artifacts are placed into correct layers (Domain, Application, Presentation) without cross-layer dependency violations.
- **II. CLI Interface Standard**: Passes. Exposes `nfw gen crud` with consistent POSIX flags and supports both interactive and non-interactive modes.
- **III. Test-First**: Passes. Integration tests (T006, T012) are defined before core orchestration logic implementation.
- **IV. Integration Testing for Generated Code**: Passes. T012 explicitly verifies generated code compiles via `dotnet build`.
- **V. Performance and Observability**: Passes. T018 audits execution time against the <2s target; `--verbose` flag supported via CLI framework.
- **Native AOT Compatibility**: Passes. Generated C# code follows framework conventions for trimmable/AOT-compatible output.
- **Zero-Dependency Core**: Passes. Command orchestrates templates without introducing new library dependencies into the CLI itself.

## Project Structure

### Documentation (this feature)

```text
src/nfw/specs/014-gen-crud-command/
β”œβ”€β”€ spec.md # Feature specification
β”œβ”€β”€ plan.md # This file (/speckit.plan command output)
β”œβ”€β”€ research.md # Phase 0 output
β”œβ”€β”€ data-model.md # Phase 1 output
β”œβ”€β”€ quickstart.md # Phase 1 output
β”œβ”€β”€ contracts/ # Phase 1 output (cli.md)
```

### Source Code (repository root)

```text
src/nfw/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ commands/
β”‚ β”‚ └── gen/
β”‚ β”‚ β”œβ”€β”€ mod.rs
β”‚ β”‚ └── crud.rs # Main command entry point and logic
β”‚ └── lib.rs # Registration of new command
β”œβ”€β”€ tests/
β”‚ └── integration/
β”‚ └── gen_crud_tests.rs # Integration tests running `dotnet build`
```

**Structure Decision**: The implementation will integrate natively into the existing Rust CLI workspace (`src/nfw`). We will add the `crud.rs` command parser and orchestrator inside `src/commands/gen/`.

## Complexity Tracking

> **Fill ONLY if Constitution Check has violations that must be justified**

*No violations detected. Standard CLI sub-command expansion.*
58 changes: 58 additions & 0 deletions specs/014-gen-crud-command/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Quickstart: Generate CRUD Command

This guide demonstrates how to use the `nfw gen crud` command to quickly scaffold an entire feature vertical slice in your NFramework workspace.

## Prerequisites

- Ensure you are inside a valid NFramework `.NET` workspace.
- Ensure the target entity exists in your domain layer (or be prepared to let the CLI create it for you).

## Basic Usage

To generate a full CRUD implementation for a `Product` entity, run:

```bash
nfw gen crud Product
```

If you haven't specified any flags, the CLI will interactively ask you a few questions:

```text
? Generate API Endpoints? Yes
? Include caching markers? No
? Include security markers? Yes
```

In under 2 seconds, the CLI will generate all DTOs, Commands, Queries, Handlers, the Repository contract, and API endpoints, placing them in the correct `Application` and `Presentation` folders.

## Advanced Usage (CI/CD / Automation)

If you are scripting the generation or just prefer to bypass interactive prompts, use flags:

```bash
# Generate everything, skip interactive prompts, overwrite existing files
nfw gen crud Product --secured --cached --force --no-input

# Generate only Application/Domain contracts (no HTTP API endpoints)
nfw gen crud Product --no-api
```

## What Gets Generated?

For the `Product` entity, you will get:

- `Application/Features/Product/CreateProductCommand.cs` (and Update/Delete)
- `Application/Features/Product/GetProductByIdQuery.cs` (and List)
- DTOs like `ProductResponse.cs`
- `Application/Contracts/IProductRepository.cs`
- `Presentation.WebApi/Endpoints/Product/CreateProductEndpoint.cs` (and other endpoints)

## Validating Generation

Because NFramework prioritizes clean code generation, the output is guaranteed to compile. Run:

```bash
dotnet build
```

Your new CRUD flow is ready to use!
43 changes: 43 additions & 0 deletions specs/014-gen-crud-command/research.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Research: Generate CRUD Command

## Domain Context

The `nfw gen crud` command belongs to the `nfw` CLI tool built in Rust, part of the NFramework ecosystem. It orchestrates the generation of a complete CRUD (Create, Read, Update, Delete) scaffolding for a `.NET` service entity. The CLI relies on source generators and abstract repositories for its scaffolding output.

## Extracted Unknowns and Resolutions

### Framework/CLI Ecosystem

**Decision**: Use `clap` for command parsing and `nfw-templates` for generator logic.
**Rationale**: `nfw` is already built using Rust 1.85+ with `clap`. The template/generator execution logic must seamlessly integrate with the existing `src/nfw-generators` schema used by `nfw gen endpoint` and `nfw add entity`.
**Alternatives considered**: Writing a completely new templating engine was rejected since `nfw-templates` already exists and maintains workspace generation conventions.

### File/Layer Generation Rules

**Decision**: Command will orchestrate existing generators or templates to produce DTOs, Commands, Queries, Handlers, Repositories, and Endpoints under `Application/Features/[Entity]` and Presentation layers.
**Rationale**: The spec mandates placing files into NFramework's standard Clean Architecture layers. The command must automatically create the target feature directory if missing.
**Alternatives considered**: Hardcoding paths instead of using the generator configuration. Rejected as it violates the dynamic template schema defined in `.specify/template.schema.json`.

### Interactive Prompts vs. Flags

**Decision**: Use a prompt library (like `dialoguer` in Rust) to interactively ask for missing options when a TTY is present. Use `--no-api`, `--secured`, `--cached` flags for non-interactive automation.
**Rationale**: Satisfies the spec's P2 stories for both developer experience (interactive) and CI/CD pipelines (non-interactive automation).
**Alternatives considered**: Only supporting flags. Rejected because it directly violates User Story 2.

### Handling Missing Entities

**Decision**: The command will interactively prompt to run the equivalent of `nfw add entity` if the entity is missing. In non-interactive mode, it will fail fast.
**Rationale**: Resolved during the clarification phase. It balances user experience in terminals with safe, predictable CI/CD failure modes.
**Alternatives considered**: Automatically generating the entity without asking, which was rejected during clarification.

### Performance Target

**Decision**: Generation must complete in <2 seconds.
**Rationale**: Rust's execution speed coupled with pre-compiled templates or fast string interpolation (e.g., `minijinja` or `tera` if used by `nfw-templates`) easily supports sub-second generation.
**Alternatives considered**: N/A, strict requirement.

### Testing Strategy

**Decision**: Integration tests using `cargo test` that invoke the command on a temporary workspace and verify `dotnet build` passes.
**Rationale**: Matches the standard `src/nfw/tests/integration/` approach used by other `nfw` commands, ensuring generated code is syntactically valid in C#.
**Alternatives considered**: Only unit testing the Rust logic. Rejected because it wouldn't guarantee the generated `.NET` code compiles, violating SC-002.
Loading
Loading