@atlashub/smartstack-cli 3.28.0 → 3.29.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 (42) 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 +11 -9
  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/ui-resource-cards.md +3 -3
  29. package/templates/skills/business-analyse/references/validation-checklist.md +21 -3
  30. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -5
  31. package/templates/skills/business-analyse/steps/step-03b-ui.md +2 -2
  32. package/templates/skills/business-analyse/steps/step-03c-compile.md +17 -9
  33. package/templates/skills/business-analyse/steps/step-03d-validate.md +1 -1
  34. package/templates/skills/business-analyse/steps/step-04b-analyze.md +5 -3
  35. package/templates/skills/business-analyse/steps/step-05a-handoff.md +23 -15
  36. package/templates/skills/business-analyse/templates/tpl-handoff.md +10 -8
  37. package/templates/skills/business-analyse/templates/tpl-progress.md +7 -6
  38. package/templates/skills/ralph-loop/references/category-rules.md +50 -6
  39. package/templates/skills/ralph-loop/references/compact-loop.md +16 -1
  40. package/templates/skills/ralph-loop/references/core-seed-data.md +158 -38
  41. package/templates/skills/ralph-loop/references/task-transform-legacy.md +3 -3
  42. package/templates/skills/ralph-loop/steps/step-02-execute.md +109 -1
@@ -132,17 +132,19 @@ Execute ALL compilation sections:
132
132
  - Functional Requirements
133
133
  - Permission matrix (CRUD per entity + module admin)
134
134
  - Navigation seed data (7 arrays — CRITICAL)
135
- - i18n keys (4 languages: fr, en, nl, de)
135
+ - i18n keys (4 languages: fr, en, it, de)
136
136
  - API endpoints summary
137
137
 
