# /controller - Skill Controller SmartStack

> **Synergie Skill/Commande:**
> - **Skill** (`.claude/skills/controller/`) → Invocation automatique par Claude
> - **Commande** (`/controller:create`) → Invocation manuelle par l'utilisateur
> - Templates partagés dans `.claude/skills/controller/templates.md`

> **MCP INTEGRATION:** This command can use `mcp__smartstack__scaffold_extension` for code generation.

---

## MCP SCAFFOLDING (Recommended)

> **NEW:** Use SmartStack MCP for consistent code generation across all projects.

### When to Use MCP

| Scenario | Use MCP | Use Templates |
|----------|---------|---------------|
| Standard CRUD controller | Yes | - |
| Controller with custom logic | - | Yes |
| Need validation before | Yes | - |
| Offline mode | - | Yes |

### MCP Invocation

**Claude instruction:** For standard controller generation, invoke MCP first:

```json
{
  "tool": "mcp__smartstack__scaffold_extension",
  "parameters": {
    "type": "controller",
    "name": "{MODULE}",
    "options": {
      "namespace": "SmartStack.Api.Controllers.{AREA}",
      "methods": ["GetAll", "GetById", "Create", "Update", "Delete"]
    }
  }
}
```

The MCP returns a `ScaffoldResult`:

```typescript
interface ScaffoldResult {
  success: boolean;
  files: GeneratedFile[];
  instructions: string[];
}

interface GeneratedFile {
  path: string;
  content: string;
  type: 'created' | 'modified';
}
```

### Post-MCP Steps

After MCP generates the controller:
1. Review generated code
2. Add to `Permissions.cs` (STEP 6 below)
3. Add to `PermissionConfiguration.cs`
4. Create migration if needed

---

## ARGUMENTS

```
/controller:create <area> <module> [entity]
```

| Variable | Extraction | Valeurs |
|----------|------------|---------|
| `$AREA` | Premier mot | `Admin`, `Support`, `Business`, `User`, `Auth` |
| `$MODULE` | Deuxième mot | Nom du module (PascalCase) |
| `$ENTITY` | Troisième mot (optionnel) | Nom de l'entité Domain (défaut = singulier de $MODULE) |

**Exemples:**
```
/controller:create Admin Users
/controller:create Support Tickets Ticket
/controller:create Business Leads Lead
```

---

## VALIDATION CONTEXTES (CRITIQUE)

> **RAPPEL:** Les controllers client doivent être dans l'Area `Business`.

### Mapping Area → Context

| Area | Route Prefix | Permission Context | Autorisé Client |
|------|--------------|-------------------|-----------------|
| `Admin` | `api/admin/` | `platform.administration.*` | ❌ NON |
| `Support` | `api/support/` | `platform.support.*` | ❌ NON |
| `Business` | `api/business/` | `business.*` | ✅ OUI |
| `User` | `api/user/` | `personal.myspace.*` | ❌ NON |
| `Auth` | `api/auth/` | (AllowAnonymous) | ❌ NON |

### Validation Automatique

```
AVANT génération:

SI $AREA NOT IN ["Admin", "Support", "Business", "User", "Auth"]:
    ❌ ERREUR: "Area '$AREA' non reconnue"
    SUGGÉRER: "Utilisez 'Business' pour les modules client"
    ABORT

SI création par client ET $AREA IN ["Admin", "Support", "User", "Auth"]:
    ⚠️ WARNING: "L'area '$AREA' est réservée au core SmartStack"
    SUGGÉRER: "Utilisez '/controller:create Business $MODULE $ENTITY'"
```

---

## RÈGLES ABSOLUES

1. **TOUJOURS** utiliser `[RequirePermission(Permissions.*)]` - jamais de strings
2. **TOUJOURS** ajouter `[ProducesResponseType]` pour chaque status possible
3. **TOUJOURS** logger les opérations (Info pour CRUD, Warning pour Delete/Sensitive)
4. **TOUJOURS** protéger les comptes système (UserType.System/LocalAdmin)
5. **JAMAIS** de SQL direct - utiliser EF Core
6. **JAMAIS** d'endpoint sans permission (sauf [AllowAnonymous] pour auth)

