---
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 (TWO calls):
1. Generate DTOs (Response, Create, Update)
2. Generate API Controller with NavRoute attribute

---

## 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}`:

| Application | Table Prefix | Controller Folder |
|-------------|--------------|-------------------|
| administration | `auth_` or `cfg_` | `Administration` |
| support | `support_` | `Support` |
| {application} | `ref_` or domain-specific | `{ApplicationPascal}` |
| myspace | `usr_` | `MySpace` |

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

See `references/mcp-scaffold-workflow.md` for complete MCP workflow, error handling, and post-generation checks.

**Call 1: Generate DTOs**
```javascript
mcp__smartstack__scaffold_extension({
  type: "dto",
  name: "{entityName}",
  options: {
    navRoute: "{permission_path}",
    schema: "core",
    dryRun: false
  }
});
```

**Call 2: Generate Controller**
```javascript
mcp__smartstack__scaffold_extension({
  type: "controller",
  name: "{entityName}",
  options: {
    navRoute: "{permission_path}",  // MANDATORY for NavRoute attribute
    navRouteSuffix: null,
    dryRun: false
  }
});
```

### 4. Parse MCP Responses

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

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

### 5. Present Output to User

```markdown
## Controller Generated via MCP

### API Layer
- `Controllers/{area}/{entityName}Controller.cs`
  - **NavRoute: `{permission_path}`** ✅
  - Endpoints: GET /api/{module}, POST, PUT, DELETE

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

### ✅ NavRoute Integration
- [NavRoute("{permission_path}")] attribute present
- Frontend/backend sync enabled
- Permission-based navigation ready

Next: step-04-perms.md
```

---

## MCP RESPONSE HANDLING

### Success Case

**After Call 1 (DTOs):**
- Display all generated DTO files
- Verify DTOs match entity properties
- Continue to Call 2

**After Call 2 (Controller):**
- Display controller file with NavRoute
- Show frontend/backend sync enabled
- Proceed to step-04-perms.md

### Error Case

**If Call 1 (DTOs) fails:**
- Display error message
- Suggest checking entity name format (must be PascalCase)
- Verify entity properties are defined
- Do NOT proceed to Call 2

**If Call 2 (Controller) fails:**
- Display error message
- Note that DTOs were generated successfully
- Suggest checking navRoute format
- Do NOT proceed to step-04-perms.md

---

## NAVROUTE VALIDATION

Verify NavRoute is present (from `references/mcp-scaffold-workflow.md`):

```javascript
if (!controllerContent.includes('[NavRoute(')) {
  console.error(`NavRoute attribute NOT FOUND`);
  console.error(`Expected: [NavRoute("${permission_path}")]`);
  STOP;
}
```

Without NavRoute:
- ❌ Frontend routes hardcoded
- ❌ No automatic permission sync
- ❌ Manual navigation required

---

## SUCCESS METRICS

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

---

## NEXT STEP:

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