@atlashub/smartstack-cli 3.28.0 → 3.30.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.
Files changed (44) hide show
  1. package/dist/index.js +6 -7
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -3
  4. package/templates/project/api.ts.template +4 -2
  5. package/templates/project/appsettings.json.template +1 -1
  6. package/templates/skills/apex/_shared.md +13 -0
  7. package/templates/skills/apex/references/post-checks.md +228 -6
  8. package/templates/skills/apex/references/smartstack-api.md +67 -17
  9. package/templates/skills/apex/references/smartstack-frontend.md +41 -1
  10. package/templates/skills/apex/references/smartstack-layers.md +40 -10
  11. package/templates/skills/apex/steps/step-02-plan.md +16 -11
  12. package/templates/skills/apex/steps/step-03-execute.md +6 -0
  13. package/templates/skills/apex/steps/step-04-examine.md +4 -2
  14. package/templates/skills/application/references/frontend-verification.md +26 -1
  15. package/templates/skills/application/steps/step-03-roles.md +1 -1
  16. package/templates/skills/application/steps/step-05-frontend.md +24 -8
  17. package/templates/skills/application/templates-frontend.md +41 -22
  18. package/templates/skills/application/templates-seed.md +53 -16
  19. package/templates/skills/business-analyse/SKILL.md +4 -2
  20. package/templates/skills/business-analyse/_shared.md +17 -4
  21. package/templates/skills/business-analyse/react/schema.md +1 -1
  22. package/templates/skills/business-analyse/references/agent-module-prompt.md +40 -11
  23. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +4 -3
  24. package/templates/skills/business-analyse/references/deploy-modes.md +1 -1
  25. package/templates/skills/business-analyse/references/handoff-file-templates.md +4 -4
  26. package/templates/skills/business-analyse/references/robustness-checks.md +12 -9
  27. package/templates/skills/business-analyse/references/spec-auto-inference.md +3 -3
  28. package/templates/skills/business-analyse/references/team-orchestration.md +57 -23
  29. package/templates/skills/business-analyse/references/ui-resource-cards.md +3 -3
  30. package/templates/skills/business-analyse/references/validation-checklist.md +21 -3
  31. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -5
  32. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +12 -0
  33. package/templates/skills/business-analyse/steps/step-03b-ui.md +14 -2
  34. package/templates/skills/business-analyse/steps/step-03c-compile.md +17 -9
  35. package/templates/skills/business-analyse/steps/step-03d-validate.md +42 -2
  36. package/templates/skills/business-analyse/steps/step-04b-analyze.md +5 -3
  37. package/templates/skills/business-analyse/steps/step-05a-handoff.md +23 -15
  38. package/templates/skills/business-analyse/templates/tpl-handoff.md +10 -8
  39. package/templates/skills/business-analyse/templates/tpl-progress.md +7 -6
  40. package/templates/skills/ralph-loop/references/category-rules.md +50 -6
  41. package/templates/skills/ralph-loop/references/compact-loop.md +16 -1
  42. package/templates/skills/ralph-loop/references/core-seed-data.md +158 -38
  43. package/templates/skills/ralph-loop/references/task-transform-legacy.md +3 -3
  44. package/templates/skills/ralph-loop/steps/step-02-execute.md +109 -1
@@ -236,16 +236,18 @@ Roles × resources × operations with full paths.
236
236
  > { "path": "business.{app}.{module}.create", "action": "create", "description": "Create new records" },
237
237
  > { "path": "business.{app}.{module}.update", "action": "update", "description": "Update existing records" },
238
238
  > { "path": "business.{app}.{module}.delete", "action": "delete", "description": "Delete records" },
239
- > { "path": "business.{app}.{module}.export", "action": "export", "description": "Export data" }
239
+ > { "path": "business.{app}.{module}.export", "action": "export", "description": "Export data" },
240
+ > { "path": "business.{app}.{module}.dashboard.read", "action": "read", "description": "View dashboard (section-level)" }
240
241
  > ],
241
242
  > "roleAssignments": [
242
- > { "role": "{App} Admin", "permissions": ["business.{app}.{module}.read", "business.{app}.{module}.create", "business.{app}.{module}.update", "business.{app}.{module}.delete", "business.{app}.{module}.export"] },
243
- > { "role": "{App} Manager", "permissions": ["business.{app}.{module}.read", "business.{app}.{module}.create", "business.{app}.{module}.update"] },
243
+ > { "role": "{App} Admin", "permissions": ["business.{app}.{module}.read", "business.{app}.{module}.create", "business.{app}.{module}.update", "business.{app}.{module}.delete", "business.{app}.{module}.export", "business.{app}.{module}.dashboard.read"] },
244
+ > { "role": "{App} Manager", "permissions": ["business.{app}.{module}.read", "business.{app}.{module}.create", "business.{app}.{module}.update", "business.{app}.{module}.dashboard.read"] },
244
245
  > { "role": "{App} Viewer", "permissions": ["business.{app}.{module}.read"] }
245
246
  > ]