138
- **CRITICAL for seed data — 7 mandatory arrays:**
139
- 1. navigationModules (1 entry)
140
- 2. navigationSections (1 per section)
141
- 3. navigationResources (1+ per section)
142
- 4. navigationTranslations (4 languages × all entries)
143
- 5. permissions (CRUD per entity)
144
- 6. rolePermissions (admin=all, manager=most, contributor=create+read+update, viewer=read)
145
- 7. permissionConstants (C# constant names)
138
+ **CRITICAL for seed data — 9 mandatory arrays:**
139
+ 1. navigationApplications (1 entry — application-level, created ONCE per app)
140
+ 2. applicationRoles (4 entries — admin, manager, contributor, viewer)
141
+ 3. navigationModules (1 entry per module)
142
+ 4. navigationSections (1 per section)
143
+ 5. navigationResources (1+ per section)
144
+ 6. navigationTranslations (4 languages × all entries)
145
+ 7. permissions (wildcard + CRUD per module — {path, action, description} format)
146
+ 8. rolePermissions (admin=wildcard, manager=CRU, contributor=CR, viewer=R)
147
+ 9. permissionConstants (C# constant names)
146
148
 
147
149
  ### Step 5: Validate & Propose (step-03d-validate.md)
148
150
  Load: `templates/skills/business-analyse/steps/step-03d-validate.md`
@@ -23,7 +23,7 @@
23
23
  | `specification.seedDataBusiness` | YES | Must define reference/lookup seed data for testing (types, categories, statuses) |
24
24
  | `specification.gherkinScenarios` | YES | Must be `{feature, scenarios[]}` (NOT flat array) |
25
25
  | `specification.navigation` | YES | Must have entries[] |
26
- | `specification.i18nKeys[]` | YES | Must have >=1 key with fr, en, nl, de |
26
+ | `specification.i18nKeys[]` | YES | Must have >=1 key with fr, en, it, de |
27
27
  | `validation` | YES | Must have completenessChecks, consistencyChecks, semanticChecks, decision |
28
28
 
29
29
  ## B. Field Name Conformity
@@ -46,7 +46,8 @@
46
46
  | BR | `BR-(VAL\|CALC\|WF\|SEC\|DATA)-{PREFIX}-\d{3}` | BR-VAL-RM-001 |
47
47
  | UC | `UC-{PREFIX}-\d{3}` | UC-RM-001 |
48
48
  | FR | `FR-{PREFIX}-\d{3}` | FR-RM-001 |
49
- | Permissions | `business.{app}.{module}.{resource}.{action}` | business.freebike.repairs.create |
49
+ | Permissions (module) | `business.{app}.{module}.{action}` | business.freebike.repairs.create |
50
+ | Permissions (section) | `business.{app}.{module}.{section}.{action}` | business.freebike.repairs.dashboard.read |
50
51
 
51
52
  ## D. Cross-Module ID Uniqueness
52
53
 
@@ -71,7 +72,7 @@ FOR each region: IF missing position or components[] -> ERROR
71
72
 
72
73
  ```
73
74
  FOR each navigationModules[].code:
74
- FOR each language in [fr, en, nl, de]:
75
+ FOR each language in [fr, en, it, de]:
75
76
  IF NOT EXISTS navigationTranslations[] with moduleCode AND language -> ERROR
76
77
  ```
77
78
 
@@ -37,7 +37,7 @@ Focused handoff for changes:
37
37
  |-------|-----------|
38
38
  | All modules missing handoff data | Return to step-05a-handoff.md. Handoff MUST be written to each module feature.json. |
39
39
  | prd.json generation failed | Verify ss derive-prd command is installed and feature.json path is correct. |
40
- | progress.txt incomplete | Ensure all 5 CORE SeedData entries are present per module. Check topological order. |
40
+ | progress.txt incomplete | Ensure all CORE SeedData entries are present: 2 app-level (NavigationApplication + ApplicationRoles) + per module (NavigationModule + NavigationSections + Permissions + Roles). Check topological order. |
41
41
  | BA manifest not found | Create docs/business/index.json if missing. Use schema provided in section 3. |
42
42
  | Manifest entries incorrect | Verify appCode, moduleCode, and version match feature.json metadata exactly. |
43
43
  | ba-interactive.html is too small (< 100KB) | FEATURE_DATA not serialized correctly. Verify JSON structure. Re-run FEATURE_DATA build. |
@@ -90,16 +90,16 @@ From `specification.uiWireframes[]`, `specification.dashboards[]` and `analysis.
90
90
 
91
91
  ## 4.6 SeedData Files
92
92
 
93
- **OBLIGATORY: 6 CORE (1 app-level + 5 per module) + business per module:**
93
+ **OBLIGATORY: 2 app-level CORE + per module CORE (NavigationModule + NavigationSections + Permissions + Roles) + business per module:**
94
94
 
95
95
  ```json
96
96
  "seedData": [
97
97
  { "path": "src/Infrastructure/Persistence/Seeding/Data/NavigationApplicationSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.navigationApplications", "module": "shared", "description": "Application-level navigation seed data. Created ONCE per application (FIRST). Provides ApplicationId for modules and roles." },
98
+ { "path": "src/Infrastructure/Persistence/Seeding/Data/ApplicationRolesSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.rolePermissions", "module": "shared", "description": "Application-scoped role definitions (admin, manager, contributor, viewer). Created ONCE per application. Provides role entries for SeedRolesAsync()." },
98
99
  { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/NavigationModuleSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.navigationModules", "module": "{moduleCode}" },
100
+ { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/NavigationSectionSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.navigationSections", "module": "{moduleCode}", "description": "MANDATORY when sections defined. Seeds section-level navigation entries (list, dashboard, etc.) with full absolute routes." },
99
101
  { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/PermissionsSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.permissions", "module": "{moduleCode}" },
100
- { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/RolesSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.roles", "module": "{moduleCode}" },
101
- { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/TenantSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.tenants", "module": "{moduleCode}" },
102
- { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/UserSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.users", "module": "{moduleCode}" },
102
+ { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/RolesSeedData.cs", "type": "SeedData", "category": "core", "source": "specification.seedDataCore.rolePermissions", "module": "{moduleCode}" },
103
103
  { "path": "src/Infrastructure/Persistence/Seeding/Data/{ModuleName}/{Entity}SeedData.cs", "type": "SeedData", "category": "business", "source": "specification.seedDataBusiness.{module}", "module": "{moduleCode}" }
104
104
  ]
105
105
  ```
@@ -17,7 +17,7 @@ This document consolidates all robustness checks implemented across the business
17
17
 
18
18
  Ensures each module has ALL required components before being marked as "specified". Prevents incomplete modules from reaching step-04 consolidation.
19
19
 
20
- ### Checks (30 total)
20
+ ### Checks (31 total)
21
21
 
22
22
  #### SECTION 1: Data Model (3 checks)
23
23
 
@@ -50,38 +50,41 @@ Ensures each module has ALL required components before being marked as "specifie
50
50
  | # | Check | Minimum | Blocking | Rationale |
51
51
  |---|-------|---------|----------|-----------|
52
52
  | 4.1 | Permissions count | ≥5 | YES | CRUD (4) + 1 business action minimum |
53
- | 4.2 | Permission format | `business.{app}.{module}.{resource}.{action}` | YES | Wrong format breaks RBAC system |
53
+ | 4.2 | Permission format | Module: `business.{app}.{module}.{action}` or Section: `business.{app}.{module}.{section}.{action}` | YES | Wrong format breaks RBAC system |
54
54
  | 4.3 | Role permissions | All roles have ≥1 permission | YES | Roles without permissions are useless |
55
55
 
56
- #### SECTION 5: UI & Navigation (3 checks)
56
+ #### SECTION 5: UI & Navigation (4 checks)
57
57
 
58
58
  | # | Check | Minimum | Blocking | Rationale |
59
59
  |---|-------|---------|----------|-----------|
60
60
  | 5.1 | Sections count | ≥2 | YES | Modules need list + form minimum |
61
61
  | 5.2 | Wireframes count | 1 per section | YES | EVERY section MUST have wireframe |
62
62
  | 5.3 | Navigation entries | ≥1 | YES | Module must be accessible in menu |
63
+ | 5.4 | Navigation route patterns | No `/list` or `/detail/:id` suffixes | YES | list route = module route (index), detail route = module + /:id. FORBIDDEN: `/module/list`, `/module/detail/:id` |
63
64
 
64
65
  #### SECTION 6: I18N & Messages (3 checks)
65
66
 
66
67
  | # | Check | Minimum | Blocking | Rationale |
67
68
  |---|-------|---------|----------|-----------|
68
69
  | 6.1 | i18n keys count | ≥42 | YES | Entities, fields, messages, validation, navigation |
69
- | 6.2 | i18n languages | All keys have 4 languages (fr/en/nl/de) | YES | Missing translations break multi-language |
70
+ | 6.2 | i18n languages | All keys have 4 languages (fr/en/it/de) | YES | Missing translations break multi-language |
70
71
  | 6.3 | Messages count | ≥4 | YES | 1 success, 1 error, 1 warning, 1 info minimum |
71
72
 
72
73
  #### SECTION 7: Seed Data (2 checks)
73
74
 
74
75
  | # | Check | Minimum | Blocking | Rationale |
75
76
  |---|-------|---------|----------|-----------|
76
- | 7.1 | CORE seed data sections | All 5 sections present | YES | Missing CORE data breaks deployment |
77
+ | 7.1 | CORE seed data sections | All 7 sections present | YES | Missing CORE data breaks deployment |
77
78
  | 7.2 | Business seed data | Template defined | NO (WARNING) | Helps with testing |
78
79
 
79
80
  **CORE sections required:**
80
81
  1. `navigationModules`
81
- 2. `navigationTranslations`
82
- 3. `permissions`
83
- 4. `rolePermissions`
84
- 5. `permissionConstants`
82
+ 2. `navigationSections`
83
+ 3. `navigationResources`
84
+ 4. `navigationTranslations`
85
+ 5. `permissions`
86
+ 6. `rolePermissions`
87
+ 7. `permissionConstants`
85
88
 
86
89
  #### SECTION 8: API Endpoints (2 checks)
87
90
 
@@ -90,15 +90,15 @@ IF entity has lifeCycles:
90
90
  ### Detail section auto-generation
91
91
 
92
92
  When auto-generating the detail section, create:
93
- - `specification.sections[]` entry with `code: "detail"`, `navigation: "hidden"`, route `/business/{app}/{module}/detail/:id`
93
+ - `specification.sections[]` entry with `code: "detail"`, `navigation: "hidden"`, route `/business/{app}/{module}/:id`
94
94
  - `specification.uiWireframes[]` entry with `section: "detail"` and ASCII mockup showing all tabs
95
95
  - Resources: `{module}-detail-header` (DetailHeader), `{module}-detail-tabs` (TabPanel), `{module}-info-card` (DetailCard), one `{module}-{relation}-grid` per relation tab, `{module}-history` (Timeline if auditable)
96
96
 
97
97
  ### Detail page navigation wiring
98
98
 
99
99
  The detail page is NOT a sidebar entry. Navigation is handled by:
100
- - **From list**: row click action `navigate:detail` → `/business/{app}/{module}/detail/{id}`
101
- - **Back button**: detail header → `/business/{app}/{module}/list`
100
+ - **From list**: row click action `navigate:detail` → `/business/{app}/{module}/{id}`
101
+ - **Back button**: detail header → `/business/{app}/{module}`
102
102
  - **Route registration**: route MUST be registered in frontend routing with `:id` parameter
103
103
 
104
104
  ## Status/Lifecycle Enhancement
@@ -8,7 +8,7 @@
8
8
  {
9
9
  "code": "list",
10
10
  "labels": { "fr": "Liste", "en": "List", "it": "Elenco", "de": "Liste" },
11
- "route": "/business/{app}/{module}/list",
11
+ "route": "/business/{app}/{module}",
12
12
  "icon": "list",
13
13
  "permission": "business.{app}.{module}.read",
14
14
  "wireframe": "{module}-list",
@@ -81,7 +81,7 @@
81
81
  {
82
82
  "code": "detail",
83
83
  "labels": { "fr": "Détail", "en": "Detail", "it": "Dettaglio", "de": "Detail" },
84
- "route": "/business/{app}/{module}/detail/:id",
84
+ "route": "/business/{app}/{module}/:id",
85
85
  "icon": "file-text",
86
86
  "permission": "business.{app}.{module}.read",
87
87
  "wireframe": "{module}-detail",
@@ -238,7 +238,7 @@ A wireframe without `componentMapping` or `layout` will FAIL validation in step
238
238
  "type": "page",
239
239
  "regions": [
240
240
  { "id": "header", "position": "top", "components": [
241
- { "type": "BackButton", "target": "/business/{app}/{module}/list" },
241
+ { "type": "BackButton", "target": "/business/{app}/{module}" },
242
242
  { "type": "DetailHeader", "resourceRef": "{module}-detail-header" },
243
243
  { "type": "StatusBadge", "resourceRef": "{module}-status" }
244
244
  ]},
@@ -115,10 +115,10 @@ const checklist = {
115
115
  },
116
116
 
117
117
  permissionFormat: {
118
- check: "All permissions use full format: business.{app}.{module}.{resource}.{action}",
118
+ check: "All permissions use correct format: module-level business.{app}.{module}.{action} or section-level business.{app}.{module}.{section}.{action}",
119
119
  status: validatePermissionFormat() ? "PASS" : "FAIL",
120
120
  blocking: true,
121
- details: "Wrong format breaks RBAC system"
121
+ details: "Wrong format breaks RBAC system. Module-level = 4 segments, section-level = 5 segments."
122
122
  },
123
123
 
124
124
  rolePermissions: {
@@ -168,6 +168,24 @@ const checklist = {
168
168
  details: "Module must be accessible in menu"
169
169
  },
170
170
 
171
+ navigationRoutePatterns: {
172
+ check: "Navigation routes do NOT contain CRUD suffixes (/list, /detail/:id)",
173
+ status: (() => {
174
+ const allRoutes = [
175
+ ...(specification.seedDataCore?.navigationSections || []).map(s => s.route),
176
+ ...(specification.sections || []).map(s => s.route),
177
+ ...(specification.navigation?.entries || []).map(e => e.route)
178
+ ].filter(Boolean);
179
+ const forbidden = allRoutes.filter(r => r.match(/\/list$/) || r.match(/\/detail\/:id$/));
180
+ return forbidden.length === 0 ? "PASS" : "FAIL";
181
+ })(),
182
+ blocking: true,
183
+ details: "FORBIDDEN: /module/list (use /module), /module/detail/:id (use /module/:id). " +
184
+ "list route = module route (React Router index route). " +
185
+ "detail route = module route + /:id (React Router :id child). " +
186
+ "Other sections (dashboard, approve) add /{section} normally."
187
+ },
188
+
171
189
  // SECTION 6: I18N & MESSAGES (BLOCKING)
172
190
  i18nKeys: {
173
191
  minimum: 42, // Realistic minimum for a module
@@ -178,7 +196,7 @@ const checklist = {
178
196
  },
179
197
 
180
198
  i18nLanguages: {
181
- check: "All i18n keys have 4 languages (fr, en, nl, de)",
199
+ check: "All i18n keys have 4 languages (fr, en, it, de)",
182
200
  status: validateI18nCompleteness() ? "PASS" : "FAIL",
183
201
  blocking: true,
184
202
  details: "Missing translations break multi-language support"
@@ -26,7 +26,7 @@
26
26
  "id": { "type": "string", "pattern": "^UC-[A-Z]{2,4}-\\d{3}$", "description": "Module-prefixed UC ID (e.g., UC-RM-001)" },
27
27
  "name": { "type": "string" },
28
28
  "primaryActor": { "type": "string" },
29
- "permission": { "type": "string", "description": "business.{app}.{module}.{action}" },
29
+ "permission": { "type": "string", "description": "Module-level: business.{app}.{module}.{action} or section-level: business.{app}.{module}.{section}.{action}" },
30
30
  "preconditions": { "type": "array", "items": { "type": "string" } },
31
31
  "postconditions": { "type": "array", "items": { "type": "string" } },
32
32
  "mainScenario": { "type": "array", "items": { "type": "string" } },
@@ -82,7 +82,7 @@
82
82
  "type": "object",
83
83
  "required": ["path", "action"],
84
84
  "properties": {
85
- "path": { "type": "string", "description": "business.{app}.{module}.{action}" },
85
+ "path": { "type": "string", "description": "Module-level: business.{app}.{module}.{action} or section-level: business.{app}.{module}.{section}.{action}" },
86
86
  "action": { "type": "string", "enum": ["read", "create", "update", "delete", "export", "import", "admin", "*"] },
87
87
  "description": { "type": "string" }
88
88
  }
@@ -382,8 +382,36 @@
382
382
  },
383
383
  "seedDataCore": {
384
384
  "type": "object",
385
- "description": "7 mandatory SmartStack core SeedData definitions (modules, sections, resources, translations, permissions, rolePermissions, permissionConstants)",
385
+ "description": "9 mandatory SmartStack core SeedData definitions (navigationApplications, applicationRoles, modules, sections, resources, translations, permissions, rolePermissions, permissionConstants)",
386
386
  "properties": {
387
+ "navigationApplications": {
388
+ "type": "array",
389
+ "description": "Level 2 (Application) navigation entry for core.nav_Applications table. Created ONCE per application (FIRST). Provides ApplicationId for modules and roles.",
390
+ "items": {
391
+ "type": "object",
392
+ "required": ["code", "label", "icon", "route"],
393
+ "properties": {
394
+ "code": { "type": "string", "description": "Application code (PascalCase, e.g., HumanResources)" },
395
+ "label": { "type": "string", "description": "Application label in default language" },
396
+ "icon": { "type": "string", "description": "Lucide icon name" },
397
+ "route": { "type": "string", "description": "Full route path (e.g., /business/human-resources)" },
398
+ "sort": { "type": "integer", "description": "Display order" }
399
+ }
400
+ }
401
+ },
402
+ "applicationRoles": {
403
+ "type": "array",
404
+ "description": "Application-scoped role definitions (admin, manager, contributor, viewer). Created ONCE per application. Used by SeedRolesAsync() in IClientSeedDataProvider.",
405
+ "items": {
406
+ "type": "object",
407
+ "required": ["code", "name", "permissions"],
408
+ "properties": {
409
+ "code": { "type": "string", "description": "Role code (e.g., admin, manager, contributor, viewer)" },
410
+ "name": { "type": "string", "description": "Human-readable role name" },
411
+ "permissions": { "type": "string", "description": "Permission level: wildcard(*), CRU, CR, R" }
412
+ }
413
+ }
414
+ },
387
415
  "navigationModules": {
388
416
  "type": "array",
389
417
  "items": {
@@ -406,7 +434,7 @@
406
434
  "type": "object",
407
435
  "required": ["code", "label", "icon", "route", "parentCode", "permission"],
408
436
  "properties": {
409
- "code": { "type": "string", "description": "Section code (list, detail, create, dashboard)" },
437
+ "code": { "type": "string", "description": "Section code (list, detail, dashboard, approve, import, etc.)" },
410
438
  "label": { "type": "string", "description": "Section label in default language (fr)" },
411
439
  "icon": { "type": "string", "description": "Lucide icon name" },
412
440
  "route": { "type": "string", "description": "Full route path" },
@@ -486,7 +514,7 @@
486
514
  "type": "object",
487
515
  "required": ["code", "labels", "route", "permission", "wireframe", "useCases", "resources"],
488
516
  "properties": {
489
- "code": { "type": "string", "description": "Section code (kebab-case: list, detail, create, dashboard)" },
517
+ "code": { "type": "string", "description": "Section code (kebab-case: list, detail, dashboard, approve, import, etc.)" },
490
518
  "labels": {
491
519
  "type": "object",
492
520
  "properties": {
@@ -243,7 +243,7 @@ A wireframe without `componentMapping` or `layout` will FAIL validation in step
243
243
 
244
244
  Adaptation rules for the detail mockup:
245
245
  - **Header**: entity code + name + status badge (if lifeCycles) + action buttons (edit, delete)
246
- - **Back button**: navigates to `/business/{app}/{module}/list`
246
+ - **Back button**: navigates to `/business/{app}/{module}`
247
247
  - **Tabs**: one per identified tab (Info + relations + history)
248
248
  - **Info tab content**: all entity attributes as label:value pairs (read-only by default)
249
249
  - **Edit button**: toggles the Info tab into SmartForm edit mode
@@ -261,7 +261,7 @@ Transition buttons are contextual: only show actions allowed from the current st
261
261
  5. **Store** in `specification.uiWireframes[]` with `section: "detail"`.
262
262
  See [references/ui-resource-cards.md](../references/ui-resource-cards.md) "Detail Page Wireframe" for exact JSON format.
263
263
 
264
- 6. **Create the detail section** in `specification.sections[]` with `navigation: "hidden"` and route `/business/{app}/{module}/detail/:id`.
264
+ 6. **Create the detail section** in `specification.sections[]` with `navigation: "hidden"` and route `/business/{app}/{module}/:id`.
265
265
  See [references/ui-resource-cards.md](../references/ui-resource-cards.md) "Detail Page section" for exact JSON format.
266
266
 
267
267
  ### 3b-bis. Wireframe-to-Component Mapping
@@ -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
 
@@ -85,7 +85,7 @@ IF failures.length > 0:
85
85
  - Every FR has ≥1 linked BR
86
86
  - All BR references exist in analysis.businessRules
87
87
  - All actors appear in permissionMatrix
88
- - Permission paths use full format: `business.{app}.{module}.{resource}.{action}`
88
+ - Permission paths use correct format: module-level `business.{app}.{module}.{action}` or section-level `business.{app}.{module}.{section}.{action}`
89
89
  - rolePermissions paths match permissions paths
90
90
  - API routes use consistent prefix
91
91
 
@@ -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