---
name: step-03-generate
description: Generate controller using MCP scaffold_extension with NavRoute
next_step: steps/step-04-perms.md
---

# Step 3: Generate Controller

## MANDATORY EXECUTION RULES

- ALWAYS use MCP `scaffold_extension` tool - NEVER use templates
- ALWAYS generate Controller + DTOs as a unit
- ALWAYS include NavRoute attribute for frontend/backend sync
- YOU ARE AN ORCHESTRATOR calling MCP, not a generator
- MCP is the SOURCE OF TRUTH for code generation

## YOUR TASK

Call the SmartStack MCP `scaffold_extension` tool with type "controller" to generate:
1. API Controller with NavRoute attribute
2. DTOs (Response, Create, Update)

---

## AVAILABLE STATE

From previous steps:

| Variable | Description |
|----------|-------------|
| `{area}` | Controller folder (Admin, Business, Support, User) |
| `{module}` | kebab-case module identifier |
| `{entity}` | Entity name (PascalCase) |
| `{permission_path}` | Complete navigation path (navRoute) |
| `{controller_type}` | crud, readonly, custom, auth |

---

## EXECUTION SEQUENCE

### 1. Derive Entity Name

Convert `{module}` to PascalCase for entity name:

```
module: "products"        → entityName: "Product"
module: "order-items"     → entityName: "OrderItem"
module: "user-profiles"   → entityName: "UserProfile"
```

### 2. Determine Table Prefix

Based on navigation context extracted from `{permission_path}`:

| Context | Table Prefix | Controller Folder |
|---------|--------------|-------------------|
| platform.administration | `auth_` or `cfg_` | `Admin` |
| platform.support | `support_` | `Support` |
| business.* | `ref_` or domain-specific | `Business` |
| personal.* | `usr_` | `User` |

### 3. Call MCP scaffold_extension (TWO CALLS)

**First call: Generate DTOs**

```
Tool: mcp__smartstack__scaffold_extension
Args:
  type: "dto"
  name: "{entityName}"  # PascalCase from step 1
  options:
    navRoute: "{permission_path}"  # For proper namespace hierarchy
    schema: "core"
    dryRun: false
```

**Second call: Generate Controller with NavRoute**

```
Tool: mcp__smartstack__scaffold_extension
Args:
  type: "controller"
  name: "{entityName}"  # PascalCase from step 1
  options:
    navRoute: "{permission_path}"  # MANDATORY for NavRoute attribute
    navRouteSuffix: null            # Optional (e.g., "details" → [NavRoute("path", Suffix = "details")])
    dryRun: false
```

**CRITICAL: NavRoute is MANDATORY** - Without it, frontend/backend sync will fail.

**Why two calls?**
- The skill `/controller` assumes the Entity already exists (verified in step-01-analyze.md)
- Type "dto" generates DTOs without regenerating the Entity
- Type "controller" generates the Controller with NavRoute and references to DTOs

### 4. Parse MCP Responses

**From first call (DTOs):**
- `Application/{Context}/{Application}/{Module}/DTOs/{entityName}ResponseDto.cs` - Response DTO
- `Application/{Context}/{Application}/{Module}/DTOs/Create{entityName}Dto.cs` - Create request
- `Application/{Context}/{Application}/{Module}/DTOs/Update{entityName}Dto.cs` - Update request

**From second call (Controller):**
- `Api/Controllers/{area}/{entityName}Controller.cs` - REST Controller **with [NavRoute]**

### 5. Present Output to User

```markdown
## Controller Generated via MCP

### API Layer
- `Controllers/{area}/{entityName}Controller.cs`
  - **NavRoute: `{permission_path}`** ✅
  - Endpoints:
    - GET /api/{module} - List all
    - GET /api/{module}/{id} - Get by ID
    - POST /api/{module} - Create
    - PUT /api/{module}/{id} - Update
    - DELETE /api/{module}/{id} - Delete

### Application Layer (DTOs)
- `{Context}/{Application}/{Module}/DTOs/{entityName}ResponseDto.cs`
- `{Context}/{Application}/{Module}/DTOs/Create{entityName}Dto.cs`
- `{Context}/{Application}/{Module}/DTOs/Update{entityName}Dto.cs`

### ✅ NavRoute Integration
The controller uses `[NavRoute("{permission_path}")]` which enables:
- ✅ Automatic frontend route generation
- ✅ Permission-based navigation sync
- ✅ Dynamic API routing from Navigation entities

### Next Steps
1. Permissions will be synchronized in step-04-perms.md
2. Validate conventions with MCP `validate_conventions`
```

---

## MCP RESPONSE HANDLING

### Success Case

**After first call (DTOs):**
- Display all generated DTO files
- Verify DTOs match entity properties
- Continue to second call

**After second call (Controller):**
- Display controller file
- Show NavRoute attribute included
- Highlight frontend/backend sync enabled
- Store controller info for permission sync
- Proceed to step-04-perms.md

### Error Case

**If first call (DTOs) fails:**
- Display error message
- Suggest checking entity name format
- Verify entity properties are defined
- Verify MCP server is running (`/mcp:healthcheck`)
- Do NOT proceed to second call

**If second call (Controller) fails:**
- Display error message
- Note that DTOs were generated successfully
- Suggest checking navRoute format
- Verify MCP server is running (`/mcp:healthcheck`)
- Do NOT proceed to step-04-perms.md

---

## NAVROUTE VALIDATION

**After generation, verify NavRoute is present:**

```
Generated controller MUST contain:
[NavRoute("{permission_path}")]

WITHOUT NavRoute:
❌ Frontend routes will be hardcoded
❌ No automatic permission sync
❌ Manual navigation management required
```

---

## OUTPUT FORMAT:

```
Generated Files:

| File | Path | Status |
|------|------|--------|
| Controller | src/.../Controllers/{area}/{entity}Controller.cs | ✅ Created with [NavRoute] |
| CreateDto | src/.../DTOs/{module}/{entity}CreateDto.cs | ✅ Created |
| UpdateDto | src/.../DTOs/{module}/{entity}UpdateDto.cs | ✅ Created |
| ResponseDto | src/.../DTOs/{module}/{entity}ResponseDto.cs | ✅ Created |

-> Synchronizing permissions...
```

---

## SUCCESS METRICS

- MCP scaffold_extension called successfully (DTOs)
- DTOs generated (ResponseDto, CreateDto, UpdateDto)
- MCP scaffold_extension called successfully (Controller)
- Controller generated with **[NavRoute]** attribute
- NavRoute matches permission_path
- Controller references DTOs correctly
- Proceeded to step-04-perms.md

## FAILURE MODES

- MCP call failed (display error, run /mcp:healthcheck, stop)
- Invalid entity name (must be PascalCase)
- Invalid navRoute format
- MCP server not running

---

## NEXT STEP:

After controller generation complete, proceed to `./step-04-perms.md`
