@atlashub/smartstack-cli 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.documentation/agents.html +916 -916
- package/.documentation/apex.html +1018 -1018
- package/.documentation/business-analyse.html +1501 -1501
- package/.documentation/commands.html +680 -680
- package/.documentation/css/styles.css +2168 -2168
- package/.documentation/efcore.html +2505 -2505
- package/.documentation/gitflow.html +2618 -2618
- package/.documentation/hooks.html +413 -413
- package/.documentation/index.html +323 -323
- package/.documentation/installation.html +462 -462
- package/.documentation/js/app.js +794 -794
- package/.documentation/test-web.html +513 -513
- package/dist/index.js +807 -277
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/agents/efcore/conflicts.md +44 -17
- package/templates/agents/efcore/db-status.md +27 -6
- package/templates/agents/efcore/scan.md +43 -13
- package/templates/commands/ai-prompt.md +315 -315
- package/templates/commands/application/create.md +362 -362
- package/templates/commands/controller/create.md +216 -216
- package/templates/commands/controller.md +59 -0
- package/templates/commands/documentation/module.md +202 -202
- package/templates/commands/efcore/_env-check.md +153 -153
- package/templates/commands/efcore/conflicts.md +109 -192
- package/templates/commands/efcore/db-status.md +101 -89
- package/templates/commands/efcore/migration.md +23 -11
- package/templates/commands/efcore/scan.md +115 -119
- package/templates/commands/efcore.md +54 -6
- package/templates/commands/feature-full.md +267 -267
- package/templates/commands/gitflow/11-finish.md +145 -11
- package/templates/commands/gitflow/13-sync.md +216 -216
- package/templates/commands/gitflow/14-rebase.md +251 -251
- package/templates/commands/gitflow/2-status.md +120 -10
- package/templates/commands/gitflow/3-commit.md +150 -0
- package/templates/commands/gitflow/7-pull-request.md +134 -5
- package/templates/commands/gitflow/9-merge.md +142 -1
- package/templates/commands/implement.md +663 -663
- package/templates/commands/init.md +562 -0
- package/templates/commands/mcp-integration.md +330 -0
- package/templates/commands/notification.md +129 -129
- package/templates/commands/validate.md +233 -0
- package/templates/commands/workflow.md +193 -193
- package/templates/skills/ai-prompt/SKILL.md +778 -778
- package/templates/skills/application/SKILL.md +563 -563
- package/templates/skills/application/templates-backend.md +450 -450
- package/templates/skills/application/templates-frontend.md +531 -531
- package/templates/skills/application/templates-i18n.md +520 -520
- package/templates/skills/application/templates-seed.md +647 -647
- package/templates/skills/controller/SKILL.md +240 -240
- package/templates/skills/controller/postman-templates.md +614 -614
- package/templates/skills/controller/templates.md +1468 -1468
- package/templates/skills/documentation/SKILL.md +133 -133
- package/templates/skills/documentation/templates.md +476 -476
- package/templates/skills/feature-full/SKILL.md +838 -838
- package/templates/skills/notification/SKILL.md +555 -555
- package/templates/skills/ui-components/SKILL.md +870 -870
- package/templates/skills/workflow/SKILL.md +582 -582
|
@@ -1,240 +1,240 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: controller
|
|
3
|
-
description: |
|
|
4
|
-
Génère automatiquement des controllers API pour SmartStack.
|
|
5
|
-
Utiliser ce skill quand:
|
|
6
|
-
- L'utilisateur demande de créer un controller, endpoint, ou API
|
|
7
|
-
- L'utilisateur mentionne "CRUD", "REST API", "endpoint"
|
|
8
|
-
- L'utilisateur veut ajouter des actions à un module existant
|
|
9
|
-
- Après création d'une entité Domain pour exposer via API
|
|
10
|
-
Types: CRUD standard, Auth/Login, Custom actions
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## STRATÉGIE MODÈLES (Qualité Maximale)
|
|
14
|
-
|
|
15
|
-
| Phase | Modèle | Coût estimé |
|
|
16
|
-
|-------|--------|-------------|
|
|
17
|
-
| Génération complète | **Sonnet** | ~$0.19 |
|
|
18
|
-
| Validation sécurité | **Opus** | ~$0.10 |
|
|
19
|
-
| **Total** | | **~$0.29** |
|
|
20
|
-
|
|
21
|
-
> **Note:** Si vous utilisez Opus pour tout, le skill fonctionne parfaitement
|
|
22
|
-
> mais coûte ~$0.94/controller. Sonnet offre le meilleur rapport qualité/coût
|
|
23
|
-
> pour la génération, Opus pour l'audit sécurité final.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
# Skill Controller SmartStack
|
|
28
|
-
|
|
29
|
-
> **Synergie Skill/Commande:**
|
|
30
|
-
> - **Skill** (`.claude/skills/controller/`) → Invocation automatique par Claude
|
|
31
|
-
> - **Commande** (`/controller:create`) → Invocation manuelle par l'utilisateur
|
|
32
|
-
> - Templates partagés dans `.claude/skills/controller/templates.md`
|
|
33
|
-
|
|
34
|
-
## QUAND CE SKILL S'ACTIVE
|
|
35
|
-
|
|
36
|
-
Claude invoque automatiquement ce skill quand il détecte :
|
|
37
|
-
|
|
38
|
-
| Déclencheur | Exemple |
|
|
39
|
-
|-------------|---------|
|
|
40
|
-
| Demande explicite | "Crée un controller pour les tickets" |
|
|
41
|
-
| Mention d'API | "Il faut exposer les SLA via REST" |
|
|
42
|
-
| Après entité Domain | "L'entité est prête, génère l'API" |
|
|
43
|
-
| Mots-clés | "CRUD", "endpoint", "controller", "API REST" |
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## WORKFLOW AUTOMATIQUE
|
|
48
|
-
|
|
49
|
-
### ÉTAPE 1: DÉTECTION DU TYPE
|
|
50
|
-
|
|
51
|
-
| Indice | → Type |
|
|
52
|
-
|--------|--------|
|
|
53
|
-
| Authentification, login, session | `auth` |
|
|
54
|
-
| Module avec CRUD complet | `crud` |
|
|
55
|
-
| Actions spécifiques seulement | `custom` |
|
|
56
|
-
|
|
57
|
-
### ÉTAPE 2: EXTRACTION DES PARAMÈTRES
|
|
58
|
-
|
|
59
|
-
| Paramètre | Source | Exemple |
|
|
60
|
-
|-----------|--------|---------|
|
|
61
|
-
| `$AREA` | Contexte navigation | `Admin`, `Support`, `Business`, `User` |
|
|
62
|
-
| `$MODULE` | Nom du module | `Tickets`, `Sla`, `Users` |
|
|
63
|
-
| `$ENTITY` | Entité Domain | `Ticket`, `SlaDefinition`, `User` |
|
|
64
|
-
| `$PERMISSION_PATH` | Hiérarchie | `platform.support.tickets` |
|
|
65
|
-
|
|
66
|
-
### ÉTAPE 3: EXÉCUTION
|
|
67
|
-
|
|
68
|
-
Suivre le workflow de la commande `/controller:create`
|
|
69
|
-
|
|
70
|
-
### ÉTAPE 4: SYNCHRONISATION BASE DE DONNÉES (OBLIGATOIRE)
|
|
71
|
-
|
|
72
|
-
> **CRITIQUE:** Un controller avec `[RequirePermission]` retournera **403 Forbidden** pour TOUS les utilisateurs si la permission n'existe pas dans la base de données.
|
|
73
|
-
|
|
74
|
-
#### 4.1 Fichiers à synchroniser
|
|
75
|
-
|
|
76
|
-
| Fichier | Rôle | Action |
|
|
77
|
-
|---------|------|--------|
|
|
78
|
-
| `Permissions.cs` | Constantes code | Ajouter la classe de permissions |
|
|
79
|
-
| `PermissionConfiguration.cs` | Seed EF Core | Ajouter les entrées HasData |
|
|
80
|
-
|
|
81
|
-
#### 4.2 Workflow obligatoire
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
┌──────────────────────────────────────────────────────────────────────────────┐
|
|
85
|
-
│ WORKFLOW SYNCHRONISATION PERMISSIONS │
|
|
86
|
-
├──────────────────────────────────────────────────────────────────────────────┤
|
|
87
|
-
│ │
|
|
88
|
-
│ 1. GÉNÉRER CONTROLLER │
|
|
89
|
-
│ └─→ [RequirePermission(Permissions.{Module}.View)] │
|
|
90
|
-
│ │
|
|
91
|
-
│ 2. AJOUTER À Permissions.cs (Application layer) │
|
|
92
|
-
│ └─→ public static class {Module} { ... } │
|
|
93
|
-
│ │
|
|
94
|
-
│ 3. AJOUTER À PermissionConfiguration.cs (Infrastructure layer) │
|
|
95
|
-
│ └─→ HasData(new { Path = "...", ModuleId = ..., ... }) │
|
|
96
|
-
│ │
|
|
97
|
-
│ 4. CRÉER MIGRATION EF CORE │
|
|
98
|
-
│ └─→ /efcore:migration Add{Module}Permissions │
|
|
99
|
-
│ │
|
|
100
|
-
│ 5. VALIDER COHÉRENCE │
|
|
101
|
-
│ └─→ Vérifier que TOUS les paths dans Permissions.cs │
|
|
102
|
-
│ existent dans PermissionConfiguration.cs │
|
|
103
|
-
│ │
|
|
104
|
-
└──────────────────────────────────────────────────────────────────────────────┘
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
#### 4.3 Template PermissionConfiguration.cs
|
|
108
|
-
|
|
109
|
-
Voir le template complet dans [templates.md](templates.md#template-permissionconfiguration-seed)
|
|
110
|
-
|
|
111
|
-
#### 4.4 Checklist de validation
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
□ Permissions.cs contient la classe {Module} avec View/Create/Update/Delete
|
|
115
|
-
□ PermissionConfiguration.cs contient les entrées HasData correspondantes
|
|
116
|
-
□ Les paths sont identiques entre les deux fichiers
|
|
117
|
-
□ Le ModuleId référence un module existant dans ModuleConfiguration.cs
|
|
118
|
-
□ Migration créée avec /efcore:migration
|
|
119
|
-
□ Migration appliquée avec /efcore:db-deploy
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## RÈGLES ABSOLUES - SÉCURITÉ
|
|
125
|
-
|
|
126
|
-
### 1. Logs Critiques (OBLIGATOIRE)
|
|
127
|
-
|
|
128
|
-
| Événement | Niveau | Pattern |
|
|
129
|
-
|-----------|--------|---------|
|
|
130
|
-
| Login échoué | `Critical` | `LogCritical("Login attempt on locked account...")` |
|
|
131
|
-
| Permission refusée | `Critical` | Auto via `SecurityAuditMiddleware` |
|
|
132
|
-
| Compte verrouillé | `Critical` | `LogCritical("Account locked...")` |
|
|
133
|
-
| Password change | `Warning` | `LogWarning("Password changed...")` |
|
|
134
|
-
| Création/MAJ | `Information` | `LogInformation("User {User} creating...")` |
|
|
135
|
-
| Suppression | `Warning` | `LogWarning("User {User} deleting...")` |
|
|
136
|
-
|
|
137
|
-
### 2. Protection Comptes Système (OBLIGATOIRE)
|
|
138
|
-
|
|
139
|
-
```csharp
|
|
140
|
-
// TOUJOURS vérifier avant modification d'entité User-related
|
|
141
|
-
if (entity.UserType == UserType.System || entity.UserType == UserType.LocalAdmin)
|
|
142
|
-
return BadRequest(new { message = "Cannot modify system accounts" });
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 3. Permissions (OBLIGATOIRE)
|
|
146
|
-
|
|
147
|
-
```csharp
|
|
148
|
-
// TOUJOURS utiliser les constantes Permissions.*
|
|
149
|
-
[RequirePermission(Permissions.Support.Tickets.View)] // ✅ Correct
|
|
150
|
-
[RequirePermission("platform.support.tickets.read")] // ❌ Éviter strings
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### 4. Cache Invalidation (SI rôles/permissions)
|
|
154
|
-
|
|
155
|
-
```csharp
|
|
156
|
-
// Après modification de rôle ou permission
|
|
157
|
-
await _permissionService.InvalidateUserPermissionsCacheAsync(userId, ct);
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## RÉFÉRENCE RAPIDE
|
|
163
|
-
|
|
164
|
-
### Services à Injecter
|
|
165
|
-
|
|
166
|
-
| Service | Usage | Obligatoire |
|
|
167
|
-
|---------|-------|-------------|
|
|
168
|
-
| `IApplicationDbContext` | Accès DB | ✅ Toujours |
|
|
169
|
-
| `ICurrentUserService` | User courant | ✅ Toujours |
|
|
170
|
-
| `ILogger<T>` | Logging | ✅ Toujours |
|
|
171
|
-
| `IPermissionService` | Cache permissions | Si roles/permissions |
|
|
172
|
-
| `IPasswordService` | Hash passwords | Si auth |
|
|
173
|
-
| `IJwtService` | Tokens JWT | Si auth |
|
|
174
|
-
| `IUserSessionService` | Sessions | Si auth |
|
|
175
|
-
| `INotificationService` | Notifications | Si notifications |
|
|
176
|
-
|
|
177
|
-
### ProducesResponseType (OBLIGATOIRE)
|
|
178
|
-
|
|
179
|
-
```csharp
|
|
180
|
-
[ProducesResponseType(typeof(ItemDto), StatusCodes.Status200OK)]
|
|
181
|
-
[ProducesResponseType(StatusCodes.Status401Unauthorized)] // Si [Authorize]
|
|
182
|
-
[ProducesResponseType(StatusCodes.Status403Forbidden)] // Si [RequirePermission]
|
|
183
|
-
[ProducesResponseType(StatusCodes.Status404NotFound)] // Si GET by ID
|
|
184
|
-
[ProducesResponseType(StatusCodes.Status400BadRequest)] // Si validation
|
|
185
|
-
[ProducesResponseType(StatusCodes.Status409Conflict)] // Si unique constraint
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## USER PATH TRACKING
|
|
191
|
-
|
|
192
|
-
> **IMPORTANT:** Le tracking du chemin utilisateur est géré par **infrastructure**, pas par les controllers.
|
|
193
|
-
|
|
194
|
-
### Middleware Existant
|
|
195
|
-
|
|
196
|
-
`ApplicationAccessTrackingMiddleware` track automatiquement :
|
|
197
|
-
- ✅ UserId, ApplicationId, ModuleId
|
|
198
|
-
- ✅ IP Address, User Agent, Device Type
|
|
199
|
-
- ✅ AccessedAt (timestamp)
|
|
200
|
-
|
|
201
|
-
### Enrichissement Recommandé (Séparé)
|
|
202
|
-
|
|
203
|
-
Pour tracker le **temps passé** sur chaque module :
|
|
204
|
-
|
|
205
|
-
```csharp
|
|
206
|
-
// Dans ApplicationAccess entity - AJOUTER :
|
|
207
|
-
public DateTime? LeftAt { get; private set; }
|
|
208
|
-
public TimeSpan? Duration => LeftAt.HasValue ? LeftAt - AccessedAt : null;
|
|
209
|
-
|
|
210
|
-
// Dans middleware - AJOUTER :
|
|
211
|
-
// 1. Au début de requête: créer/identifier session
|
|
212
|
-
// 2. À la fin de requête: calculer durée ou marquer "navigation away"
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
→ Ceci est un **enhancement infrastructure**, pas un controller concern.
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## TESTS POSTMAN
|
|
220
|
-
|
|
221
|
-
Chaque controller doit avoir des tests couvrant :
|
|
222
|
-
|
|
223
|
-
| Test | User | Status Attendu |
|
|
224
|
-
|------|------|----------------|
|
|
225
|
-
| GET list | SuperAdmin | 200 |
|
|
226
|
-
| GET list | NoPerm | 403 |
|
|
227
|
-
| GET list | Anonymous | 401 |
|
|
228
|
-
| POST create | ReadOnly | 403 |
|
|
229
|
-
| POST create | WithPerm | 201 |
|
|
230
|
-
| DELETE | ReadOnly | 403 |
|
|
231
|
-
|
|
232
|
-
→ Templates dans `postman-templates.md`
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## FICHIERS ASSOCIÉS
|
|
237
|
-
|
|
238
|
-
- **Templates Controller:** [templates.md](templates.md)
|
|
239
|
-
- **Templates Postman:** [postman-templates.md](postman-templates.md)
|
|
240
|
-
- **Commande complète:** `.claude/commands/controller-create.md`
|
|
1
|
+
---
|
|
2
|
+
name: controller
|
|
3
|
+
description: |
|
|
4
|
+
Génère automatiquement des controllers API pour SmartStack.
|
|
5
|
+
Utiliser ce skill quand:
|
|
6
|
+
- L'utilisateur demande de créer un controller, endpoint, ou API
|
|
7
|
+
- L'utilisateur mentionne "CRUD", "REST API", "endpoint"
|
|
8
|
+
- L'utilisateur veut ajouter des actions à un module existant
|
|
9
|
+
- Après création d'une entité Domain pour exposer via API
|
|
10
|
+
Types: CRUD standard, Auth/Login, Custom actions
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## STRATÉGIE MODÈLES (Qualité Maximale)
|
|
14
|
+
|
|
15
|
+
| Phase | Modèle | Coût estimé |
|
|
16
|
+
|-------|--------|-------------|
|
|
17
|
+
| Génération complète | **Sonnet** | ~$0.19 |
|
|
18
|
+
| Validation sécurité | **Opus** | ~$0.10 |
|
|
19
|
+
| **Total** | | **~$0.29** |
|
|
20
|
+
|
|
21
|
+
> **Note:** Si vous utilisez Opus pour tout, le skill fonctionne parfaitement
|
|
22
|
+
> mais coûte ~$0.94/controller. Sonnet offre le meilleur rapport qualité/coût
|
|
23
|
+
> pour la génération, Opus pour l'audit sécurité final.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Skill Controller SmartStack
|
|
28
|
+
|
|
29
|
+
> **Synergie Skill/Commande:**
|
|
30
|
+
> - **Skill** (`.claude/skills/controller/`) → Invocation automatique par Claude
|
|
31
|
+
> - **Commande** (`/controller:create`) → Invocation manuelle par l'utilisateur
|
|
32
|
+
> - Templates partagés dans `.claude/skills/controller/templates.md`
|
|
33
|
+
|
|
34
|
+
## QUAND CE SKILL S'ACTIVE
|
|
35
|
+
|
|
36
|
+
Claude invoque automatiquement ce skill quand il détecte :
|
|
37
|
+
|
|
38
|
+
| Déclencheur | Exemple |
|
|
39
|
+
|-------------|---------|
|
|
40
|
+
| Demande explicite | "Crée un controller pour les tickets" |
|
|
41
|
+
| Mention d'API | "Il faut exposer les SLA via REST" |
|
|
42
|
+
| Après entité Domain | "L'entité est prête, génère l'API" |
|
|
43
|
+
| Mots-clés | "CRUD", "endpoint", "controller", "API REST" |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## WORKFLOW AUTOMATIQUE
|
|
48
|
+
|
|
49
|
+
### ÉTAPE 1: DÉTECTION DU TYPE
|
|
50
|
+
|
|
51
|
+
| Indice | → Type |
|
|
52
|
+
|--------|--------|
|
|
53
|
+
| Authentification, login, session | `auth` |
|
|
54
|
+
| Module avec CRUD complet | `crud` |
|
|
55
|
+
| Actions spécifiques seulement | `custom` |
|
|
56
|
+
|
|
57
|
+
### ÉTAPE 2: EXTRACTION DES PARAMÈTRES
|
|
58
|
+
|
|
59
|
+
| Paramètre | Source | Exemple |
|
|
60
|
+
|-----------|--------|---------|
|
|
61
|
+
| `$AREA` | Contexte navigation | `Admin`, `Support`, `Business`, `User` |
|
|
62
|
+
| `$MODULE` | Nom du module | `Tickets`, `Sla`, `Users` |
|
|
63
|
+
| `$ENTITY` | Entité Domain | `Ticket`, `SlaDefinition`, `User` |
|
|
64
|
+
| `$PERMISSION_PATH` | Hiérarchie | `platform.support.tickets` |
|
|
65
|
+
|
|
66
|
+
### ÉTAPE 3: EXÉCUTION
|
|
67
|
+
|
|
68
|
+
Suivre le workflow de la commande `/controller:create`
|
|
69
|
+
|
|
70
|
+
### ÉTAPE 4: SYNCHRONISATION BASE DE DONNÉES (OBLIGATOIRE)
|
|
71
|
+
|
|
72
|
+
> **CRITIQUE:** Un controller avec `[RequirePermission]` retournera **403 Forbidden** pour TOUS les utilisateurs si la permission n'existe pas dans la base de données.
|
|
73
|
+
|
|
74
|
+
#### 4.1 Fichiers à synchroniser
|
|
75
|
+
|
|
76
|
+
| Fichier | Rôle | Action |
|
|
77
|
+
|---------|------|--------|
|
|
78
|
+
| `Permissions.cs` | Constantes code | Ajouter la classe de permissions |
|
|
79
|
+
| `PermissionConfiguration.cs` | Seed EF Core | Ajouter les entrées HasData |
|
|
80
|
+
|
|
81
|
+
#### 4.2 Workflow obligatoire
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
┌──────────────────────────────────────────────────────────────────────────────┐
|
|
85
|
+
│ WORKFLOW SYNCHRONISATION PERMISSIONS │
|
|
86
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
87
|
+
│ │
|
|
88
|
+
│ 1. GÉNÉRER CONTROLLER │
|
|
89
|
+
│ └─→ [RequirePermission(Permissions.{Module}.View)] │
|
|
90
|
+
│ │
|
|
91
|
+
│ 2. AJOUTER À Permissions.cs (Application layer) │
|
|
92
|
+
│ └─→ public static class {Module} { ... } │
|
|
93
|
+
│ │
|
|
94
|
+
│ 3. AJOUTER À PermissionConfiguration.cs (Infrastructure layer) │
|
|
95
|
+
│ └─→ HasData(new { Path = "...", ModuleId = ..., ... }) │
|
|
96
|
+
│ │
|
|
97
|
+
│ 4. CRÉER MIGRATION EF CORE │
|
|
98
|
+
│ └─→ /efcore:migration Add{Module}Permissions │
|
|
99
|
+
│ │
|
|
100
|
+
│ 5. VALIDER COHÉRENCE │
|
|
101
|
+
│ └─→ Vérifier que TOUS les paths dans Permissions.cs │
|
|
102
|
+
│ existent dans PermissionConfiguration.cs │
|
|
103
|
+
│ │
|
|
104
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### 4.3 Template PermissionConfiguration.cs
|
|
108
|
+
|
|
109
|
+
Voir le template complet dans [templates.md](templates.md#template-permissionconfiguration-seed)
|
|
110
|
+
|
|
111
|
+
#### 4.4 Checklist de validation
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
□ Permissions.cs contient la classe {Module} avec View/Create/Update/Delete
|
|
115
|
+
□ PermissionConfiguration.cs contient les entrées HasData correspondantes
|
|
116
|
+
□ Les paths sont identiques entre les deux fichiers
|
|
117
|
+
□ Le ModuleId référence un module existant dans ModuleConfiguration.cs
|
|
118
|
+
□ Migration créée avec /efcore:migration
|
|
119
|
+
□ Migration appliquée avec /efcore:db-deploy
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## RÈGLES ABSOLUES - SÉCURITÉ
|
|
125
|
+
|
|
126
|
+
### 1. Logs Critiques (OBLIGATOIRE)
|
|
127
|
+
|
|
128
|
+
| Événement | Niveau | Pattern |
|
|
129
|
+
|-----------|--------|---------|
|
|
130
|
+
| Login échoué | `Critical` | `LogCritical("Login attempt on locked account...")` |
|
|
131
|
+
| Permission refusée | `Critical` | Auto via `SecurityAuditMiddleware` |
|
|
132
|
+
| Compte verrouillé | `Critical` | `LogCritical("Account locked...")` |
|
|
133
|
+
| Password change | `Warning` | `LogWarning("Password changed...")` |
|
|
134
|
+
| Création/MAJ | `Information` | `LogInformation("User {User} creating...")` |
|
|
135
|
+
| Suppression | `Warning` | `LogWarning("User {User} deleting...")` |
|
|
136
|
+
|
|
137
|
+
### 2. Protection Comptes Système (OBLIGATOIRE)
|
|
138
|
+
|
|
139
|
+
```csharp
|
|
140
|
+
// TOUJOURS vérifier avant modification d'entité User-related
|
|
141
|
+
if (entity.UserType == UserType.System || entity.UserType == UserType.LocalAdmin)
|
|
142
|
+
return BadRequest(new { message = "Cannot modify system accounts" });
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 3. Permissions (OBLIGATOIRE)
|
|
146
|
+
|
|
147
|
+
```csharp
|
|
148
|
+
// TOUJOURS utiliser les constantes Permissions.*
|
|
149
|
+
[RequirePermission(Permissions.Support.Tickets.View)] // ✅ Correct
|
|
150
|
+
[RequirePermission("platform.support.tickets.read")] // ❌ Éviter strings
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 4. Cache Invalidation (SI rôles/permissions)
|
|
154
|
+
|
|
155
|
+
```csharp
|
|
156
|
+
// Après modification de rôle ou permission
|
|
157
|
+
await _permissionService.InvalidateUserPermissionsCacheAsync(userId, ct);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## RÉFÉRENCE RAPIDE
|
|
163
|
+
|
|
164
|
+
### Services à Injecter
|
|
165
|
+
|
|
166
|
+
| Service | Usage | Obligatoire |
|
|
167
|
+
|---------|-------|-------------|
|
|
168
|
+
| `IApplicationDbContext` | Accès DB | ✅ Toujours |
|
|
169
|
+
| `ICurrentUserService` | User courant | ✅ Toujours |
|
|
170
|
+
| `ILogger<T>` | Logging | ✅ Toujours |
|
|
171
|
+
| `IPermissionService` | Cache permissions | Si roles/permissions |
|
|
172
|
+
| `IPasswordService` | Hash passwords | Si auth |
|
|
173
|
+
| `IJwtService` | Tokens JWT | Si auth |
|
|
174
|
+
| `IUserSessionService` | Sessions | Si auth |
|
|
175
|
+
| `INotificationService` | Notifications | Si notifications |
|
|
176
|
+
|
|
177
|
+
### ProducesResponseType (OBLIGATOIRE)
|
|
178
|
+
|
|
179
|
+
```csharp
|
|
180
|
+
[ProducesResponseType(typeof(ItemDto), StatusCodes.Status200OK)]
|
|
181
|
+
[ProducesResponseType(StatusCodes.Status401Unauthorized)] // Si [Authorize]
|
|
182
|
+
[ProducesResponseType(StatusCodes.Status403Forbidden)] // Si [RequirePermission]
|
|
183
|
+
[ProducesResponseType(StatusCodes.Status404NotFound)] // Si GET by ID
|
|
184
|
+
[ProducesResponseType(StatusCodes.Status400BadRequest)] // Si validation
|
|
185
|
+
[ProducesResponseType(StatusCodes.Status409Conflict)] // Si unique constraint
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## USER PATH TRACKING
|
|
191
|
+
|
|
192
|
+
> **IMPORTANT:** Le tracking du chemin utilisateur est géré par **infrastructure**, pas par les controllers.
|
|
193
|
+
|
|
194
|
+
### Middleware Existant
|
|
195
|
+
|
|
196
|
+
`ApplicationAccessTrackingMiddleware` track automatiquement :
|
|
197
|
+
- ✅ UserId, ApplicationId, ModuleId
|
|
198
|
+
- ✅ IP Address, User Agent, Device Type
|
|
199
|
+
- ✅ AccessedAt (timestamp)
|
|
200
|
+
|
|
201
|
+
### Enrichissement Recommandé (Séparé)
|
|
202
|
+
|
|
203
|
+
Pour tracker le **temps passé** sur chaque module :
|
|
204
|
+
|
|
205
|
+
```csharp
|
|
206
|
+
// Dans ApplicationAccess entity - AJOUTER :
|
|
207
|
+
public DateTime? LeftAt { get; private set; }
|
|
208
|
+
public TimeSpan? Duration => LeftAt.HasValue ? LeftAt - AccessedAt : null;
|
|
209
|
+
|
|
210
|
+
// Dans middleware - AJOUTER :
|
|
211
|
+
// 1. Au début de requête: créer/identifier session
|
|
212
|
+
// 2. À la fin de requête: calculer durée ou marquer "navigation away"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
→ Ceci est un **enhancement infrastructure**, pas un controller concern.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## TESTS POSTMAN
|
|
220
|
+
|
|
221
|
+
Chaque controller doit avoir des tests couvrant :
|
|
222
|
+
|
|
223
|
+
| Test | User | Status Attendu |
|
|
224
|
+
|------|------|----------------|
|
|
225
|
+
| GET list | SuperAdmin | 200 |
|
|
226
|
+
| GET list | NoPerm | 403 |
|
|
227
|
+
| GET list | Anonymous | 401 |
|
|
228
|
+
| POST create | ReadOnly | 403 |
|
|
229
|
+
| POST create | WithPerm | 201 |
|
|
230
|
+
| DELETE | ReadOnly | 403 |
|
|
231
|
+
|
|
232
|
+
→ Templates dans `postman-templates.md`
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## FICHIERS ASSOCIÉS
|
|
237
|
+
|
|
238
|
+
- **Templates Controller:** [templates.md](templates.md)
|
|
239
|
+
- **Templates Postman:** [postman-templates.md](postman-templates.md)
|
|
240
|
+
- **Commande complète:** `.claude/commands/controller-create.md`
|