@atlashub/smartstack-cli 1.4.1 → 1.5.1
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 +5 -1
- package/.documentation/apex.html +5 -1
- package/.documentation/business-analyse.html +5 -1
- package/.documentation/commands.html +5 -1
- package/.documentation/css/styles.css +2168 -2168
- package/.documentation/efcore.html +5 -1
- package/.documentation/gitflow.html +5 -1
- package/.documentation/hooks.html +5 -1
- package/.documentation/index.html +5 -1
- package/.documentation/init.html +565 -0
- package/.documentation/installation.html +92 -6
- package/.documentation/js/app.js +794 -794
- package/.documentation/ralph-loop.html +534 -530
- package/.documentation/test-web.html +5 -1
- package/dist/index.js +817 -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 +567 -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,563 +1,563 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: application
|
|
3
|
-
description: |
|
|
4
|
-
Crée des applications/modules SmartStack full-stack.
|
|
5
|
-
Utiliser ce skill quand:
|
|
6
|
-
- L'utilisateur demande de créer une application, un module, ou un context
|
|
7
|
-
- L'utilisateur mentionne "nouveau module", "nouvelle application", "ajouter une fonctionnalité"
|
|
8
|
-
- L'utilisateur veut étendre la navigation avec de nouvelles entrées
|
|
9
|
-
Scope: Context → Application → Module → Section (tous niveaux)
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## STRATÉGIE MODÈLES
|
|
13
|
-
|
|
14
|
-
| Phase | Modèle | Coût estimé |
|
|
15
|
-
|-------|--------|-------------|
|
|
16
|
-
| Analyse & Planning | **Opus** | ~$0.15 |
|
|
17
|
-
| Génération code | **Sonnet** | ~$0.25 |
|
|
18
|
-
| Validation architecture | **Opus** | ~$0.10 |
|
|
19
|
-
| **Total** | | **~$0.50** |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
# Skill Application SmartStack
|
|
24
|
-
|
|
25
|
-
> **Synergie Skill/Commande:**
|
|
26
|
-
> - **Skill** (`.claude/skills/application/`) → Invocation automatique par Claude
|
|
27
|
-
> - **Commande** (`/application:create`) → Invocation manuelle par l'utilisateur
|
|
28
|
-
> - Templates partagés dans `.claude/skills/application/templates-*.md`
|
|
29
|
-
|
|
30
|
-
## QUAND CE SKILL S'ACTIVE
|
|
31
|
-
|
|
32
|
-
Claude invoque automatiquement ce skill quand il détecte :
|
|
33
|
-
|
|
34
|
-
| Déclencheur | Exemple |
|
|
35
|
-
|-------------|---------|
|
|
36
|
-
| Demande explicite | "Crée un module pour gérer les produits" |
|
|
37
|
-
| Nouvelle fonctionnalité | "Il faut ajouter la gestion des commandes" |
|
|
38
|
-
| Extension navigation | "Ajoute une application CRM dans business" |
|
|
39
|
-
| Mots-clés | "nouveau module", "nouvelle application", "ajouter un context" |
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## ARCHITECTURE EN COUCHES (OBLIGATOIRE)
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
47
|
-
│ ARCHITECTURE SMARTSTACK │
|
|
48
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
49
|
-
│ │
|
|
50
|
-
│ ┌──────────────┐ │
|
|
51
|
-
│ │ WEB (React) │ ← Pages, Components, Hooks, i18n │
|
|
52
|
-
│ └──────┬───────┘ │
|
|
53
|
-
│ │ HTTP (API calls via apiClient) │
|
|
54
|
-
│ ▼ │
|
|
55
|
-
│ ┌──────────────┐ │
|
|
56
|
-
│ │ API (.NET) │ ← Controllers, DTOs, Validation │
|
|
57
|
-
│ └──────┬───────┘ │
|
|
58
|
-
│ │ DI (Services) │
|
|
59
|
-
│ ▼ │
|
|
60
|
-
│ ┌──────────────┐ │
|
|
61
|
-
│ │ Application │ ← Interfaces, Models, Commands/Queries │
|
|
62
|
-
│ └──────┬───────┘ │
|
|
63
|
-
│ │ DI (Implementations) │
|
|
64
|
-
│ ▼ │
|
|
65
|
-
│ ┌──────────────┐ │
|
|
66
|
-
│ │Infrastructure │ ← EF Core, Services, Configurations │
|
|
67
|
-
│ └──────┬───────┘ │
|
|
68
|
-
│ │ EF Core │
|
|
69
|
-
│ ▼ │
|
|
70
|
-
│ ┌──────────────┐ │
|
|
71
|
-
│ │ Database │ ← SQL Server (schemas: nav, auth, usr, etc.) │
|
|
72
|
-
│ └──────────────┘ │
|
|
73
|
-
│ │
|
|
74
|
-
│ ❌ INTERDIT: WEB → Infrastructure (accès DB direct) │
|
|
75
|
-
│ ❌ INTERDIT: WEB → Domain (manipulation directe) │
|
|
76
|
-
│ ✅ OBLIGATOIRE: WEB → API → Application → Infrastructure │
|
|
77
|
-
│ │
|
|
78
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Validation Architecture Active
|
|
82
|
-
|
|
83
|
-
Le skill **DOIT** vérifier que le code généré ne viole pas l'architecture :
|
|
84
|
-
- Aucun import de `SmartStack.Infrastructure` dans les fichiers React
|
|
85
|
-
- Aucun appel SQL direct depuis le frontend
|
|
86
|
-
- Tous les appels API passent par `apiClient`
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## WORKFLOW AUTOMATIQUE
|
|
91
|
-
|
|
92
|
-
### ÉTAPE 1: DÉTECTION DU NIVEAU
|
|
93
|
-
|
|
94
|
-
| Indice | → Niveau |
|
|
95
|
-
|--------|----------|
|
|
96
|
-
| "context", "espace", "workspace" | Context |
|
|
97
|
-
| "application", "app", "module principal" | Application |
|
|
98
|
-
| "module", "fonctionnalité", "page" | Module |
|
|
99
|
-
| "section", "sous-menu", "onglet" | Section |
|
|
100
|
-
|
|
101
|
-
### ÉTAPE 2: EXTRACTION DES PARAMÈTRES
|
|
102
|
-
|
|
103
|
-
| Paramètre | Source | Exemple |
|
|
104
|
-
|-----------|--------|---------|
|
|
105
|
-
| `$LEVEL` | Détection | `context`, `application`, `module`, `section` |
|
|
106
|
-
| `$PARENT` | Context existant | `platform`, `business`, `personal` |
|
|
107
|
-
| `$CODE` | Nom kebab-case | `products`, `order-management` |
|
|
108
|
-
| `$LABEL_FR` | Libellé français | `Produits`, `Gestion des commandes` |
|
|
109
|
-
| `$ICON` | Icône Lucide | `Package`, `ShoppingCart` |
|
|
110
|
-
|
|
111
|
-
### ÉTAPE 3: GÉNÉRATION FULL-STACK
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
POUR chaque niveau créé:
|
|
115
|
-
1. DB SEED (Navigation + Translations 4 langues)
|
|
116
|
-
2. PERMISSIONS - 2 FICHIERS OBLIGATOIRES:
|
|
117
|
-
a. Permissions.cs (constantes C#)
|
|
118
|
-
b. PermissionConfiguration.cs (seed data DB - HasData)
|
|
119
|
-
3. API (Controller + DTOs via /controller:create)
|
|
120
|
-
4. SERVICES (Interface + Implementation)
|
|
121
|
-
5. FRONTEND (Page + Components + Hooks)
|
|
122
|
-
6. I18N (4 fichiers JSON: fr, en, it, de)
|
|
123
|
-
7. ROUTES (App.tsx - routes imbriquées obligatoires)
|
|
124
|
-
8. PREFERENCES (Template complet)
|
|
125
|
-
9. MIGRATION (via /efcore:migration)
|
|
126
|
-
10. TESTS (via /controller:create)
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
> ⚠️ **ATTENTION:** L'étape 2 (PERMISSIONS) requiert la modification de 2 fichiers.
|
|
130
|
-
> Si PermissionConfiguration.cs n'est pas mis à jour, les permissions n'existeront pas en base de données !
|
|
131
|
-
|
|
132
|
-
### ÉTAPE 4: CHAÎNAGE AUTOMATIQUE
|
|
133
|
-
|
|
134
|
-
Le skill appelle automatiquement :
|
|
135
|
-
- `/controller:create` pour les controllers API
|
|
136
|
-
- `/efcore:migration` pour les migrations DB
|
|
137
|
-
- `/ui-components` pour les pages avec listes/grilles (EntityCard, DataTable)
|
|
138
|
-
|
|
139
|
-
### ⚠️ RÈGLE UI-COMPONENTS (OBLIGATOIRE)
|
|
140
|
-
|
|
141
|
-
Lors de la création de pages avec affichage d'entités :
|
|
142
|
-
1. **TOUJOURS** utiliser `EntityCard` pour les cards d'entités
|
|
143
|
-
2. **TOUJOURS** utiliser `DataTable` pour les tableaux
|
|
144
|
-
3. **JAMAIS** créer de cards manuelles avec des divs
|
|
145
|
-
|
|
146
|
-
Voir le skill `/ui-components` pour les patterns détaillés.
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## PRÉFÉRENCES UTILISATEUR (OBLIGATOIRE)
|
|
151
|
-
|
|
152
|
-
Chaque module **DOIT** implémenter le template complet de préférences :
|
|
153
|
-
|
|
154
|
-
| Préférence | Description | Stockage |
|
|
155
|
-
|------------|-------------|----------|
|
|
156
|
-
| `pageSize` | Taille de page par défaut | `user.preferences.{module}.pageSize` |
|
|
157
|
-
| `sortColumn` | Colonne de tri par défaut | `user.preferences.{module}.sortColumn` |
|
|
158
|
-
| `sortDirection` | Direction du tri (asc/desc) | `user.preferences.{module}.sortDirection` |
|
|
159
|
-
| `filters` | Filtres actifs par défaut | `user.preferences.{module}.filters` |
|
|
160
|
-
| `visibleColumns` | Colonnes affichées | `user.preferences.{module}.visibleColumns` |
|
|
161
|
-
| `viewMode` | Mode d'affichage (list/grid) | `user.preferences.{module}.viewMode` |
|
|
162
|
-
|
|
163
|
-
### Hook Pattern
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
// hooks/use{Module}Preferences.ts
|
|
167
|
-
export function use{Module}Preferences() {
|
|
168
|
-
const { preferences, updatePreference } = useUserPreferences();
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
pageSize: preferences.{module}?.pageSize ?? 10,
|
|
172
|
-
sortColumn: preferences.{module}?.sortColumn ?? 'createdAt',
|
|
173
|
-
sortDirection: preferences.{module}?.sortDirection ?? 'desc',
|
|
174
|
-
filters: preferences.{module}?.filters ?? {},
|
|
175
|
-
visibleColumns: preferences.{module}?.visibleColumns ?? DEFAULT_COLUMNS,
|
|
176
|
-
viewMode: preferences.{module}?.viewMode ?? 'list',
|
|
177
|
-
|
|
178
|
-
setPageSize: (size: number) => updatePreference('{module}.pageSize', size),
|
|
179
|
-
setSortColumn: (col: string) => updatePreference('{module}.sortColumn', col),
|
|
180
|
-
// ... autres setters
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
## TRADUCTIONS (4 LANGUES OBLIGATOIRES)
|
|
188
|
-
|
|
189
|
-
### Base de données (nav.Translations)
|
|
190
|
-
|
|
191
|
-
```csharp
|
|
192
|
-
// Pour CHAQUE entité créée (Context, Application, Module, Section)
|
|
193
|
-
translations.Add(new {
|
|
194
|
-
Id = GenerateGuid(index++),
|
|
195
|
-
EntityType = NavigationEntityType.Module,
|
|
196
|
-
EntityId = moduleId,
|
|
197
|
-
LanguageCode = "fr",
|
|
198
|
-
Label = "Produits",
|
|
199
|
-
Description = "Gestion des produits",
|
|
200
|
-
CreatedAt = seedDate
|
|
201
|
-
});
|
|
202
|
-
translations.Add(new { /* ... en */ });
|
|
203
|
-
translations.Add(new { /* ... it */ });
|
|
204
|
-
translations.Add(new { /* ... de */ });
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Frontend (i18n)
|
|
208
|
-
|
|
209
|
-
```
|
|
210
|
-
web/smartstack-web/src/i18n/locales/
|
|
211
|
-
├── fr/{module}.json
|
|
212
|
-
├── en/{module}.json
|
|
213
|
-
├── it/{module}.json
|
|
214
|
-
└── de/{module}.json
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## COMPOSANTS RÉUTILISABLES
|
|
220
|
-
|
|
221
|
-
Emplacement : `components/common/`
|
|
222
|
-
|
|
223
|
-
| Type | Pattern | Exemple |
|
|
224
|
-
|------|---------|---------|
|
|
225
|
-
| Liste avec pagination | `{Module}ListView` | `ProductsListView` |
|
|
226
|
-
| Formulaire CRUD | `{Module}Form` | `ProductForm` |
|
|
227
|
-
| Détail | `{Module}Detail` | `ProductDetail` |
|
|
228
|
-
| Filtres | `{Module}Filters` | `ProductFilters` |
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
## PERMISSIONS (2 FICHIERS OBLIGATOIRES)
|
|
233
|
-
|
|
234
|
-
### ⚠️ RÈGLE CRITIQUE: DOUBLE ENREGISTREMENT DES PERMISSIONS
|
|
235
|
-
|
|
236
|
-
Les permissions doivent être ajoutées dans **2 fichiers distincts** :
|
|
237
|
-
|
|
238
|
-
| Fichier | Contenu | Obligatoire |
|
|
239
|
-
|---------|---------|-------------|
|
|
240
|
-
| `Permissions.cs` | Constantes C# | ✅ OUI |
|
|
241
|
-
| `PermissionConfiguration.cs` | Seed data DB (HasData) | ✅ OUI |
|
|
242
|
-
|
|
243
|
-
**Si l'un des deux manque, les permissions ne fonctionneront pas !**
|
|
244
|
-
|
|
245
|
-
### Fichier 1: Permissions.cs (Application Layer)
|
|
246
|
-
|
|
247
|
-
```csharp
|
|
248
|
-
// src/SmartStack.Application/Common/Authorization/Permissions.cs
|
|
249
|
-
|
|
250
|
-
public static class Business
|
|
251
|
-
{
|
|
252
|
-
public static class $APPLICATION_PASCAL
|
|
253
|
-
{
|
|
254
|
-
public const string Access = "$CONTEXT.$APPLICATION";
|
|
255
|
-
|
|
256
|
-
public static class $MODULE_PASCAL
|
|
257
|
-
{
|
|
258
|
-
public const string View = "$CONTEXT.$APPLICATION.$MODULE.read";
|
|
259
|
-
public const string Create = "$CONTEXT.$APPLICATION.$MODULE.create";
|
|
260
|
-
public const string Update = "$CONTEXT.$APPLICATION.$MODULE.update";
|
|
261
|
-
public const string Delete = "$CONTEXT.$APPLICATION.$MODULE.delete";
|
|
262
|
-
public const string Execute = "$CONTEXT.$APPLICATION.$MODULE.execute"; // Si workflow
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Fichier 2: PermissionConfiguration.cs (Infrastructure Layer)
|
|
269
|
-
|
|
270
|
-
```csharp
|
|
271
|
-
// src/SmartStack.Infrastructure/Persistence/Configurations/Navigation/PermissionConfiguration.cs
|
|
272
|
-
// Dans la méthode GetSeedData()
|
|
273
|
-
|
|
274
|
-
// Déclarer les IDs (doivent correspondre à NavigationModuleConfiguration.cs)
|
|
275
|
-
var $moduleModuleId = Guid.Parse("$MODULE_GUID");
|
|
276
|
-
|
|
277
|
-
// Ajouter dans le tableau de permissions:
|
|
278
|
-
|
|
279
|
-
// Wildcard Module
|
|
280
|
-
new {
|
|
281
|
-
Id = Guid.Parse("$PERM_WILDCARD_GUID"),
|
|
282
|
-
Path = "$CONTEXT.$APPLICATION.$MODULE.*",
|
|
283
|
-
Level = PermissionLevel.Module,
|
|
284
|
-
IsWildcard = true,
|
|
285
|
-
ModuleId = $moduleModuleId,
|
|
286
|
-
Description = "Full $MODULE_LABEL access",
|
|
287
|
-
CreatedAt = seedDate
|
|
288
|
-
},
|
|
289
|
-
// CRUD Actions
|
|
290
|
-
new {
|
|
291
|
-
Id = Guid.Parse("$PERM_READ_GUID"),
|
|
292
|
-
Path = "$CONTEXT.$APPLICATION.$MODULE.read",
|
|
293
|
-
Level = PermissionLevel.Module,
|
|
294
|
-
Action = PermissionAction.Read,
|
|
295
|
-
IsWildcard = false,
|
|
296
|
-
ModuleId = $moduleModuleId,
|
|
297
|
-
Description = "View $MODULE_LABEL",
|
|
298
|
-
CreatedAt = seedDate
|
|
299
|
-
},
|
|
300
|
-
// ... create, update, delete, execute
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### Checklist Permissions
|
|
304
|
-
|
|
305
|
-
| Vérification | Status |
|
|
306
|
-
|--------------|--------|
|
|
307
|
-
| ☐ Constantes dans Permissions.cs | |
|
|
308
|
-
| ☐ Seed data dans PermissionConfiguration.cs | |
|
|
309
|
-
| ☐ Module ID correspond à NavigationModuleConfiguration | |
|
|
310
|
-
| ☐ GUIDs aléatoires (pas séquentiels) | |
|
|
311
|
-
| ☐ Wildcard + actions CRUD | |
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## VALIDATION FINALE
|
|
316
|
-
|
|
317
|
-
### Build + Lint + Tests
|
|
318
|
-
|
|
319
|
-
```bash
|
|
320
|
-
# Backend
|
|
321
|
-
dotnet build
|
|
322
|
-
dotnet test
|
|
323
|
-
|
|
324
|
-
# Frontend
|
|
325
|
-
cd web/smartstack-web
|
|
326
|
-
npm run build
|
|
327
|
-
npm run lint
|
|
328
|
-
npm run test
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
### Checklist Automatique
|
|
332
|
-
|
|
333
|
-
| Vérification | Commande |
|
|
334
|
-
|--------------|----------|
|
|
335
|
-
| ✅ Compilation backend | `dotnet build` |
|
|
336
|
-
| ✅ Compilation frontend | `npm run build` |
|
|
337
|
-
| ✅ Lint TypeScript | `npm run lint` |
|
|
338
|
-
| ✅ Tests unitaires | `npm run test` |
|
|
339
|
-
| ✅ Architecture valide | Analyse imports |
|
|
340
|
-
| ✅ 4 langues i18n | Vérification fichiers |
|
|
341
|
-
| ✅ Préférences impl. | Vérification hook |
|
|
342
|
-
| ✅ Permissions.cs | Constantes ajoutées |
|
|
343
|
-
| ✅ PermissionConfiguration.cs | Seed data ajouté |
|
|
344
|
-
| ✅ Routes imbriquées | Pas de flat siblings |
|
|
345
|
-
| ✅ EntityCard utilisé | Pas de divs manuels |
|
|
346
|
-
|
|
347
|
-
---
|
|
348
|
-
|
|
349
|
-
## FICHIERS ASSOCIÉS
|
|
350
|
-
|
|
351
|
-
- **Templates Backend:** [templates-backend.md](templates-backend.md)
|
|
352
|
-
- **Templates Frontend:** [templates-frontend.md](templates-frontend.md)
|
|
353
|
-
- **Templates i18n:** [templates-i18n.md](templates-i18n.md)
|
|
354
|
-
- **Templates DB Seed:** [templates-seed.md](templates-seed.md)
|
|
355
|
-
- **Commande:** `.claude/commands/application-create.md`
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
|
-
## RÈGLES ABSOLUES
|
|
360
|
-
|
|
361
|
-
1. **TOUJOURS** 4 langues (FR, EN, IT, DE) - jamais moins
|
|
362
|
-
2. **TOUJOURS** respecter l'architecture en couches
|
|
363
|
-
3. **TOUJOURS** implémenter les préférences utilisateur
|
|
364
|
-
4. **TOUJOURS** utiliser `apiClient` pour les appels API
|
|
365
|
-
5. **TOUJOURS** chaîner avec `/controller:create` et `/efcore:migration`
|
|
366
|
-
6. **TOUJOURS** utiliser des routes imbriquées (nested routes) - voir templates-frontend.md
|
|
367
|
-
7. **TOUJOURS** utiliser `EntityCard` pour les cards d'entités - voir `/ui-components`
|
|
368
|
-
8. **TOUJOURS** utiliser `DataTable` pour les tableaux de données - voir `/ui-components`
|
|
369
|
-
9. **JAMAIS** d'import Infrastructure dans le frontend
|
|
370
|
-
10. **JAMAIS** de SQL direct dans le code frontend
|
|
371
|
-
11. **JAMAIS** de GUIDs séquentiels - utiliser `GenerateGuid(index)`
|
|
372
|
-
12. **JAMAIS** de routes plates (flat siblings) pour les applications multi-modules
|
|
373
|
-
13. **JAMAIS** de cards manuelles avec divs (utiliser EntityCard)
|
|
374
|
-
14. **TOUJOURS** ajouter les permissions dans Permissions.cs ET PermissionConfiguration.cs (2 fichiers)
|
|
375
|
-
15. **JAMAIS** oublier le seed data des permissions dans PermissionConfiguration.cs
|
|
376
|
-
|
|
377
|
-
---
|
|
378
|
-
|
|
379
|
-
## ROUTING (CRITIQUE - REACT ROUTER V7)
|
|
380
|
-
|
|
381
|
-
### Pattern obligatoire pour les applications multi-modules
|
|
382
|
-
|
|
383
|
-
```tsx
|
|
384
|
-
// ✅ CORRECT - Routes imbriquées avec index
|
|
385
|
-
<Route path="$APPLICATION">
|
|
386
|
-
<Route index element={<Navigate to="$DEFAULT_MODULE" replace />} />
|
|
387
|
-
<Route path="$MODULE1" element={<Module1Page />} />
|
|
388
|
-
<Route path="$MODULE2" element={<Module2Page />} />
|
|
389
|
-
</Route>
|
|
390
|
-
|
|
391
|
-
// ❌ INTERDIT - Routes plates (causent des redirections vers Home)
|
|
392
|
-
<Route path="$APPLICATION" element={<Navigate to="..." replace />} />
|
|
393
|
-
<Route path="$APPLICATION/$MODULE1" element={<Module1Page />} />
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### Raisons techniques
|
|
397
|
-
|
|
398
|
-
| Problème routes plates | Impact |
|
|
399
|
-
|------------------------|--------|
|
|
400
|
-
| Matching ambigu | React Router peut matcher la mauvaise route |
|
|
401
|
-
| Navigate absolu | Peut échouer si le contexte de route est mal résolu |
|
|
402
|
-
| Pas d'Outlet | Impossible d'avoir des layouts partagés |
|
|
403
|
-
| Redirect vers Home | Bug fréquent quand le matching échoue |
|
|
404
|
-
|
|
405
|
-
---
|
|
406
|
-
|
|
407
|
-
## INTEGRATIONS SMARTSTACK
|
|
408
|
-
|
|
409
|
-
### Skills Complementaires
|
|
410
|
-
|
|
411
|
-
Ce skill s'integre avec les skills suivants pour une experience complete :
|
|
412
|
-
|
|
413
|
-
| Skill | Quand l'utiliser | Action |
|
|
414
|
-
|-------|------------------|--------|
|
|
415
|
-
| `/notification` | Module avec alertes utilisateur | Notifications in-app + SignalR |
|
|
416
|
-
| `/workflow` | Module avec emails automatiques | Workflows + Email templates |
|
|
417
|
-
| `/ai-prompt` | Module avec assistance IA | Prompts + Validation schema |
|
|
418
|
-
| `/feature-full` | Feature complete oneshot | Orchestration de tous les skills |
|
|
419
|
-
|
|
420
|
-
### Integration Notifications
|
|
421
|
-
|
|
422
|
-
Quand le module necessite des notifications :
|
|
423
|
-
|
|
424
|
-
```csharp
|
|
425
|
-
// Dans le service, injecter INotificationService
|
|
426
|
-
public class {Module}Service : I{Module}Service
|
|
427
|
-
{
|
|
428
|
-
private readonly INotificationService _notificationService;
|
|
429
|
-
|
|
430
|
-
public async Task<{Entity}Dto> CreateAsync(...)
|
|
431
|
-
{
|
|
432
|
-
// ... creation ...
|
|
433
|
-
|
|
434
|
-
// Notification
|
|
435
|
-
await _notificationService.SendNotificationAsync(
|
|
436
|
-
_currentUser.Id,
|
|
437
|
-
NotificationType.{Entity}Created,
|
|
438
|
-
"{Entity} creee",
|
|
439
|
-
$"{entity.Name} a ete cree avec succes",
|
|
440
|
-
relatedEntityType: nameof({Entity}),
|
|
441
|
-
relatedEntityId: entity.Id,
|
|
442
|
-
actionUrl: $"/{module}/{entity.Id}");
|
|
443
|
-
|
|
444
|
-
return result;
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
```typescript
|
|
450
|
-
// Dans le hook frontend, ajouter SignalR
|
|
451
|
-
import { useSignalR } from '@/hooks/useSignalR';
|
|
452
|
-
|
|
453
|
-
export function use{Module}() {
|
|
454
|
-
const queryClient = useQueryClient();
|
|
455
|
-
|
|
456
|
-
useSignalR({
|
|
457
|
-
onNotification: (notification) => {
|
|
458
|
-
if (notification.relatedEntityType === '{Entity}') {
|
|
459
|
-
queryClient.invalidateQueries(['{module}']);
|
|
460
|
-
toast.info(notification.title);
|
|
461
|
-
}
|
|
462
|
-
},
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
### Integration Workflows
|
|
468
|
-
|
|
469
|
-
Quand le module necessite des emails automatiques :
|
|
470
|
-
|
|
471
|
-
```csharp
|
|
472
|
-
// Dans le service, injecter IWorkflowService
|
|
473
|
-
public class {Module}Service : I{Module}Service
|
|
474
|
-
{
|
|
475
|
-
private readonly IWorkflowService _workflowService;
|
|
476
|
-
|
|
477
|
-
public async Task<{Entity}Dto> CreateAsync(...)
|
|
478
|
-
{
|
|
479
|
-
// ... creation ...
|
|
480
|
-
|
|
481
|
-
// Declencher workflow email
|
|
482
|
-
await _workflowService.TriggerAsync(
|
|
483
|
-
"{entity}.created",
|
|
484
|
-
new Dictionary<string, object>
|
|
485
|
-
{
|
|
486
|
-
["entityId"] = entity.Id,
|
|
487
|
-
["entityName"] = entity.Name,
|
|
488
|
-
["creatorEmail"] = _currentUser.Email
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
return result;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
### Integration IA
|
|
497
|
-
|
|
498
|
-
Quand le module necessite une assistance IA :
|
|
499
|
-
|
|
500
|
-
```csharp
|
|
501
|
-
// Dans le service, injecter IAiCompletionService
|
|
502
|
-
public class {Module}Service : I{Module}Service
|
|
503
|
-
{
|
|
504
|
-
private readonly IAiCompletionService _aiService;
|
|
505
|
-
|
|
506
|
-
public async Task<{Entity}AnalysisResult?> AnalyzeAsync(Guid id, CancellationToken ct)
|
|
507
|
-
{
|
|
508
|
-
var entity = await _context.{Entity}s.FindAsync(id);
|
|
509
|
-
|
|
510
|
-
var result = await _aiService
|
|
511
|
-
.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
|
|
512
|
-
"{entity}-analyzer",
|
|
513
|
-
new Dictionary<string, object>
|
|
514
|
-
{
|
|
515
|
-
["entityName"] = entity.Name,
|
|
516
|
-
["entityDescription"] = entity.Description ?? ""
|
|
517
|
-
},
|
|
518
|
-
cancellationToken: ct);
|
|
519
|
-
|
|
520
|
-
return result.Success && result.IsValid ? result.Data : null;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
### Checklist Integrations
|
|
526
|
-
|
|
527
|
-
```
|
|
528
|
-
□ Module necessite des notifications ?
|
|
529
|
-
□ Ajouter NotificationType dans l'enum
|
|
530
|
-
□ Injecter INotificationService
|
|
531
|
-
□ Envoyer notifications aux moments cles
|
|
532
|
-
□ Ajouter useSignalR dans le hook frontend
|
|
533
|
-
|
|
534
|
-
□ Module necessite des emails automatiques ?
|
|
535
|
-
□ Creer le trigger (WorkflowTriggerConfiguration.cs)
|
|
536
|
-
□ Creer le workflow (WorkflowConfiguration.cs)
|
|
537
|
-
□ Creer le template email
|
|
538
|
-
□ Injecter IWorkflowService
|
|
539
|
-
□ Declencher avec TriggerAsync
|
|
540
|
-
|
|
541
|
-
□ Module necessite une assistance IA ?
|
|
542
|
-
□ Creer le prompt (via /ai-prompt)
|
|
543
|
-
□ Creer le schema de validation
|
|
544
|
-
□ Injecter IAiCompletionService
|
|
545
|
-
□ Appeler ExecutePromptAsync
|
|
546
|
-
□ Ajouter bouton IA dans le frontend
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
---
|
|
550
|
-
|
|
551
|
-
## SKILLS ET COMMANDES ASSOCIES
|
|
552
|
-
|
|
553
|
-
| Type | Nom | Usage |
|
|
554
|
-
|------|-----|-------|
|
|
555
|
-
| Skill | `/application` | Creation module (ce skill) |
|
|
556
|
-
| Skill | `/controller` | Generation controller API |
|
|
557
|
-
| Skill | `/ui-components` | Composants UI (EntityCard, DataTable) |
|
|
558
|
-
| Skill | `/notification` | Integration notifications |
|
|
559
|
-
| Skill | `/workflow` | Integration workflows/emails |
|
|
560
|
-
| Skill | `/ai-prompt` | Integration IA |
|
|
561
|
-
| Skill | `/feature-full` | Feature complete oneshot |
|
|
562
|
-
| Commande | `/efcore:migration` | Migration EF Core |
|
|
563
|
-
| Commande | `/efcore:db-deploy` | Deploiement migrations |
|
|
1
|
+
---
|
|
2
|
+
name: application
|
|
3
|
+
description: |
|
|
4
|
+
Crée des applications/modules SmartStack full-stack.
|
|
5
|
+
Utiliser ce skill quand:
|
|
6
|
+
- L'utilisateur demande de créer une application, un module, ou un context
|
|
7
|
+
- L'utilisateur mentionne "nouveau module", "nouvelle application", "ajouter une fonctionnalité"
|
|
8
|
+
- L'utilisateur veut étendre la navigation avec de nouvelles entrées
|
|
9
|
+
Scope: Context → Application → Module → Section (tous niveaux)
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## STRATÉGIE MODÈLES
|
|
13
|
+
|
|
14
|
+
| Phase | Modèle | Coût estimé |
|
|
15
|
+
|-------|--------|-------------|
|
|
16
|
+
| Analyse & Planning | **Opus** | ~$0.15 |
|
|
17
|
+
| Génération code | **Sonnet** | ~$0.25 |
|
|
18
|
+
| Validation architecture | **Opus** | ~$0.10 |
|
|
19
|
+
| **Total** | | **~$0.50** |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Skill Application SmartStack
|
|
24
|
+
|
|
25
|
+
> **Synergie Skill/Commande:**
|
|
26
|
+
> - **Skill** (`.claude/skills/application/`) → Invocation automatique par Claude
|
|
27
|
+
> - **Commande** (`/application:create`) → Invocation manuelle par l'utilisateur
|
|
28
|
+
> - Templates partagés dans `.claude/skills/application/templates-*.md`
|
|
29
|
+
|
|
30
|
+
## QUAND CE SKILL S'ACTIVE
|
|
31
|
+
|
|
32
|
+
Claude invoque automatiquement ce skill quand il détecte :
|
|
33
|
+
|
|
34
|
+
| Déclencheur | Exemple |
|
|
35
|
+
|-------------|---------|
|
|
36
|
+
| Demande explicite | "Crée un module pour gérer les produits" |
|
|
37
|
+
| Nouvelle fonctionnalité | "Il faut ajouter la gestion des commandes" |
|
|
38
|
+
| Extension navigation | "Ajoute une application CRM dans business" |
|
|
39
|
+
| Mots-clés | "nouveau module", "nouvelle application", "ajouter un context" |
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## ARCHITECTURE EN COUCHES (OBLIGATOIRE)
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
47
|
+
│ ARCHITECTURE SMARTSTACK │
|
|
48
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
49
|
+
│ │
|
|
50
|
+
│ ┌──────────────┐ │
|
|
51
|
+
│ │ WEB (React) │ ← Pages, Components, Hooks, i18n │
|
|
52
|
+
│ └──────┬───────┘ │
|
|
53
|
+
│ │ HTTP (API calls via apiClient) │
|
|
54
|
+
│ ▼ │
|
|
55
|
+
│ ┌──────────────┐ │
|
|
56
|
+
│ │ API (.NET) │ ← Controllers, DTOs, Validation │
|
|
57
|
+
│ └──────┬───────┘ │
|
|
58
|
+
│ │ DI (Services) │
|
|
59
|
+
│ ▼ │
|
|
60
|
+
│ ┌──────────────┐ │
|
|
61
|
+
│ │ Application │ ← Interfaces, Models, Commands/Queries │
|
|
62
|
+
│ └──────┬───────┘ │
|
|
63
|
+
│ │ DI (Implementations) │
|
|
64
|
+
│ ▼ │
|
|
65
|
+
│ ┌──────────────┐ │
|
|
66
|
+
│ │Infrastructure │ ← EF Core, Services, Configurations │
|
|
67
|
+
│ └──────┬───────┘ │
|
|
68
|
+
│ │ EF Core │
|
|
69
|
+
│ ▼ │
|
|
70
|
+
│ ┌──────────────┐ │
|
|
71
|
+
│ │ Database │ ← SQL Server (schemas: nav, auth, usr, etc.) │
|
|
72
|
+
│ └──────────────┘ │
|
|
73
|
+
│ │
|
|
74
|
+
│ ❌ INTERDIT: WEB → Infrastructure (accès DB direct) │
|
|
75
|
+
│ ❌ INTERDIT: WEB → Domain (manipulation directe) │
|
|
76
|
+
│ ✅ OBLIGATOIRE: WEB → API → Application → Infrastructure │
|
|
77
|
+
│ │
|
|
78
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Validation Architecture Active
|
|
82
|
+
|
|
83
|
+
Le skill **DOIT** vérifier que le code généré ne viole pas l'architecture :
|
|
84
|
+
- Aucun import de `SmartStack.Infrastructure` dans les fichiers React
|
|
85
|
+
- Aucun appel SQL direct depuis le frontend
|
|
86
|
+
- Tous les appels API passent par `apiClient`
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## WORKFLOW AUTOMATIQUE
|
|
91
|
+
|
|
92
|
+
### ÉTAPE 1: DÉTECTION DU NIVEAU
|
|
93
|
+
|
|
94
|
+
| Indice | → Niveau |
|
|
95
|
+
|--------|----------|
|
|
96
|
+
| "context", "espace", "workspace" | Context |
|
|
97
|
+
| "application", "app", "module principal" | Application |
|
|
98
|
+
| "module", "fonctionnalité", "page" | Module |
|
|
99
|
+
| "section", "sous-menu", "onglet" | Section |
|
|
100
|
+
|
|
101
|
+
### ÉTAPE 2: EXTRACTION DES PARAMÈTRES
|
|
102
|
+
|
|
103
|
+
| Paramètre | Source | Exemple |
|
|
104
|
+
|-----------|--------|---------|
|
|
105
|
+
| `$LEVEL` | Détection | `context`, `application`, `module`, `section` |
|
|
106
|
+
| `$PARENT` | Context existant | `platform`, `business`, `personal` |
|
|
107
|
+
| `$CODE` | Nom kebab-case | `products`, `order-management` |
|
|
108
|
+
| `$LABEL_FR` | Libellé français | `Produits`, `Gestion des commandes` |
|
|
109
|
+
| `$ICON` | Icône Lucide | `Package`, `ShoppingCart` |
|
|
110
|
+
|
|
111
|
+
### ÉTAPE 3: GÉNÉRATION FULL-STACK
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
POUR chaque niveau créé:
|
|
115
|
+
1. DB SEED (Navigation + Translations 4 langues)
|
|
116
|
+
2. PERMISSIONS - 2 FICHIERS OBLIGATOIRES:
|
|
117
|
+
a. Permissions.cs (constantes C#)
|
|
118
|
+
b. PermissionConfiguration.cs (seed data DB - HasData)
|
|
119
|
+
3. API (Controller + DTOs via /controller:create)
|
|
120
|
+
4. SERVICES (Interface + Implementation)
|
|
121
|
+
5. FRONTEND (Page + Components + Hooks)
|
|
122
|
+
6. I18N (4 fichiers JSON: fr, en, it, de)
|
|
123
|
+
7. ROUTES (App.tsx - routes imbriquées obligatoires)
|
|
124
|
+
8. PREFERENCES (Template complet)
|
|
125
|
+
9. MIGRATION (via /efcore:migration)
|
|
126
|
+
10. TESTS (via /controller:create)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
> ⚠️ **ATTENTION:** L'étape 2 (PERMISSIONS) requiert la modification de 2 fichiers.
|
|
130
|
+
> Si PermissionConfiguration.cs n'est pas mis à jour, les permissions n'existeront pas en base de données !
|
|
131
|
+
|
|
132
|
+
### ÉTAPE 4: CHAÎNAGE AUTOMATIQUE
|
|
133
|
+
|
|
134
|
+
Le skill appelle automatiquement :
|
|
135
|
+
- `/controller:create` pour les controllers API
|
|
136
|
+
- `/efcore:migration` pour les migrations DB
|
|
137
|
+
- `/ui-components` pour les pages avec listes/grilles (EntityCard, DataTable)
|
|
138
|
+
|
|
139
|
+
### ⚠️ RÈGLE UI-COMPONENTS (OBLIGATOIRE)
|
|
140
|
+
|
|
141
|
+
Lors de la création de pages avec affichage d'entités :
|
|
142
|
+
1. **TOUJOURS** utiliser `EntityCard` pour les cards d'entités
|
|
143
|
+
2. **TOUJOURS** utiliser `DataTable` pour les tableaux
|
|
144
|
+
3. **JAMAIS** créer de cards manuelles avec des divs
|
|
145
|
+
|
|
146
|
+
Voir le skill `/ui-components` pour les patterns détaillés.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## PRÉFÉRENCES UTILISATEUR (OBLIGATOIRE)
|
|
151
|
+
|
|
152
|
+
Chaque module **DOIT** implémenter le template complet de préférences :
|
|
153
|
+
|
|
154
|
+
| Préférence | Description | Stockage |
|
|
155
|
+
|------------|-------------|----------|
|
|
156
|
+
| `pageSize` | Taille de page par défaut | `user.preferences.{module}.pageSize` |
|
|
157
|
+
| `sortColumn` | Colonne de tri par défaut | `user.preferences.{module}.sortColumn` |
|
|
158
|
+
| `sortDirection` | Direction du tri (asc/desc) | `user.preferences.{module}.sortDirection` |
|
|
159
|
+
| `filters` | Filtres actifs par défaut | `user.preferences.{module}.filters` |
|
|
160
|
+
| `visibleColumns` | Colonnes affichées | `user.preferences.{module}.visibleColumns` |
|
|
161
|
+
| `viewMode` | Mode d'affichage (list/grid) | `user.preferences.{module}.viewMode` |
|
|
162
|
+
|
|
163
|
+
### Hook Pattern
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// hooks/use{Module}Preferences.ts
|
|
167
|
+
export function use{Module}Preferences() {
|
|
168
|
+
const { preferences, updatePreference } = useUserPreferences();
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
pageSize: preferences.{module}?.pageSize ?? 10,
|
|
172
|
+
sortColumn: preferences.{module}?.sortColumn ?? 'createdAt',
|
|
173
|
+
sortDirection: preferences.{module}?.sortDirection ?? 'desc',
|
|
174
|
+
filters: preferences.{module}?.filters ?? {},
|
|
175
|
+
visibleColumns: preferences.{module}?.visibleColumns ?? DEFAULT_COLUMNS,
|
|
176
|
+
viewMode: preferences.{module}?.viewMode ?? 'list',
|
|
177
|
+
|
|
178
|
+
setPageSize: (size: number) => updatePreference('{module}.pageSize', size),
|
|
179
|
+
setSortColumn: (col: string) => updatePreference('{module}.sortColumn', col),
|
|
180
|
+
// ... autres setters
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## TRADUCTIONS (4 LANGUES OBLIGATOIRES)
|
|
188
|
+
|
|
189
|
+
### Base de données (nav.Translations)
|
|
190
|
+
|
|
191
|
+
```csharp
|
|
192
|
+
// Pour CHAQUE entité créée (Context, Application, Module, Section)
|
|
193
|
+
translations.Add(new {
|
|
194
|
+
Id = GenerateGuid(index++),
|
|
195
|
+
EntityType = NavigationEntityType.Module,
|
|
196
|
+
EntityId = moduleId,
|
|
197
|
+
LanguageCode = "fr",
|
|
198
|
+
Label = "Produits",
|
|
199
|
+
Description = "Gestion des produits",
|
|
200
|
+
CreatedAt = seedDate
|
|
201
|
+
});
|
|
202
|
+
translations.Add(new { /* ... en */ });
|
|
203
|
+
translations.Add(new { /* ... it */ });
|
|
204
|
+
translations.Add(new { /* ... de */ });
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Frontend (i18n)
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
web/smartstack-web/src/i18n/locales/
|
|
211
|
+
├── fr/{module}.json
|
|
212
|
+
├── en/{module}.json
|
|
213
|
+
├── it/{module}.json
|
|
214
|
+
└── de/{module}.json
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## COMPOSANTS RÉUTILISABLES
|
|
220
|
+
|
|
221
|
+
Emplacement : `components/common/`
|
|
222
|
+
|
|
223
|
+
| Type | Pattern | Exemple |
|
|
224
|
+
|------|---------|---------|
|
|
225
|
+
| Liste avec pagination | `{Module}ListView` | `ProductsListView` |
|
|
226
|
+
| Formulaire CRUD | `{Module}Form` | `ProductForm` |
|
|
227
|
+
| Détail | `{Module}Detail` | `ProductDetail` |
|
|
228
|
+
| Filtres | `{Module}Filters` | `ProductFilters` |
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## PERMISSIONS (2 FICHIERS OBLIGATOIRES)
|
|
233
|
+
|
|
234
|
+
### ⚠️ RÈGLE CRITIQUE: DOUBLE ENREGISTREMENT DES PERMISSIONS
|
|
235
|
+
|
|
236
|
+
Les permissions doivent être ajoutées dans **2 fichiers distincts** :
|
|
237
|
+
|
|
238
|
+
| Fichier | Contenu | Obligatoire |
|
|
239
|
+
|---------|---------|-------------|
|
|
240
|
+
| `Permissions.cs` | Constantes C# | ✅ OUI |
|
|
241
|
+
| `PermissionConfiguration.cs` | Seed data DB (HasData) | ✅ OUI |
|
|
242
|
+
|
|
243
|
+
**Si l'un des deux manque, les permissions ne fonctionneront pas !**
|
|
244
|
+
|
|
245
|
+
### Fichier 1: Permissions.cs (Application Layer)
|
|
246
|
+
|
|
247
|
+
```csharp
|
|
248
|
+
// src/SmartStack.Application/Common/Authorization/Permissions.cs
|
|
249
|
+
|
|
250
|
+
public static class Business
|
|
251
|
+
{
|
|
252
|
+
public static class $APPLICATION_PASCAL
|
|
253
|
+
{
|
|
254
|
+
public const string Access = "$CONTEXT.$APPLICATION";
|
|
255
|
+
|
|
256
|
+
public static class $MODULE_PASCAL
|
|
257
|
+
{
|
|
258
|
+
public const string View = "$CONTEXT.$APPLICATION.$MODULE.read";
|
|
259
|
+
public const string Create = "$CONTEXT.$APPLICATION.$MODULE.create";
|
|
260
|
+
public const string Update = "$CONTEXT.$APPLICATION.$MODULE.update";
|
|
261
|
+
public const string Delete = "$CONTEXT.$APPLICATION.$MODULE.delete";
|
|
262
|
+
public const string Execute = "$CONTEXT.$APPLICATION.$MODULE.execute"; // Si workflow
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Fichier 2: PermissionConfiguration.cs (Infrastructure Layer)
|
|
269
|
+
|
|
270
|
+
```csharp
|
|
271
|
+
// src/SmartStack.Infrastructure/Persistence/Configurations/Navigation/PermissionConfiguration.cs
|
|
272
|
+
// Dans la méthode GetSeedData()
|
|
273
|
+
|
|
274
|
+
// Déclarer les IDs (doivent correspondre à NavigationModuleConfiguration.cs)
|
|
275
|
+
var $moduleModuleId = Guid.Parse("$MODULE_GUID");
|
|
276
|
+
|
|
277
|
+
// Ajouter dans le tableau de permissions:
|
|
278
|
+
|
|
279
|
+
// Wildcard Module
|
|
280
|
+
new {
|
|
281
|
+
Id = Guid.Parse("$PERM_WILDCARD_GUID"),
|
|
282
|
+
Path = "$CONTEXT.$APPLICATION.$MODULE.*",
|
|
283
|
+
Level = PermissionLevel.Module,
|
|
284
|
+
IsWildcard = true,
|
|
285
|
+
ModuleId = $moduleModuleId,
|
|
286
|
+
Description = "Full $MODULE_LABEL access",
|
|
287
|
+
CreatedAt = seedDate
|
|
288
|
+
},
|
|
289
|
+
// CRUD Actions
|
|
290
|
+
new {
|
|
291
|
+
Id = Guid.Parse("$PERM_READ_GUID"),
|
|
292
|
+
Path = "$CONTEXT.$APPLICATION.$MODULE.read",
|
|
293
|
+
Level = PermissionLevel.Module,
|
|
294
|
+
Action = PermissionAction.Read,
|
|
295
|
+
IsWildcard = false,
|
|
296
|
+
ModuleId = $moduleModuleId,
|
|
297
|
+
Description = "View $MODULE_LABEL",
|
|
298
|
+
CreatedAt = seedDate
|
|
299
|
+
},
|
|
300
|
+
// ... create, update, delete, execute
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Checklist Permissions
|
|
304
|
+
|
|
305
|
+
| Vérification | Status |
|
|
306
|
+
|--------------|--------|
|
|
307
|
+
| ☐ Constantes dans Permissions.cs | |
|
|
308
|
+
| ☐ Seed data dans PermissionConfiguration.cs | |
|
|
309
|
+
| ☐ Module ID correspond à NavigationModuleConfiguration | |
|
|
310
|
+
| ☐ GUIDs aléatoires (pas séquentiels) | |
|
|
311
|
+
| ☐ Wildcard + actions CRUD | |
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## VALIDATION FINALE
|
|
316
|
+
|
|
317
|
+
### Build + Lint + Tests
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Backend
|
|
321
|
+
dotnet build
|
|
322
|
+
dotnet test
|
|
323
|
+
|
|
324
|
+
# Frontend
|
|
325
|
+
cd web/smartstack-web
|
|
326
|
+
npm run build
|
|
327
|
+
npm run lint
|
|
328
|
+
npm run test
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Checklist Automatique
|
|
332
|
+
|
|
333
|
+
| Vérification | Commande |
|
|
334
|
+
|--------------|----------|
|
|
335
|
+
| ✅ Compilation backend | `dotnet build` |
|
|
336
|
+
| ✅ Compilation frontend | `npm run build` |
|
|
337
|
+
| ✅ Lint TypeScript | `npm run lint` |
|
|
338
|
+
| ✅ Tests unitaires | `npm run test` |
|
|
339
|
+
| ✅ Architecture valide | Analyse imports |
|
|
340
|
+
| ✅ 4 langues i18n | Vérification fichiers |
|
|
341
|
+
| ✅ Préférences impl. | Vérification hook |
|
|
342
|
+
| ✅ Permissions.cs | Constantes ajoutées |
|
|
343
|
+
| ✅ PermissionConfiguration.cs | Seed data ajouté |
|
|
344
|
+
| ✅ Routes imbriquées | Pas de flat siblings |
|
|
345
|
+
| ✅ EntityCard utilisé | Pas de divs manuels |
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## FICHIERS ASSOCIÉS
|
|
350
|
+
|
|
351
|
+
- **Templates Backend:** [templates-backend.md](templates-backend.md)
|
|
352
|
+
- **Templates Frontend:** [templates-frontend.md](templates-frontend.md)
|
|
353
|
+
- **Templates i18n:** [templates-i18n.md](templates-i18n.md)
|
|
354
|
+
- **Templates DB Seed:** [templates-seed.md](templates-seed.md)
|
|
355
|
+
- **Commande:** `.claude/commands/application-create.md`
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## RÈGLES ABSOLUES
|
|
360
|
+
|
|
361
|
+
1. **TOUJOURS** 4 langues (FR, EN, IT, DE) - jamais moins
|
|
362
|
+
2. **TOUJOURS** respecter l'architecture en couches
|
|
363
|
+
3. **TOUJOURS** implémenter les préférences utilisateur
|
|
364
|
+
4. **TOUJOURS** utiliser `apiClient` pour les appels API
|
|
365
|
+
5. **TOUJOURS** chaîner avec `/controller:create` et `/efcore:migration`
|
|
366
|
+
6. **TOUJOURS** utiliser des routes imbriquées (nested routes) - voir templates-frontend.md
|
|
367
|
+
7. **TOUJOURS** utiliser `EntityCard` pour les cards d'entités - voir `/ui-components`
|
|
368
|
+
8. **TOUJOURS** utiliser `DataTable` pour les tableaux de données - voir `/ui-components`
|
|
369
|
+
9. **JAMAIS** d'import Infrastructure dans le frontend
|
|
370
|
+
10. **JAMAIS** de SQL direct dans le code frontend
|
|
371
|
+
11. **JAMAIS** de GUIDs séquentiels - utiliser `GenerateGuid(index)`
|
|
372
|
+
12. **JAMAIS** de routes plates (flat siblings) pour les applications multi-modules
|
|
373
|
+
13. **JAMAIS** de cards manuelles avec divs (utiliser EntityCard)
|
|
374
|
+
14. **TOUJOURS** ajouter les permissions dans Permissions.cs ET PermissionConfiguration.cs (2 fichiers)
|
|
375
|
+
15. **JAMAIS** oublier le seed data des permissions dans PermissionConfiguration.cs
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## ROUTING (CRITIQUE - REACT ROUTER V7)
|
|
380
|
+
|
|
381
|
+
### Pattern obligatoire pour les applications multi-modules
|
|
382
|
+
|
|
383
|
+
```tsx
|
|
384
|
+
// ✅ CORRECT - Routes imbriquées avec index
|
|
385
|
+
<Route path="$APPLICATION">
|
|
386
|
+
<Route index element={<Navigate to="$DEFAULT_MODULE" replace />} />
|
|
387
|
+
<Route path="$MODULE1" element={<Module1Page />} />
|
|
388
|
+
<Route path="$MODULE2" element={<Module2Page />} />
|
|
389
|
+
</Route>
|
|
390
|
+
|
|
391
|
+
// ❌ INTERDIT - Routes plates (causent des redirections vers Home)
|
|
392
|
+
<Route path="$APPLICATION" element={<Navigate to="..." replace />} />
|
|
393
|
+
<Route path="$APPLICATION/$MODULE1" element={<Module1Page />} />
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Raisons techniques
|
|
397
|
+
|
|
398
|
+
| Problème routes plates | Impact |
|
|
399
|
+
|------------------------|--------|
|
|
400
|
+
| Matching ambigu | React Router peut matcher la mauvaise route |
|
|
401
|
+
| Navigate absolu | Peut échouer si le contexte de route est mal résolu |
|
|
402
|
+
| Pas d'Outlet | Impossible d'avoir des layouts partagés |
|
|
403
|
+
| Redirect vers Home | Bug fréquent quand le matching échoue |
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## INTEGRATIONS SMARTSTACK
|
|
408
|
+
|
|
409
|
+
### Skills Complementaires
|
|
410
|
+
|
|
411
|
+
Ce skill s'integre avec les skills suivants pour une experience complete :
|
|
412
|
+
|
|
413
|
+
| Skill | Quand l'utiliser | Action |
|
|
414
|
+
|-------|------------------|--------|
|
|
415
|
+
| `/notification` | Module avec alertes utilisateur | Notifications in-app + SignalR |
|
|
416
|
+
| `/workflow` | Module avec emails automatiques | Workflows + Email templates |
|
|
417
|
+
| `/ai-prompt` | Module avec assistance IA | Prompts + Validation schema |
|
|
418
|
+
| `/feature-full` | Feature complete oneshot | Orchestration de tous les skills |
|
|
419
|
+
|
|
420
|
+
### Integration Notifications
|
|
421
|
+
|
|
422
|
+
Quand le module necessite des notifications :
|
|
423
|
+
|
|
424
|
+
```csharp
|
|
425
|
+
// Dans le service, injecter INotificationService
|
|
426
|
+
public class {Module}Service : I{Module}Service
|
|
427
|
+
{
|
|
428
|
+
private readonly INotificationService _notificationService;
|
|
429
|
+
|
|
430
|
+
public async Task<{Entity}Dto> CreateAsync(...)
|
|
431
|
+
{
|
|
432
|
+
// ... creation ...
|
|
433
|
+
|
|
434
|
+
// Notification
|
|
435
|
+
await _notificationService.SendNotificationAsync(
|
|
436
|
+
_currentUser.Id,
|
|
437
|
+
NotificationType.{Entity}Created,
|
|
438
|
+
"{Entity} creee",
|
|
439
|
+
$"{entity.Name} a ete cree avec succes",
|
|
440
|
+
relatedEntityType: nameof({Entity}),
|
|
441
|
+
relatedEntityId: entity.Id,
|
|
442
|
+
actionUrl: $"/{module}/{entity.Id}");
|
|
443
|
+
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
// Dans le hook frontend, ajouter SignalR
|
|
451
|
+
import { useSignalR } from '@/hooks/useSignalR';
|
|
452
|
+
|
|
453
|
+
export function use{Module}() {
|
|
454
|
+
const queryClient = useQueryClient();
|
|
455
|
+
|
|
456
|
+
useSignalR({
|
|
457
|
+
onNotification: (notification) => {
|
|
458
|
+
if (notification.relatedEntityType === '{Entity}') {
|
|
459
|
+
queryClient.invalidateQueries(['{module}']);
|
|
460
|
+
toast.info(notification.title);
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Integration Workflows
|
|
468
|
+
|
|
469
|
+
Quand le module necessite des emails automatiques :
|
|
470
|
+
|
|
471
|
+
```csharp
|
|
472
|
+
// Dans le service, injecter IWorkflowService
|
|
473
|
+
public class {Module}Service : I{Module}Service
|
|
474
|
+
{
|
|
475
|
+
private readonly IWorkflowService _workflowService;
|
|
476
|
+
|
|
477
|
+
public async Task<{Entity}Dto> CreateAsync(...)
|
|
478
|
+
{
|
|
479
|
+
// ... creation ...
|
|
480
|
+
|
|
481
|
+
// Declencher workflow email
|
|
482
|
+
await _workflowService.TriggerAsync(
|
|
483
|
+
"{entity}.created",
|
|
484
|
+
new Dictionary<string, object>
|
|
485
|
+
{
|
|
486
|
+
["entityId"] = entity.Id,
|
|
487
|
+
["entityName"] = entity.Name,
|
|
488
|
+
["creatorEmail"] = _currentUser.Email
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Integration IA
|
|
497
|
+
|
|
498
|
+
Quand le module necessite une assistance IA :
|
|
499
|
+
|
|
500
|
+
```csharp
|
|
501
|
+
// Dans le service, injecter IAiCompletionService
|
|
502
|
+
public class {Module}Service : I{Module}Service
|
|
503
|
+
{
|
|
504
|
+
private readonly IAiCompletionService _aiService;
|
|
505
|
+
|
|
506
|
+
public async Task<{Entity}AnalysisResult?> AnalyzeAsync(Guid id, CancellationToken ct)
|
|
507
|
+
{
|
|
508
|
+
var entity = await _context.{Entity}s.FindAsync(id);
|
|
509
|
+
|
|
510
|
+
var result = await _aiService
|
|
511
|
+
.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
|
|
512
|
+
"{entity}-analyzer",
|
|
513
|
+
new Dictionary<string, object>
|
|
514
|
+
{
|
|
515
|
+
["entityName"] = entity.Name,
|
|
516
|
+
["entityDescription"] = entity.Description ?? ""
|
|
517
|
+
},
|
|
518
|
+
cancellationToken: ct);
|
|
519
|
+
|
|
520
|
+
return result.Success && result.IsValid ? result.Data : null;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Checklist Integrations
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
□ Module necessite des notifications ?
|
|
529
|
+
□ Ajouter NotificationType dans l'enum
|
|
530
|
+
□ Injecter INotificationService
|
|
531
|
+
□ Envoyer notifications aux moments cles
|
|
532
|
+
□ Ajouter useSignalR dans le hook frontend
|
|
533
|
+
|
|
534
|
+
□ Module necessite des emails automatiques ?
|
|
535
|
+
□ Creer le trigger (WorkflowTriggerConfiguration.cs)
|
|
536
|
+
□ Creer le workflow (WorkflowConfiguration.cs)
|
|
537
|
+
□ Creer le template email
|
|
538
|
+
□ Injecter IWorkflowService
|
|
539
|
+
□ Declencher avec TriggerAsync
|
|
540
|
+
|
|
541
|
+
□ Module necessite une assistance IA ?
|
|
542
|
+
□ Creer le prompt (via /ai-prompt)
|
|
543
|
+
□ Creer le schema de validation
|
|
544
|
+
□ Injecter IAiCompletionService
|
|
545
|
+
□ Appeler ExecutePromptAsync
|
|
546
|
+
□ Ajouter bouton IA dans le frontend
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## SKILLS ET COMMANDES ASSOCIES
|
|
552
|
+
|
|
553
|
+
| Type | Nom | Usage |
|
|
554
|
+
|------|-----|-------|
|
|
555
|
+
| Skill | `/application` | Creation module (ce skill) |
|
|
556
|
+
| Skill | `/controller` | Generation controller API |
|
|
557
|
+
| Skill | `/ui-components` | Composants UI (EntityCard, DataTable) |
|
|
558
|
+
| Skill | `/notification` | Integration notifications |
|
|
559
|
+
| Skill | `/workflow` | Integration workflows/emails |
|
|
560
|
+
| Skill | `/ai-prompt` | Integration IA |
|
|
561
|
+
| Skill | `/feature-full` | Feature complete oneshot |
|
|
562
|
+
| Commande | `/efcore:migration` | Migration EF Core |
|
|
563
|
+
| Commande | `/efcore:db-deploy` | Deploiement migrations |
|