@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.
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
- package/templates/project/api.ts.template +4 -2
- package/templates/project/appsettings.json.template +1 -1
- package/templates/skills/apex/_shared.md +13 -0
- package/templates/skills/apex/references/post-checks.md +228 -6
- package/templates/skills/apex/references/smartstack-api.md +67 -17
- package/templates/skills/apex/references/smartstack-frontend.md +41 -1
- package/templates/skills/apex/references/smartstack-layers.md +40 -10
- package/templates/skills/apex/steps/step-02-plan.md +16 -11
- package/templates/skills/apex/steps/step-03-execute.md +6 -0
- package/templates/skills/apex/steps/step-04-examine.md +4 -2
- package/templates/skills/application/references/frontend-verification.md +26 -1
- package/templates/skills/application/steps/step-03-roles.md +1 -1
- package/templates/skills/application/steps/step-05-frontend.md +24 -8
- package/templates/skills/application/templates-frontend.md +41 -22
- package/templates/skills/application/templates-seed.md +53 -16
- package/templates/skills/business-analyse/SKILL.md +4 -2
- package/templates/skills/business-analyse/_shared.md +17 -4
- package/templates/skills/business-analyse/react/schema.md +1 -1
- package/templates/skills/business-analyse/references/agent-module-prompt.md +11 -9
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +4 -3
- package/templates/skills/business-analyse/references/deploy-modes.md +1 -1
- package/templates/skills/business-analyse/references/handoff-file-templates.md +4 -4
- package/templates/skills/business-analyse/references/robustness-checks.md +12 -9
- package/templates/skills/business-analyse/references/spec-auto-inference.md +3 -3
- package/templates/skills/business-analyse/references/ui-resource-cards.md +3 -3
- package/templates/skills/business-analyse/references/validation-checklist.md +21 -3
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -5
- package/templates/skills/business-analyse/steps/step-03b-ui.md +2 -2
- package/templates/skills/business-analyse/steps/step-03c-compile.md +17 -9
- package/templates/skills/business-analyse/steps/step-03d-validate.md +1 -1
- package/templates/skills/business-analyse/steps/step-04b-analyze.md +5 -3
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +23 -15
- package/templates/skills/business-analyse/templates/tpl-handoff.md +10 -8
- package/templates/skills/business-analyse/templates/tpl-progress.md +7 -6
- package/templates/skills/ralph-loop/references/category-rules.md +50 -6
- package/templates/skills/ralph-loop/references/compact-loop.md +16 -1
- package/templates/skills/ralph-loop/references/core-seed-data.md +158 -38
- package/templates/skills/ralph-loop/references/task-transform-legacy.md +3 -3
- 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,
|
|
135
|
+
- i18n keys (4 languages: fr, en, it, de)
|
|
136
136
|
- API endpoints summary
|
|
137
137
|
|
|
138
|
-
**CRITICAL for seed data —
|
|
139
|
-
1.
|
|
140
|
-
2.
|
|
141
|
-
3.
|
|
142
|
-
4.
|
|
143
|
-
5.
|
|
144
|
-
6.
|
|
145
|
-
7.
|
|
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,
|
|
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}.{
|
|
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,
|
|
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
|
|
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:
|
|
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.
|
|
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 (
|
|
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}.{
|
|
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 (
|
|
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/
|
|
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
|
|
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. `
|
|
82
|
-
3. `
|
|
83
|
-
4. `
|
|
84
|
-
5. `
|
|
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}
|
|
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}/
|
|
101
|
-
- **Back button**: detail header → `/business/{app}/{module}
|
|
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}
|
|
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}
|
|
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}
|
|
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
|
|
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,
|
|
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": "
|
|
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,
|
|
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,
|
|
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}
|
|
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}
|
|
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}
|
|
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}
|
|
278
|
-
> { "code": "detail", "label": "Détail", "icon": "FileText", "route": "/business/{app}/{module}
|
|
279
|
-
> { "code": "
|
|
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
|
|
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
|
|
40
|
-
`business.{app}.{module}.{
|
|
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
|
-
-
|
|
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
|
|
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` |
|
|
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:
|
|
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:
|
|
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 === "
|
|
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.
|
|
504
|
-
master.
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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
|
|
518
|
-
role.level === 'contributor' ? 'read,create
|
|
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
|
|
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 | `
|
|
94
|
-
| 3 | `
|
|
95
|
-
| 4 | `
|
|
96
|
-
| 5 | `
|
|
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 (
|
|
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
|
-
□
|
|
32
|
-
□
|
|
33
|
-
□
|
|
34
|
-
□
|
|
35
|
-
□
|
|
36
|
-
|
|
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
|