---

## WORKFLOW

### ÉTAPE 1: PARSING DES ARGUMENTS

```
EXTRAIRE $AREA = premier mot des arguments (PascalCase)
EXTRAIRE $MODULE = deuxième mot des arguments (PascalCase)
EXTRAIRE $ENTITY = troisième mot OU singulier de $MODULE

SI $AREA absent → AskUserQuestion (options: Admin, Support, Business, User, Auth)
SI $MODULE absent → AskUserQuestion (texte libre)
```

### ÉTAPE 2: ANALYSE EXISTANTE

| Action | Commande |
|--------|----------|
| Entity Domain | `Glob "Domain/**/{Entity}.cs"` |
| Permissions existantes | `Read Permissions.cs` |
| DbContext DbSet | `Grep "{Entity}s" ApplicationDbContext.cs` |
| Controller existant | `Glob "Controllers/{Area}/{Module}Controller.cs"` |

### ÉTAPE 3: CONFIRMATION UTILISATEUR

```typescript
AskUserQuestion({
  questions: [
    {
      header: "Type",
      question: "Quel type de controller ?",
      options: [
        { label: "CRUD Complet (Recommended)", description: "GET list, GET by ID, POST, PUT, PATCH, DELETE" },
        { label: "Read-Only", description: "GET list, GET by ID uniquement" },
        { label: "Custom", description: "Actions spécifiques à définir" }
      ]
    },
    {
      header: "Postman",
      question: "Générer les tests Postman ?",
      options: [
        { label: "Oui (Recommended)", description: "Ajoute tests dans SmartStack.Security.postman_collection.json" },
        { label: "Non", description: "Controller uniquement" }
      ]
    }
  ]
})
```

### ÉTAPE 4: VALIDATION SÉCURITÉ

**Vérifications obligatoires avant génération:**

1. ✅ Permission path existe ou sera créée
2. ✅ Format permission: `context.application.module.action`
3. ✅ DbSet existe dans ApplicationDbContext
4. ✅ Entity a les méthodes Create/Update nécessaires

### ÉTAPE 5: GÉNÉRATION

| Fichier | Chemin | Action |
|---------|--------|--------|
| Controller | `src/SmartStack.Api/Controllers/{Area}/{Module}Controller.cs` | CREATE |
| Permissions | `src/SmartStack.Application/Common/Authorization/Permissions.cs` | UPDATE |
| Tests Postman | `tests/SmartStack.Security.postman_collection.json` | UPDATE (si choisi) |

**Utiliser templates de** → `.claude/skills/controller/templates.md`

### ÉTAPE 6: SYNCHRONISATION BASE DE DONNÉES (OBLIGATOIRE)

> **CRITIQUE:** Un controller avec `[RequirePermission]` retournera **403 Forbidden** pour TOUS les utilisateurs si la permission n'existe pas dans la base de données.

#### Workflow obligatoire

```
┌──────────────────────────────────────────────────────────────────────────────┐
│                     WORKFLOW SYNCHRONISATION PERMISSIONS                     │
├──────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  1. GÉNÉRER CONTROLLER                                                       │
│     └─→ [RequirePermission(Permissions.{Module}.View)]                       │
│                                                                              │
│  2. AJOUTER À Permissions.cs (Application layer)                             │
│     └─→ public static class {Module} { ... }                                 │
│                                                                              │
│  3. AJOUTER À PermissionConfiguration.cs (Infrastructure layer)              │
│     └─→ HasData(new { Path = "...", ModuleId = ..., ... })                   │
│                                                                              │
│  4. CRÉER MIGRATION EF CORE                                                  │
│     └─→ /efcore:migration Add{Module}Permissions                             │
│                                                                              │
│  5. VALIDER COHÉRENCE                                                        │
│     └─→ Vérifier que TOUS les paths dans Permissions.cs                      │
│         existent dans PermissionConfiguration.cs                             │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘
```