246
247
  > }
247
248
  > ```
248
249
  > **STRUCTURE:** Object with 2 arrays: `permissions[]` and `roleAssignments[]`
250
+ > **Permission levels:** Module-level = `business.{app}.{module}.{action}` (4 segments). Section-level = `business.{app}.{module}.{section}.{action}` (5 segments, for sections needing distinct access like dashboard, approve, import).
249
251
  > **FORBIDDEN:** Do NOT use a flat array with `resource`/`roles` fields. Always use the nested structure above.
250
252
 
251
253
  #### 8e. Navigation
@@ -257,7 +259,7 @@ Module → Sections → Resources (levels 3-4-5 of the hierarchy).
257
259
  > {
258
260
  > "entries": [
259
261
  > { "level": "module", "code": "{module}", "labels": {"fr": "...", "en": "..."}, "route": "/business/{app}/{module}", "icon": "list" },
260
- > { "level": "section", "code": "list", "labels": {"fr": "Liste", "en": "List", "it": "Elenco", "de": "Liste"}, "route": "/business/{app}/{module}/list", "icon": "list" },
262
+ > { "level": "section", "code": "list", "labels": {"fr": "Liste", "en": "List", "it": "Elenco", "de": "Liste"}, "route": "/business/{app}/{module}", "icon": "list" },
261
263
  > { "level": "section", "code": "dashboard", "labels": {"fr": "Dashboard", "en": "Dashboard"}, "route": "/business/{app}/{module}/dashboard", "icon": "chart-bar", "isNew": true }
262
264
  > ]
263
265
  > }
@@ -274,13 +276,12 @@ Module → Sections → Resources (levels 3-4-5 of the hierarchy).
274
276
  > { "code": "{module}", "label": "{Module Name}", "icon": "list", "route": "/business/{app}/{module}", "parentCode": "{app}", "sort": 1 }
275
277
  > ],
276
278
  > "navigationSections": [
277
- > { "code": "list", "label": "Liste", "icon": "List", "route": "/business/{app}/{module}/list", "parentCode": "{module}", "permission": "business.{app}.{module}.read", "sort": 1 },
278
- > { "code": "detail", "label": "Détail", "icon": "FileText", "route": "/business/{app}/{module}/detail/:id", "parentCode": "{module}", "permission": "business.{app}.{module}.read", "sort": 2 },
279
- > { "code": "create", "label": "Créer", "icon": "Plus", "route": "/business/{app}/{module}/create", "parentCode": "{module}", "permission": "business.{app}.{module}.create", "sort": 3 }
279
+ > { "code": "list", "label": "Liste", "icon": "List", "route": "/business/{app}/{module}", "parentCode": "{module}", "permission": "business.{app}.{module}.read", "sort": 1 },
280
+ > { "code": "detail", "label": "Détail", "icon": "FileText", "route": "/business/{app}/{module}/:id", "parentCode": "{module}", "permission": "business.{app}.{module}.read", "sort": 2, "navigation": "hidden" },
281
+ > { "code": "dashboard", "label": "Dashboard", "icon": "BarChart", "route": "/business/{app}/{module}/dashboard", "parentCode": "{module}", "permission": "business.{app}.{module}.dashboard.read", "sort": 3 }
280
282
  > ],
281
283
  > "navigationResources": [
282
284
  > { "code": "{module}-grid", "type": "SmartTable", "entity": "{Entity}", "parentCode": "list", "permission": "business.{app}.{module}.read" },
283
- > { "code": "{module}-form", "type": "SmartForm", "entity": "{Entity}", "parentCode": "create", "permission": "business.{app}.{module}.create" },
284
285
  > { "code": "{module}-detail-card", "type": "DetailCard", "entity": "{Entity}", "parentCode": "detail", "permission": "business.{app}.{module}.read" }
285
286
  > ],
286
287
  > "navigationTranslations": [
@@ -291,7 +292,8 @@ Module → Sections → Resources (levels 3-4-5 of the hierarchy).
291
292
  > ],
292
293
  > "permissions": [
293
294
  > { "path": "business.{app}.{module}.read", "action": "read", "description": "View {module}" },
294
- > { "path": "business.{app}.{module}.create", "action": "create", "description": "Create {module}" }
295
+ > { "path": "business.{app}.{module}.create", "action": "create", "description": "Create {module}" },
296
+ > { "path": "business.{app}.{module}.dashboard.read", "action": "read", "description": "View {module} dashboard (section-level)" }
295
297
  > ],
296
298
  > "rolePermissions": [
297
299
  > { "role": "{App} Admin", "permissionPath": "business.{app}.{module}.*" },
@@ -305,7 +307,13 @@ Module → Sections → Resources (levels 3-4-5 of the hierarchy).
305
307
  > ```