### ÉTAPE 7: LOGS CRITIQUES - VÉRIFICATION

Après génération, **VÉRIFIER** que le controller contient :

| Événement | Niveau Requis | Présent ? |
|-----------|---------------|-----------|
| Login échoué (si auth) | `LogCritical` | ☐ |
| Compte verrouillé (si auth) | `LogCritical` | ☐ |
| Password change | `LogWarning` | ☐ |
| Création | `LogInformation` | ☐ |
| Modification | `LogInformation` | ☐ |
| Suppression | `LogWarning` | ☐ |
| Désactivation | `LogWarning` | ☐ |

### ÉTAPE 8: RÉSUMÉ FINAL

Afficher:
- ✅ Fichiers créés (chemins cliquables)
- 🔐 Permissions ajoutées
- 🧪 Tests Postman générés (si applicable)
- 📝 Prochaines étapes:
  - Vérifier les DTOs
  - Ajouter validation métier si nécessaire
  - Tester avec Swagger/Postman

---

## SOURCES DE DONNÉES

| Donnée | Source |
|--------|--------|
| Entity Domain | `src/SmartStack.Domain/**/{Entity}.cs` |
| DbContext | `src/SmartStack.Application/Common/Interfaces/IApplicationDbContext.cs` |
| Permissions | `src/SmartStack.Application/Common/Authorization/Permissions.cs` |
| Controllers existants | `src/SmartStack.Api/Controllers/**/*.cs` |
| Tests Postman | `tests/SmartStack.Security.postman_collection.json` |

---

## RÈGLES SÉCURITÉ - LOGS CRITIQUES (OBLIGATOIRE)

| Événement | Niveau | Pattern |
|-----------|--------|---------|
| Login échoué | `Critical` | `LogCritical("Login attempt on locked account...")` |
| Permission refusée | `Critical` | Auto via `SecurityAuditMiddleware` |
| Compte verrouillé | `Critical` | `LogCritical("Account locked...")` |
| Password change | `Warning` | `LogWarning("Password changed...")` |
| Création/MAJ | `Information` | `LogInformation("User {User} creating...")` |
| Suppression | `Warning` | `LogWarning("User {User} deleting...")` |

---

## CONTRAINTES TECHNIQUES

### Injection de Dépendances (Obligatoire)

```csharp
public {Module}Controller(
    IApplicationDbContext context,     // TOUJOURS
    ICurrentUserService currentUser,   // TOUJOURS
    ILogger<{Module}Controller> logger // TOUJOURS
    // + services spécifiques au module
)
```

### ProducesResponseType (Obligatoire)

```csharp
[ProducesResponseType(typeof(PagedResult<T>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]  // Si [Authorize]
[ProducesResponseType(StatusCodes.Status403Forbidden)]     // Si [RequirePermission]
[ProducesResponseType(StatusCodes.Status404NotFound)]      // Si GET/PUT/DELETE by ID
```

### Logging Pattern (Obligatoire)

```csharp
// Information - opérations standard
_logger.LogInformation("User {User} created {Entity} {Id}",
    _currentUser.Email, entity.Id);

// Warning - opérations sensibles
_logger.LogWarning("User {User} deleted {Entity} {Id} ({Name})",
    _currentUser.Email, id, entity.Name);

// Critical - sécurité (automatique via middleware pour 401/403)
_logger.LogCritical("SECURITY: Login attempt on locked account - {Email} from {IP}",
    email, ipAddress);
```

---

## TEMPLATES

→ **Voir `.claude/skills/controller/templates.md`**

Templates disponibles:
- CRUD Controller (standard)
- Auth Controller (login/logout/change-password)
- Controller avec Relations (nested resources)
- Patterns réutilisables (pagination, error responses)

→ **Voir `.claude/skills/controller/postman-templates.md`**

Templates tests:
- GET list (200, 403, 401)
- POST create (201, 403)
- DELETE (403)
- Auth (login success/fail, invalid token)