306
308
  > **MANDATORY:** All 7 arrays must be present. Each element must be an object, NOT a string.
307
309
  > **CRITICAL:** `navigationSections` and `navigationResources` are DERIVED from `specification.sections[]` — use the transform algorithm below (section 8f-bis).
310
+ > **IMPORTANT:** `create` and `edit` are NEVER sections — they are action pages reached via buttons. Do NOT include them in `navigationSections`. Only include actual sidebar sections (list, dashboard, approve, import, etc.) and hidden route sections (detail).
308
311
  > **FORBIDDEN:** Do NOT use `navigationModule` (singular string), `permissions` as flat string array, `rolePermissions` as flat object, `permissionsConstants` as comma-separated string.
312
+ >
313
+ > **FORBIDDEN in navigation routes:**
314
+ > - `/business/{app}/{module}/list` → use `/business/{app}/{module}` (list IS the module route)
315
+ > - `/business/{app}/{module}/detail/:id` → use `/business/{app}/{module}/:id`
316
+ > - Navigation routes must match React Router paths exactly
309
317
 
310
318
  #### 8f-bis. Transform Sections into Navigation SeedData
311
319
 
@@ -15,6 +15,21 @@ next_step: steps/step-03a1-setup.md OR steps/step-04a-collect.md (conditional)
15
15
  - This step VALIDATES the specification from step-03c, writes it to feature.json, and decides loop continuation
16
16
  - ALWAYS verify specification completeness before writing
17
17
  - ALL communication in `{language}`
18
+
19
+ ## MODE DETECTION (inherited from step-03a1)
20
+
21
+ > **CRITICAL: Re-check your execution mode before proceeding.**
22
+
23
+ **IF you are running as a TEAM AGENT** (your prompt contains `PROPOSE & REVIEW` or `team-lead` as recipient):
24
+ → **NEVER** use `AskUserQuestion` in ANY section below (sections 9d, 10, 12)
25
+ → Section 9d: if validation fails, AUTO-CORRECT silently (no user options)
26
+ → Section 12: **SKIP ENTIRELY** — go directly to section 12-bis (Agent Mode)
27
+ → After writing feature.json, send `PROPOSAL_READY` to team lead via SendMessage
28
+ → NEVER present options/menus to the user — you are an autonomous agent
29
+
30
+ **IF you are running in the MAIN CONVERSATION** (classic inline mode):
31
+ → Normal interactive mode — use `AskUserQuestion` as documented
32
+ → Section 12-bis does NOT apply to you
18
33
  - **ID NAMING RULE (MANDATORY, NO EXCEPTION):**
19
34
  All IDs MUST include a module prefix to guarantee application-wide uniqueness.
20
35
  The prefix is derived from the module code initials (2-4 chars):
@@ -85,7 +100,7 @@ IF failures.length > 0:
85
100
  - Every FR has ≥1 linked BR
86
101
  - All BR references exist in analysis.businessRules
87
102
  - All actors appear in permissionMatrix
88
- - Permission paths use full format: `business.{app}.{module}.{resource}.{action}`
103
+ - Permission paths use correct format: module-level `business.{app}.{module}.{action}` or section-level `business.{app}.{module}.{section}.{action}`
89
104
  - rolePermissions paths match permissions paths
90
105
  - API routes use consistent prefix
91
106
 
@@ -167,6 +182,10 @@ if (entityAutoFixCount > 0) {
167
182
 
168
183
  #### 9d. Decision
169
184
 
185
+ > **TEAM AGENT MODE:** If running as team agent, SKIP AskUserQuestion. On FAIL → auto-correct silently. On PASS → proceed directly to section 11 (write). NEVER present options to the user.
186
+
187
+ **INLINE MODE ONLY (main conversation):**
188
+
170
189
  IF validation PASS:
171
190
  Display summary, ask client for confirmation
172
191
 
@@ -482,6 +501,10 @@ Uses the **same mapping** as step-05b-deploy.md — only difference is `moduleSp
482
501
 
483
502
  ### 12. Loop Decision
484
503
 
504
+ > **TEAM AGENT MODE: SKIP THIS ENTIRE SECTION.** If you are a team agent (your prompt contains `PROPOSE & REVIEW`), go directly to **section 12-bis** below. Section 12 is for inline mode ONLY. You MUST NOT load the next step or advance the module loop — the team lead handles orchestration.
505
+
506
+ **INLINE MODE ONLY (main conversation):**
507
+
485
508
  ```
486
509
  ba-writer.advanceModuleLoop({feature_id})
487
510
  → Increments currentModuleIndex
@@ -595,7 +618,24 @@ SendMessage({
595
618
  })
596
619
  ```
597
620
 
598
- **STOP HERE**do NOT loop to next module. The team lead handles module ordering and will spawn a new agent for the next module.
621
+ Then WAITthe team lead will send you a `shutdown_request`.
622
+ Do NOT loop to next module. The team lead handles module ordering and will spawn a new agent for the next module.
623
+
624
+ ### E. Shutdown (MANDATORY)
625
+
626
+ When you receive a `shutdown_request` from the team lead:
627
+
628
+ ```
629
+ SendMessage({
630
+ type: "shutdown_response",
631
+ request_id: "{requestId from the shutdown_request message}",
632
+ approve: true
633
+ })
634
+ ```
635
+
636
+ This terminates your process. Do NOT output any text after `shutdown_response`.
637
+
638
+ **Sequence reminder:** APPROVED → MODULE_COMPLETE → shutdown_request → shutdown_response (4 separate steps, never skip).
599
639
 
600
640
  ---
601
641
 
@@ -36,13 +36,15 @@ FOR each module in completedModules:
36
36
 
37
37
  **3b. Permission Path Format**
38
38
 
39
- Verify all permission paths follow the pattern:
40
- `business.{app}.{module}.{resource}.{action}`
39
+ Verify all permission paths follow one of these patterns:
40
+ - Module-level: `business.{app}.{module}.{action}` (4 segments)
41
+ - Section-level: `business.{app}.{module}.{section}.{action}` (5 segments)
41
42
 
42
43
  Check for:
43
44
  - Inconsistent app prefix → ERROR
44
45
  - Missing module segment → ERROR
45
- - Shortcut paths (not full format) → ERROR
46
+ - Fewer than 4 segments (shortcut paths) → ERROR
47
+ - More than 5 segments → ERROR
46
48
 
47
49
  **3c. Role Hierarchy Coherence**
48
50
 
@@ -17,7 +17,7 @@ next_step: steps/step-05b-deploy.md
17
17
  - **NEVER** invent entities/FRs/BRs not in feature.json
18
18
  - **ALL** API routes from specification.apiEndpoints (exact copy)
19
19
  - **Permission** paths from specification.permissionMatrix (full format)
20
- - **ALWAYS** generate 5 CORE SeedData task entries per module
20
+ - **ALWAYS** generate CORE SeedData entries: 2 app-level (NavigationApplication + ApplicationRoles) + per module (NavigationModule + NavigationSections + Permissions + Roles)
21
21
 
22
22
  ## YOUR TASK
23
23
 
@@ -197,7 +197,7 @@ See [references/handoff-file-templates.md](../references/handoff-file-templates.
197
197
  | **4.3 Infrastructure** | `analysis.entities[]` | EF Configurations, DbSet, DI. **DEPENDENCY:** Each EF config task MUST `dependsOn` its corresponding domain entity task. |
198
198
  | **4.4 API** | `specification.apiEndpoints[]` | Controllers with `{ContextShort}` mapping |
199
199
  | **4.5 Frontend** | `specification.uiWireframes[]` | Pages, Components, Hooks + wireframe traceability |
200
- | **4.6 SeedData** | `specification.seedDataCore` | 5 CORE + business + IClientSeedDataProvider |
200
+ | **4.6 SeedData** | `specification.seedDataCore` | 2 app-level + per module CORE (NavigationModule + NavigationSections + Permissions + Roles) + business + IClientSeedDataProvider |
201
201
  | **4.7 Tests** | All layers | Unit, Integration, Security tests |
202
202
 
203
203
  #### Route Convention (CRITICAL)
@@ -252,7 +252,7 @@ For NavigationSeedData tasks in `handoff.filesToCreate`, add:
252
252
  **Critical rules:**
253
253
  - All backend paths include `{ContextPascal}/{ApplicationName}/` hierarchy
254
254
  - Frontend pages MUST have `linkedWireframes[]` + `wireframeAcceptanceCriteria`
255
- - SeedData: 5 CORE entries ALWAYS + IClientSeedDataProvider for client projects
255
+ - SeedData: 2 app-level CORE (NavigationApplication + ApplicationRoles) + per-module CORE (NavigationModule + NavigationSections + Permissions + Roles) + IClientSeedDataProvider for client projects
256
256
  - **Acceptance Criteria Mapping:** Each task's `acceptanceCriteria` MUST be derived from its own `linkedFRs[]` entries (lookup FR → `acceptanceCriteria`). NEVER map by sequential FR index — use the task's explicit linkedFRs to resolve the correct criteria.
257
257
  - Path convention: `Persistence/Seeding/Data/` (NEVER `Data/SeedData/`)
258
258
 
@@ -462,7 +462,7 @@ const seedDataCore = {
462
462
  description: m.description,
463
463
  icon: inferIconFromModule(m) || "folder", // MUST be non-null — use sensible default
464
464
  iconType: "lucide",
465
- route: `/business/${master.metadata.application.toLowerCase()}/${m.code.toLowerCase()}`,
465
+ route: `/${contextCode}/${toKebabCase(appCode)}/${toKebabCase(m.code)}`,
466
466
  displayOrder: (i + 1) * 10
467
467
  })),
468
468
 
@@ -472,7 +472,11 @@ const seedDataCore = {
472
472
  code: s.code,
473
473
  label: s.description?.split(':')[0] || s.code,
474
474
  description: s.description || "",
475
- route: s.code === "detail" ? null : `/${s.code}`,
475
+ route: s.code === "list"
476
+ ? `/${contextCode}/${toKebabCase(appCode)}/${toKebabCase(m.code)}`
477
+ : s.code === "detail"
478
+ ? `/${contextCode}/${toKebabCase(appCode)}/${toKebabCase(m.code)}/:id`
479
+ : `/${contextCode}/${toKebabCase(appCode)}/${toKebabCase(m.code)}/${toKebabCase(s.code)}`,
476
480
  displayOrder: (j + 1) * 10,
477
481
  navigation: s.code === "detail" ? "hidden" : "visible"
478
482
  }))
@@ -500,22 +504,26 @@ const seedDataCore = {
500
504
  }));
501
505
  }),
502
506
 
503
- permissions: master.cadrage.applicationRoles.flatMap(role =>
504
- master.modules.map(m => ({
505
- role: role.role,
506
- module: m.code,
507
- pattern: role.permissionPattern.replace('*', `${m.code.toLowerCase()}.*`),
508
- level: role.level
509
- }))
510
- ),
507
+ permissions: master.modules.flatMap(m => {
508
+ const basePath = `business.${master.metadata.application.toLowerCase()}.${m.code.toLowerCase()}`;
509
+ const actions = ['read', 'create', 'update', 'delete'];
510
+ return [
511
+ { path: `${basePath}.*`, action: '*', description: `Full ${m.name || m.code} access` },
512
+ ...actions.map(action => ({
513
+ path: `${basePath}.${action}`,
514
+ action: action,
515
+ description: `${action.charAt(0).toUpperCase() + action.slice(1)} ${m.name || m.code}`
516
+ }))
517
+ ];
518
+ }),
511
519
 
512
520
  rolePermissions: master.cadrage.applicationRoles.map(role => ({
513
521
  role: role.role,
514
522
  level: role.level,
515
523
  permissions: master.modules.map(m => `business.${master.metadata.application.toLowerCase()}.${m.code.toLowerCase()}.${
516
524
  role.level === 'admin' ? '*' :
517
- role.level === 'manager' ? 'read,create,update,validate' :
518
- role.level === 'contributor' ? 'read,create,update' : 'read'
525
+ role.level === 'manager' ? 'read,create,update' :
526
+ role.level === 'contributor' ? 'read,create' : 'read'
519
527
  }`)
520
528
  })),
521
529
 
@@ -84,16 +84,17 @@ FRONTEND:
84
84
  ### 3.2 SeedData Core (CRITICAL -- without these, module is invisible and returns 403)
85
85
 
86
86
  > **Source:** `feature.json.specification.seedDataCore` (generated in step-02)
87
- > **5 mandatory files** for every new module (4 EF Core HasData + 1 Application code).
88
- > Derive content EXACTLY from `specification.seedDataCore` sections (navigationModules, navigationTranslations, permissions, rolePermissions, permissionConstants).
87
+ > **5 core files + NavigationSectionSeedData when sections are defined** for every new module.
88
+ > Derive content EXACTLY from `specification.seedDataCore` sections (navigationModules, navigationSections, navigationTranslations, permissions, rolePermissions, permissionConstants).
89
89
 
90
90
  | # | File | Layer | Content |
91
91
  |---|------|-------|---------|
92
92
  | 1 | `NavigationModuleConfiguration.cs` | Infrastructure (HasData) | Module entry in `nav_Modules` |
93
- | 2 | `NavigationTranslationConfiguration.cs` | Infrastructure (HasData) | 4 translations (fr, en, it, de) per nav entity |
94
- | 3 | `PermissionConfiguration.cs` | Infrastructure (HasData) | Wildcard + CRUD permissions in `nav_Permissions` |
95
- | 4 | `Permissions.cs` | Application (code) | Compile-time constants for `[RequirePermission]` |
96
- | 5 | `RolePermissionConfiguration.cs` | Infrastructure (HasData) | Role->Permission for {App} Admin, {App} Manager, {App} Contributor, {App} Viewer |
93
+ | 2 | `NavigationSectionSeedData.cs` | Infrastructure (HasData) | Section entries (list, dashboard, etc.) with full absolute routes. **MANDATORY when sections defined.** |
94
+ | 3 | `NavigationTranslationConfiguration.cs` | Infrastructure (HasData) | 4 translations (fr, en, it, de) per nav entity |
95
+ | 4 | `PermissionConfiguration.cs` | Infrastructure (HasData) | Wildcard + CRUD permissions in `nav_Permissions` |
96
+ | 5 | `Permissions.cs` | Application (code) | Compile-time constants for `[RequirePermission]` |
97
+ | 6 | `RolePermissionConfiguration.cs` | Infrastructure (HasData) | Role->Permission for {App} Admin, {App} Manager, {App} Contributor, {App} Viewer |
97
98
 
98
99
  ### 3.3 Frontend
99
100
 
@@ -136,7 +137,7 @@ From: `feature.specification.seedDataCore` (5 core files), `feature.specificatio
136
137
  > **IMPORTANT :** Les données des 5 fichiers SeedData Core doivent être dérivées de `specification.seedDataCore` :
137
138
  > - `navigationModules` → NavigationModuleConfiguration.cs
138
139
  > - `navigationTranslations` → NavigationTranslationConfiguration.cs
139
- > - `permissions` → PermissionConfiguration.cs (format complet : `business.{app}.{module}.{resource}.{action}`)
140
+ > - `permissions` → PermissionConfiguration.cs (module-level: `business.{app}.{module}.{action}`, section-level: `business.{app}.{module}.{section}.{action}`)
140
141
  > - `rolePermissions` → RolePermissionConfiguration.cs
141
142
  > - `permissionConstants` → Permissions.cs (PascalCase constants)
142
143
 
@@ -163,8 +164,9 @@ From: `feature.specification.seedDataCore` (5 core files), `feature.specificatio
163
164
 
164
165
  **SeedData Core (CRITICAL):**
165
166
  - [ ] Navigation module entry (HasData in NavigationModuleConfiguration.cs)
167
+ - [ ] Navigation section entries (NavigationSectionSeedData.cs — MANDATORY when sections defined, with full absolute routes)
166
168
  - [ ] Navigation translations (4 languages in NavigationTranslationConfiguration.cs)
167
- - [ ] Permissions (HasData in PermissionConfiguration.cs: wildcard + CRUD)
169
+ - [ ] Permissions (HasData in PermissionConfiguration.cs: wildcard + CRUD + section-level)
168
170
  - [ ] Permission constants (Permissions.cs in Application layer)
169
171
  - [ ] Role-Permission assignments (HasData in RolePermissionConfiguration.cs: 4 roles)
170
172
  - [ ] EF Core migration created (includes all HasData seeds)
@@ -28,12 +28,13 @@
28
28
  □ Total: X tasks
29
29
 
30
30
  [SEEDDATA-CORE] Core Configuration (MANDATORY)
31
- NavigationModuleConfiguration - Module navigation structure
32
- PermissionsConfiguration - RBAC permissions setup
33
- RolesConfiguration - Predefined roles
34
- TenantConfiguration - Test tenants
35
- UserConfiguration - Test users
36
- Total: 5 CORE tasks
31
+ NavigationApplicationSeedData - Application navigation entry (once per app)
32
+ ApplicationRolesSeedData - Application-scoped roles (once per app)
33
+ NavigationModuleSeedData - Module navigation structure (per module)
34
+ PermissionsSeedData - RBAC permissions (per module)
35
+ RolesSeedData - Role-permission mappings (per module)
36
+ {App}SeedDataProvider - IClientSeedDataProvider (4 methods)
37
+ Total: 2 app-level + 3 per-module + 1 provider
37
38
 
38
39
  [SEEDDATA] Business Reference Data
39
40
  □ Seed {Entity1} reference data
@@ -79,25 +79,50 @@ Execution sequence:
79
79
  > "PermissionsSeedData", "RolesSeedData", or "IClientSeedDataProvider":
80
80
  > **THEN read `references/core-seed-data.md`** — this is MANDATORY, DO NOT improvise.
81
81
 
82
- **Rules:**
83
- - NavigationModuleSeedData.cs: deterministic GUIDs (SHA256), 4 languages (fr, en, it, de)
84
- - PermissionsSeedData.cs: MCP `generate_permissions` first, fallback to template
85
- - RolesSeedData.cs: context-based role mapping (Admin=CRUD, Manager=CRU, Contributor=CR, Viewer=R)
86
- - SeedConstants.cs: shared deterministic GUIDs
87
- - IClientSeedDataProvider: SeedNavigationAsync + SeedPermissionsAsync + SeedRolePermissionsAsync
82
+ **Seed Data Chain (9 files minimum):**
83
+
84
+ Application-level (created ONCE, shared across modules):
85
+ - **NavigationApplicationSeedData.cs**: Application navigation entry (MUST be first). Provides ApplicationId.
86
+ - **ApplicationRolesSeedData.cs**: 4 application-scoped roles (admin, manager, contributor, viewer). Provides role entries for SeedRolesAsync().
87
+
88
+ Per-module:
89
+ - **NavigationModuleSeedData.cs**: deterministic GUIDs (SHA256), 4 languages (fr, en, it, de)
90
+ - **Permissions.cs**: Static permission constants (`Permissions.{Module}.Read`). Referenced by `[RequirePermission]`.
91
+ - **PermissionsSeedData.cs**: MCP `generate_permissions` first, fallback to template
92
+ - **RolesSeedData.cs**: code-based role-permission mapping (Admin=wildcard, Manager=CRU, Contributor=CR, Viewer=R)
93
+
94
+ Per-module (MANDATORY when `seedDataCore.navigationSections` exists in feature.json):
95
+ - **NavigationSectionSeedData**: section entries, section translations (4 languages), section-level permissions, and section-level role mappings — all within `NavigationModuleSeedData.cs`, `PermissionsSeedData.cs`, and `RolesSeedData.cs`
96
+ - Section-level permissions: wildcard + CRUD per section (same pattern as module-level)
97
+ - Section-level role mappings: Admin=wildcard, Manager=CRU, Contributor=CR, Viewer=R per section
98
+
99
+ Infrastructure:
100
+ - **SeedConstants.cs**: shared deterministic GUIDs (ApplicationId, ModuleIds)
101
+ - **{App}SeedDataProvider.cs**: implements IClientSeedDataProvider with 4 methods
88
102
  - DI: `services.AddScoped<IClientSeedDataProvider, {AppPascalName}SeedDataProvider>()`
89
103
 
104
+ **Rules:**
105
+ - IClientSeedDataProvider: SeedNavigationAsync + SeedRolesAsync + SeedPermissionsAsync + SeedRolePermissionsAsync
106
+ - Admin=wildcard(*), Manager=CRU (read+create+update), Contributor=CR (read+create), Viewer=R (read only)
107
+
90
108
  **Business seed data (DevDataSeeder):**
91
109
  - ALL seeded business entities MUST include `TenantId = {tenantGuid}`
92
110
  - Reference entities (types, categories, statuses) MUST set TenantId
93
111
  - Use deterministic TenantId from SeedConstants (NEVER hardcoded inline)
94
112
  - DevDataSeeder MUST implement `IDevDataSeeder` with idempotent `SeedAsync()` method
95
113
 
114
+ **Section route conventions (BLOCKING):**
115
+ - `list` section route = module route (e.g., `/business/human-resources/employees`) — NO `/list` suffix
116
+ - `detail` section route = module route + `/:id` (e.g., `/business/human-resources/employees/:id`) — NOT `/detail/:id`
117
+ - Other sections (dashboard, approve, import) = module route + `/{section-kebab}` (normal)
118
+ - FORBIDDEN: `/{module}/list`, `/{module}/detail/:id` — these are CRUD view modes, not sub-areas
119
+
96
120
  **FORBIDDEN:**
97
121
  - `Guid.NewGuid()` → use deterministic GUIDs
98
122
  - Empty seed data classes with only GUIDs and no seeding methods
99
123
  - Missing translations (must have all 4 languages)
100
124
  - Seeding business entities WITHOUT `TenantId`
125
+ - Navigation section routes ending in `/list` or `/detail/:id`
101
126
 
102
127
  ### POST-CHECK: Navigation translations diacritical marks
103
128
 
@@ -302,6 +327,13 @@ fi
302
327
  - Reference/lookup entities (types, categories, statuses) MUST also have controllers — they are needed for dropdowns and configuration
303
328
  - Count: `controllers created >= entities in module`. If fewer → FAIL
304
329
 
330
+ **Section-level controllers (CONDITIONAL: when `navSections[]` defined in feature.json):**
331
+ - File path: `Api/Controllers/{ContextShort}/{App}/{Section}Controller.cs`
332
+ - NavRoute attribute: `[NavRoute("{context}.{app}.{module}.{section}")]`
333
+ - Permission attribute: `[RequirePermission(Permissions.{Module}.{Section}.{Action})]`
334
+ - Route prefix: `api/{context}/{app}/{module}/{section}`
335
+ - Each section gets its own controller with CRUD endpoints scoped to the section
336
+
305
337
  **FORBIDDEN:**
306
338
  - `[Authorize]` without specific permission → use `[RequirePermission]`
307
339
  - Returning domain entities directly
@@ -374,6 +406,18 @@ fi
374
406
  - Navigation seed data Route values MUST also use kebab-case
375
407
  - The POST-CHECK in step-02 will BLOCK if frontend routes don't match backend kebab-case convention
376
408
 
409
+ **Section-level pages (CONDITIONAL: when `navSections[]` defined in feature.json):**
410
+ - Page file: `src/pages/{ContextPascal}/{AppPascal}/{Module}/{Section}Page.tsx`
411
+ - Route: nested as child of module route in App.tsx (e.g., `/business/human-resources/projects/timesheets`)
412
+ - Add to `contextRoutes.{context}[]` (Pattern A) or as nested `<Route>` (Pattern B)
413
+ - Each section page has its own route and permission check
414
+
415
+ **React Router mapping for sections:**
416
+ - `list` section → already the module's `index: true` route (NO separate `path: 'list'`)
417
+ - `detail` section → already the module's `path: ':id'` route (NO separate `path: 'detail'`)
418
+ - Other sections → `path: '{section-kebab}'` as child of module route
419
+ - FORBIDDEN frontend paths: `path: 'list'`, `path: 'detail'` — these are handled by the module's index and :id routes
420
+
377
421
  **CSS:** Variables ONLY → `bg-[var(--bg-card)]`, `text-[var(--text-primary)]`
378
422
 
379
423
  **Form error handling (MANDATORY):**
@@ -309,7 +309,22 @@ Batch: {batch.length} [{firstCategory}] → {batch.map(t => `[${t.id}] ${t.descr
309
309
  ```
310
310
  If FAIL → migration is broken → fix → rebuild → DO NOT commit
311
311
 
312
- 5bis. **Core Seed Data Integrity (BLOCKING — if seed data tasks in batch):**
312
+ 5bis. **Navigation section route CRUD suffix check (BLOCKING — if seed data tasks in batch):**
313
+ ```bash
314
+ # Detect /list or /detail/:id in navigation section routes
315
+ SEED_NAV_FILES=$(find src/ -path "*/Seeding/Data/*" -name "*NavigationSeedData.cs" 2>/dev/null)
316
+ if [ -n "$SEED_NAV_FILES" ]; then
317
+ CRUD_ROUTES=$(grep -rn 'Route.*=.*\/list\b\|Route.*=.*\/detail' $SEED_NAV_FILES 2>/dev/null | grep -v '//.*Route')
318
+ if [ -n "$CRUD_ROUTES" ]; then
319
+ echo "BLOCKING: Navigation section routes contain /list or /detail/:id suffixes"
320
+ echo "Convention: list → module route (no suffix), detail → module route + /:id"
321
+ echo "$CRUD_ROUTES"
322
+ # FIX REQUIRED before commit
323
+ fi
324
+ fi
325
+ ```
326
+
327
+ 5ter. **Core Seed Data Integrity (BLOCKING — if seed data tasks in batch):**
313
328
  ```bash
314
329
  # Verify NavigationApplicationSeedData.cs exists
315
330
  APP_SEED=$(find . -path "*/Seeding/Data/NavigationApplicationSeedData.cs" 2>/dev/null | head -1)