@atlashub/smartstack-cli 3.36.0 → 3.38.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 +16 -24
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +201 -256
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +3 -2
- package/scripts/extract-api-endpoints.ts +325 -0
- package/scripts/extract-business-rules.ts +440 -0
- package/scripts/generate-doc-with-mock-ui.ts +804 -0
- package/scripts/health-check.sh +168 -0
- package/scripts/postinstall.js +18 -0
- package/templates/agents/ba-reader.md +9 -9
- package/templates/agents/ba-writer.md +12 -15
- package/templates/agents/code-reviewer.md +1 -1
- package/templates/agents/docs-context-reader.md +1 -1
- package/templates/agents/gitflow/merge.md +0 -4
- package/templates/agents/gitflow/pr.md +0 -4
- package/templates/agents/gitflow/start.md +30 -5
- package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +20 -20
- package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +16 -24
- package/templates/mcp-scaffolding/migrations/seed-roles.cs.hbs +2 -2
- package/templates/skills/_resources/mcp-validate-documentation-spec.md +3 -3
- package/templates/skills/_shared.md +15 -17
- package/templates/skills/ai-prompt/SKILL.md +1 -1
- package/templates/skills/ai-prompt/steps/step-00-init.md +47 -0
- package/templates/skills/apex/SKILL.md +3 -4
- package/templates/skills/apex/_shared.md +10 -20
- package/templates/skills/apex/references/analysis-methods.md +141 -0
- package/templates/skills/apex/references/challenge-questions.md +1 -21
- package/templates/skills/apex/references/core-seed-data.md +35 -57
- package/templates/skills/apex/references/examine-build-validation.md +87 -0
- package/templates/skills/apex/references/execution-frontend-gates.md +177 -0
- package/templates/skills/apex/references/execution-frontend-patterns.md +105 -0
- package/templates/skills/apex/references/execution-layer1-rules.md +96 -0
- package/templates/skills/apex/references/initialization-challenge-flow.md +110 -0
- package/templates/skills/apex/references/planning-layer-mapping.md +151 -0
- package/templates/skills/apex/references/post-checks.md +145 -40
- package/templates/skills/apex/references/smartstack-api.md +35 -51
- package/templates/skills/apex/references/smartstack-frontend.md +17 -17
- package/templates/skills/apex/references/smartstack-layers.md +38 -62
- package/templates/skills/apex/steps/step-00-init.md +14 -26
- package/templates/skills/apex/steps/step-01-analyze.md +10 -143
- package/templates/skills/apex/steps/step-02-plan.md +10 -92
- package/templates/skills/apex/steps/step-03-execute.md +47 -249
- package/templates/skills/apex/steps/step-04-examine.md +14 -78
- package/templates/skills/apex/steps/step-05-deep-review.md +2 -2
- package/templates/skills/apex/steps/step-08-run-tests.md +2 -0
- package/templates/skills/application/SKILL.md +6 -7
- package/templates/skills/application/references/backend-controller-hierarchy.md +16 -16
- package/templates/skills/application/references/backend-seeding-and-dto-output.md +83 -0
- package/templates/skills/application/references/backend-table-prefix-mapping.md +79 -0
- package/templates/skills/application/references/backend-verification.md +1 -1
- package/templates/skills/application/references/frontend-i18n-and-output.md +67 -0
- package/templates/skills/application/references/frontend-route-naming.md +117 -0
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +107 -0
- package/templates/skills/application/references/frontend-verification.md +12 -12
- package/templates/skills/application/references/init-parameter-detection.md +120 -0
- package/templates/skills/application/references/migration-checklist-troubleshooting.md +100 -0
- package/templates/skills/application/references/nav-fallback-procedure.md +5 -6
- package/templates/skills/application/references/provider-template.md +2 -6
- package/templates/skills/application/references/roles-client-project-handling.md +55 -0
- package/templates/skills/application/references/roles-fallback-procedure.md +149 -0
- package/templates/skills/application/references/test-coverage-requirements.md +213 -0
- package/templates/skills/application/references/test-frontend.md +3 -3
- package/templates/skills/application/steps/step-00-init.md +11 -141
- package/templates/skills/application/steps/step-01-navigation.md +3 -3
- package/templates/skills/application/steps/step-02-permissions.md +4 -4
- package/templates/skills/application/steps/step-03-roles.md +18 -175
- package/templates/skills/application/steps/step-03b-provider.md +1 -2
- package/templates/skills/application/steps/step-04-backend.md +19 -110
- package/templates/skills/application/steps/step-05-frontend.md +17 -143
- package/templates/skills/application/steps/step-06-migration.md +12 -60
- package/templates/skills/application/steps/step-07-tests.md +9 -76
- package/templates/skills/application/templates-backend.md +29 -27
- package/templates/skills/application/templates-frontend.md +48 -48
- package/templates/skills/application/templates-seed.md +57 -131
- package/templates/skills/business-analyse/SKILL.md +27 -30
- package/templates/skills/business-analyse/_architecture.md +6 -6
- package/templates/skills/business-analyse/_shared.md +60 -88
- package/templates/skills/business-analyse/questionnaire/04-data.md +3 -3
- package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
- package/templates/skills/business-analyse/questionnaire/13-cross-module.md +1 -1
- package/templates/skills/business-analyse/react/application-viewer.md +12 -12
- package/templates/skills/business-analyse/react/components.md +8 -12
- package/templates/skills/business-analyse/react/schema.md +11 -11
- package/templates/skills/business-analyse/references/agent-module-prompt.md +2 -3
- package/templates/skills/business-analyse/references/analysis-semantic-checks.md +190 -0
- package/templates/skills/business-analyse/references/cache-warming-strategy.md +2 -2
- package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +41 -0
- package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +74 -0
- package/templates/skills/business-analyse/references/cadrage-shared-modules.md +69 -0
- package/templates/skills/business-analyse/references/cadrage-structure-cards.md +1 -1
- package/templates/skills/business-analyse/references/compilation-structure-cards.md +297 -0
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +2 -2
- package/templates/skills/business-analyse/references/deploy-modes.md +5 -5
- package/templates/skills/business-analyse/references/detection-strategies.md +7 -7
- package/templates/skills/business-analyse/references/handoff-file-templates.md +14 -22
- package/templates/skills/business-analyse/references/handoff-mappings.md +4 -4
- package/templates/skills/business-analyse/references/handoff-seeddata-generation.md +312 -0
- package/templates/skills/business-analyse/references/init-schema-deployment.md +3 -3
- package/templates/skills/business-analyse/references/naming-conventions.md +22 -24
- package/templates/skills/business-analyse/references/prd-generation.md +2 -2
- package/templates/skills/business-analyse/references/review-data-mapping.md +2 -2
- package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
- package/templates/skills/business-analyse/references/spec-auto-inference.md +3 -3
- package/templates/skills/business-analyse/references/team-orchestration.md +49 -6
- package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
- package/templates/skills/business-analyse/references/ui-resource-cards.md +18 -18
- package/templates/skills/business-analyse/references/validate-incremental-html.md +2 -2
- package/templates/skills/business-analyse/references/validation-checklist.md +2 -2
- package/templates/skills/business-analyse/schemas/application-schema.json +4 -5
- package/templates/skills/business-analyse/schemas/project-schema.json +1 -6
- package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +2 -3
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +4 -4
- package/templates/skills/business-analyse/steps/step-00-init.md +8 -17
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +35 -198
- package/templates/skills/business-analyse/steps/step-01b-applications.md +16 -20
- package/templates/skills/business-analyse/steps/step-02-decomposition.md +1 -1
- package/templates/skills/business-analyse/steps/step-03a1-setup.md +4 -4
- package/templates/skills/business-analyse/steps/step-03a2-analysis.md +1 -1
- package/templates/skills/business-analyse/steps/step-03b-ui.md +4 -4
- package/templates/skills/business-analyse/steps/step-03c-compile.md +66 -140
- package/templates/skills/business-analyse/steps/step-03d-validate.md +2 -2
- package/templates/skills/business-analyse/steps/step-04a-collect.md +2 -2
- package/templates/skills/business-analyse/steps/step-04b-analyze.md +42 -160
- package/templates/skills/business-analyse/steps/step-04c-decide.md +1 -1
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +74 -104
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +13 -11
- package/templates/skills/business-analyse/steps/step-06-review.md +3 -3
- package/templates/skills/business-analyse/templates/tpl-frd.md +13 -13
- package/templates/skills/business-analyse/templates/tpl-handoff.md +12 -12
- package/templates/skills/business-analyse/templates-frd.md +25 -25
- package/templates/skills/business-analyse/templates-react.md +15 -21
- package/templates/skills/controller/SKILL.md +1 -1
- package/templates/skills/controller/postman-templates.md +1 -1
- package/templates/skills/controller/references/controller-code-templates.md +2 -2
- package/templates/skills/controller/references/mcp-scaffold-workflow.md +209 -0
- package/templates/skills/controller/references/permission-sync-templates.md +13 -16
- package/templates/skills/controller/steps/step-00-init.md +11 -11
- package/templates/skills/controller/steps/step-03-generate.md +64 -103
- package/templates/skills/controller/templates.md +67 -71
- package/templates/skills/debug/SKILL.md +13 -218
- package/templates/skills/debug/steps/step-00-init.md +57 -0
- package/templates/skills/debug/steps/step-01-analyze.md +219 -0
- package/templates/skills/debug/steps/step-02-resolve.md +85 -0
- package/templates/skills/documentation/SKILL.md +49 -345
- package/templates/skills/documentation/data-schema.md +11 -8
- package/templates/skills/documentation/steps/step-00-init.md +70 -0
- package/templates/skills/documentation/steps/step-01-scan.md +113 -0
- package/templates/skills/documentation/steps/step-02-generate.md +231 -0
- package/templates/skills/documentation/steps/step-03-validate.md +238 -0
- package/templates/skills/documentation/templates.md +480 -322
- package/templates/skills/efcore/references/both-contexts.md +32 -0
- package/templates/skills/efcore/references/database-operations.md +67 -0
- package/templates/skills/efcore/references/destructive-operations.md +38 -0
- package/templates/skills/efcore/references/reset-operations.md +81 -0
- package/templates/skills/efcore/references/seed-methods.md +86 -0
- package/templates/skills/efcore/references/shared-init-functions.md +250 -0
- package/templates/skills/efcore/references/sql-objects-injection.md +61 -0
- package/templates/skills/efcore/references/troubleshooting.md +81 -0
- package/templates/skills/efcore/steps/db/step-deploy.md +1 -32
- package/templates/skills/efcore/steps/db/step-reset.md +7 -103
- package/templates/skills/efcore/steps/db/step-seed.md +10 -132
- package/templates/skills/efcore/steps/db/step-status.md +5 -44
- package/templates/skills/efcore/steps/migration/step-03-validate.md +8 -62
- package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +1 -57
- package/templates/skills/efcore/steps/shared/step-00-init.md +11 -254
- package/templates/skills/efcore/steps/squash/step-03-create.md +1 -58
- package/templates/skills/feature-full/SKILL.md +1 -1
- package/templates/skills/feature-full/steps/step-00-init.md +57 -0
- package/templates/skills/feature-full/steps/step-01-implementation.md +1 -1
- package/templates/skills/gitflow/SKILL.md +1 -1
- package/templates/skills/gitflow/_shared.md +23 -0
- package/templates/skills/gitflow/references/commit-message-generation.md +58 -0
- package/templates/skills/gitflow/references/commit-migration-validation.md +49 -0
- package/templates/skills/gitflow/references/finish-cleanup.md +51 -0
- package/templates/skills/gitflow/references/finish-version-bumping.md +45 -0
- package/templates/skills/gitflow/references/init-environment-detection.md +41 -0
- package/templates/skills/gitflow/references/init-questions.md +185 -0
- package/templates/skills/gitflow/references/init-structure-creation.md +71 -0
- package/templates/skills/gitflow/references/init-version-detection.md +21 -0
- package/templates/skills/gitflow/references/init-workspace-detection.md +43 -0
- package/templates/skills/gitflow/references/merge-ci-status.md +36 -0
- package/templates/skills/gitflow/references/merge-execution.md +62 -0
- package/templates/skills/gitflow/references/merge-pr-context.md +76 -0
- package/templates/skills/gitflow/references/pr-build-checks.md +60 -0
- package/templates/skills/gitflow/references/pr-generation.md +58 -0
- package/templates/skills/gitflow/references/start-branch-normalization.md +28 -0
- package/templates/skills/gitflow/references/start-worktree-creation.md +50 -0
- package/templates/skills/gitflow/references/sync-push-verify.md +44 -0
- package/templates/skills/gitflow/references/sync-rebase-conflicts.md +38 -0
- package/templates/skills/gitflow/steps/step-commit.md +12 -91
- package/templates/skills/gitflow/steps/step-finish.md +15 -159
- package/templates/skills/gitflow/steps/step-init.md +24 -326
- package/templates/skills/gitflow/steps/step-merge.md +17 -176
- package/templates/skills/gitflow/steps/step-pr.md +10 -116
- package/templates/skills/gitflow/steps/step-start.md +16 -109
- package/templates/skills/gitflow/steps/step-sync.md +6 -69
- package/templates/skills/ralph-loop/SKILL.md +6 -0
- package/templates/skills/ralph-loop/references/category-completeness.md +185 -0
- package/templates/skills/ralph-loop/references/compact-loop.md +1 -1
- package/templates/skills/ralph-loop/references/init-resume-recovery.md +127 -0
- package/templates/skills/ralph-loop/references/module-transition.md +151 -0
- package/templates/skills/ralph-loop/references/multi-module-queue.md +171 -0
- package/templates/skills/ralph-loop/references/parallel-execution.md +246 -0
- package/templates/skills/ralph-loop/references/task-transform-legacy.md +6 -9
- package/templates/skills/ralph-loop/references/team-orchestration.md +45 -3
- package/templates/skills/ralph-loop/steps/step-00-init.md +36 -109
- package/templates/skills/ralph-loop/steps/step-01-task.md +15 -163
- package/templates/skills/ralph-loop/steps/step-02-execute.md +8 -154
- package/templates/skills/ralph-loop/steps/step-04-check.md +21 -73
- package/templates/skills/review-code/references/owasp-api-top10.md +5 -5
- package/templates/skills/review-code/references/smartstack-conventions.md +11 -11
- package/templates/skills/validate-feature/references/api-smoke-tests.md +140 -0
- package/templates/skills/validate-feature/references/db-validation-checks.md +180 -0
- package/templates/skills/validate-feature/steps/step-01-compile.md +5 -2
- package/templates/skills/validate-feature/steps/step-04-api-smoke.md +34 -145
- package/templates/skills/validate-feature/steps/step-05-db-validation.md +74 -260
- package/templates/skills/workflow/SKILL.md +1 -1
- package/templates/skills/workflow/steps/step-00-init.md +57 -0
|
@@ -60,7 +60,7 @@ JSON Schema for validation: Code, Name, JsonSchema, DotNetType
|
|
|
60
60
|
|
|
61
61
|
## Implementation
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Start with [steps/step-00-init.md](steps/step-00-init.md) to gather requirements, then proceed to [steps/step-01-implementation.md](steps/step-01-implementation.md) for:
|
|
64
64
|
- Workflow steps (define use case, create prompt, define schema, execute)
|
|
65
65
|
- AI service interfaces (IAiCompletionService, IPromptService)
|
|
66
66
|
- Frontend integration (API, hooks, components)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Step 0: Initialization
|
|
2
|
+
|
|
3
|
+
## YOUR TASK
|
|
4
|
+
Gather context about the AI integration requirements before implementation.
|
|
5
|
+
|
|
6
|
+
## EXECUTION SEQUENCE
|
|
7
|
+
|
|
8
|
+
### 1. Identify AI Use Case
|
|
9
|
+
- What type of AI integration? (prompt execution, chat, content generation, validation, analysis)
|
|
10
|
+
- What model/provider should be used? (Claude, GPT-4, GPT-4o, Gemini, local model)
|
|
11
|
+
- What is the input schema? (user query, structured data, multiple parameters)
|
|
12
|
+
- What is the expected output? (text, JSON, structured object, classification)
|
|
13
|
+
|
|
14
|
+
### 2. Check Existing Patterns
|
|
15
|
+
- Search existing `Application/Common/Interfaces/IAiCompletionService` usage
|
|
16
|
+
- Identify reusable patterns: AiProviderInstance configuration, OutputSchema definitions
|
|
17
|
+
- Check for existing Prompt entities with similar use cases
|
|
18
|
+
- Review error handling patterns for API failures and quota limits
|
|
19
|
+
|
|
20
|
+
### 3. Plan Implementation
|
|
21
|
+
- Determine required files:
|
|
22
|
+
- Prompt entity and PromptBlock creation
|
|
23
|
+
- OutputSchema if structured response needed
|
|
24
|
+
- Service integration with IAiCompletionService
|
|
25
|
+
- Frontend API client and React hook
|
|
26
|
+
- Identify dependencies:
|
|
27
|
+
- Which AI provider instance to use? (API keys, budget limits)
|
|
28
|
+
- Token budget and cost implications
|
|
29
|
+
- Error handling strategy (fallback provider, graceful degradation)
|
|
30
|
+
- Map variables and placeholders for dynamic content
|
|
31
|
+
|
|
32
|
+
### 4. Define Success Criteria
|
|
33
|
+
- Prompt executes with correct model and parameters
|
|
34
|
+
- Response validates against OutputSchema (if applicable)
|
|
35
|
+
- Token usage logged and budget respected
|
|
36
|
+
- Error handling covers API downtime and quota exhaustion
|
|
37
|
+
- Frontend integrates with loading/error states
|
|
38
|
+
|
|
39
|
+
## SUCCESS METRICS
|
|
40
|
+
- AI use case clearly identified and documented
|
|
41
|
+
- Implementation plan with all required files listed
|
|
42
|
+
- Dependencies identified (provider instance, budget, error handling)
|
|
43
|
+
- Decision on structured vs. unstructured response
|
|
44
|
+
- Token budget and cost reviewed
|
|
45
|
+
|
|
46
|
+
## NEXT STEP
|
|
47
|
+
Proceed to `./step-01-implementation.md` to implement the Prompt, OutputSchema, Service integration, and Frontend components.
|
|
@@ -11,7 +11,7 @@ argument-hint: "[-a] [-x] [-s] [-e] [-r] [-pr] <task description>"
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
<objective>
|
|
14
|
-
Execute incremental SmartStack development using the APEX methodology. This skill knows the SmartStack hierarchy (
|
|
14
|
+
Execute incremental SmartStack development using the APEX methodology. This skill knows the SmartStack hierarchy (application/module/section/resource), delegates code creation to existing skills (/controller, /application, /ui-components, /efcore, /notification, /workflow) and MCP tools, and validates via MCP conventions.
|
|
15
15
|
|
|
16
16
|
**Key principle:** /apex ORCHESTRATES — it never generates SmartStack code directly. All generation goes through skills and MCP tools.
|
|
17
17
|
</objective>
|
|
@@ -57,7 +57,6 @@ Execute incremental SmartStack development using the APEX methodology. This skil
|
|
|
57
57
|
| `{delegate_mode}` | boolean | Delegated by `/ralph-loop` via `-d` flag |
|
|
58
58
|
| `{delegate_prd_path}` | string? | Path to PRD file (`.ralph/prd.json` or `.ralph/prd-{module}.json`) |
|
|
59
59
|
| `{foundation_mode}` | boolean | Foundation mode: entities-only (no services/controllers/frontend). Used by ralph-loop Phase 0. |
|
|
60
|
-
| `{context_code}` | string | "business", "platform", "personal" |
|
|
61
60
|
| `{app_name}` | string | Application name |
|
|
62
61
|
| `{module_code}` | string | Module code |
|
|
63
62
|
| `{sections}` | object[] | Sections (MANDATORY, min 1) with code/labels/icon/displayOrder |
|
|
@@ -84,7 +83,7 @@ Execute incremental SmartStack development using the APEX methodology. This skil
|
|
|
84
83
|
|
|
85
84
|
| Step | File | Model | Purpose |
|
|
86
85
|
|------|------|-------|---------|
|
|
87
|
-
| 00 | `steps/step-00-init.md` | Sonnet | Parse flags, detect
|
|
86
|
+
| 00 | `steps/step-00-init.md` | Sonnet | Parse flags, detect application, verify MCP, define hierarchy (4 levels), challenge need |
|
|
88
87
|
| 01 | `steps/step-01-analyze.md` | Opus | Explore existing code (Agent Teams or direct) |
|
|
89
88
|
| 02 | `steps/step-02-plan.md` | Opus | Layer-by-layer plan with skill/MCP mapping |
|
|
90
89
|
| 03 | `steps/step-03-execute.md` | Opus | Orchestrate execution via skills and MCP |
|
|
@@ -158,7 +157,7 @@ Execute incremental SmartStack development using the APEX methodology. This skil
|
|
|
158
157
|
</error_handling>
|
|
159
158
|
|
|
160
159
|
<success_criteria>
|
|
161
|
-
- SmartStack
|
|
160
|
+
- SmartStack hierarchy detected (app/module)
|
|
162
161
|
- Plan validated with skill/MCP mapped for each file
|
|
163
162
|
- Code created/corrected via existing skills and MCP (no direct generation)
|
|
164
163
|
- MCP validate_conventions: 0 errors
|
|
@@ -13,15 +13,6 @@
|
|
|
13
13
|
3. `.ralph/prd-*.json` → PRDs exist
|
|
14
14
|
4. `src/pages/` → React frontend exists
|
|
15
15
|
|
|
16
|
-
### Context-to-Folder Mapping
|
|
17
|
-
|
|
18
|
-
| Context | Backend | Controller | Frontend Layout |
|
|
19
|
-
|---------|---------|------------|----------------|
|
|
20
|
-
| `business` | `Business` | `Business` | `BusinessLayout` |
|
|
21
|
-
| `platform.administration` | `Platform/Administration` | `Admin` | `AdminLayout` |
|
|
22
|
-
| `platform.support` | `Platform/Support` | `Support` | `AdminLayout` |
|
|
23
|
-
| `personal` | `Personal` | `User` | `UserLayout` |
|
|
24
|
-
|
|
25
16
|
---
|
|
26
17
|
|
|
27
18
|
## Delegate Mode Context
|
|
@@ -32,7 +23,6 @@ When `/ralph-loop` invokes `/apex -d {prd_path}`:
|
|
|
32
23
|
|
|
33
24
|
1. **Read PRD** from `{delegate_prd_path}` (`.ralph/prd.json` or `.ralph/prd-{module}.json`)
|
|
34
25
|
2. **Extract context:**
|
|
35
|
-
- `context_code` = `prd.project.context` (e.g., "business")
|
|
36
26
|
- `app_name` = `prd.project.application` (e.g., "HumanResources")
|
|
37
27
|
- `module_code` = `prd.project.module` (e.g., "EmployeeManagement")
|
|
38
28
|
- `sections` = from `_seedDataMeta.coreSeedData.navigationSections` in infrastructure tasks
|
|
@@ -72,23 +62,23 @@ Write back to {delegate_prd_path}
|
|
|
72
62
|
|
|
73
63
|
| Level | Permission format | Segments |
|
|
74
64
|
|-------|------------------|----------|
|
|
75
|
-
| Module | `{
|
|
76
|
-
| Section | `{
|
|
77
|
-
| Resource | `{
|
|
65
|
+
| Module | `{app}.{module}.{action}` | 2+1 segments |
|
|
66
|
+
| Section | `{app}.{module}.{section}.{action}` | 3+1 segments |
|
|
67
|
+
| Resource | `{app}.{module}.{section}.{resource}.{action}` | 4+1 segments |
|
|
78
68
|
|
|
79
69
|
**Examples:**
|
|
80
|
-
- Module: `
|
|
81
|
-
- Section: `
|
|
82
|
-
- Resource: `
|
|
70
|
+
- Module: `human-resources.employees.read` (2+1)
|
|
71
|
+
- Section: `human-resources.employees.departments.read` (3+1)
|
|
72
|
+
- Resource: `human-resources.employees.departments.export.execute` (4+1)
|
|
83
73
|
|
|
84
74
|
> **CRITICAL — Permission codes use the SAME kebab-case segments as NavRoute codes.**
|
|
85
75
|
> Every dot-separated segment in a permission path is a navigation entity code.
|
|
86
76
|
> Multi-word codes MUST be kebab-case: `human-resources`, NOT `humanresources`.
|
|
87
77
|
>
|
|
88
|
-
> SmartStack.app reference: `
|
|
78
|
+
> SmartStack.app reference: `support-client.my-tickets.read`, `administration.email-templates.read`
|
|
89
79
|
>
|
|
90
|
-
> **FORBIDDEN:** `
|
|
91
|
-
> **CORRECT:** `
|
|
80
|
+
> **FORBIDDEN:** `humanresources.employees.read` (concatenated — no kebab-case)
|
|
81
|
+
> **CORRECT:** `human-resources.employees.read` (kebab-case — matches NavRoute)
|
|
92
82
|
|
|
93
83
|
### Generation (step-03)
|
|
94
84
|
|
|
@@ -144,7 +134,7 @@ Write back to {delegate_prd_path}
|
|
|
144
134
|
| Skill | When to delegate |
|
|
145
135
|
|-------|-----------------|
|
|
146
136
|
| `/controller` | Complex controller with custom routes |
|
|
147
|
-
| `/application` | New
|
|
137
|
+
| `/application` | New application/module structure |
|
|
148
138
|
| `/ui-components` | Complex React pages (tables, grids, dashboards) |
|
|
149
139
|
| `/efcore` | Complex EF Core configurations |
|
|
150
140
|
| `/notification` | In-app or email notifications |
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Analysis Methods — FK Detection, Tenant Modes, Code Patterns, Gap Analysis
|
|
2
|
+
|
|
3
|
+
> **Loaded by:** step-01-analyze.md (sections 4-7)
|
|
4
|
+
> **Purpose:** Detailed methods for analyzing existing code and planning entity-level requirements.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## FK Field Detection
|
|
9
|
+
|
|
10
|
+
For each entity found (or to be created), identify FK relationships:
|
|
11
|
+
- Properties ending in "Id" with matching navigation property
|
|
12
|
+
- Record: `{ entity, fkProperty, targetEntity, isRequired }`
|
|
13
|
+
|
|
14
|
+
**Why:** FK fields drive two critical requirements:
|
|
15
|
+
1. **Frontend:** Each FK field MUST use `<EntityLookup />` (NEVER `<input>`, NEVER `<select>`)
|
|
16
|
+
2. **Backend:** Each target entity's GetAll MUST support `?search=` parameter + return `PaginatedResult<T>`
|
|
17
|
+
|
|
18
|
+
See `references/execution-frontend-patterns.md` for EntityLookup patterns.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Tenant Mode Decision
|
|
23
|
+
|
|
24
|
+
For each entity found (or to be created), determine the `tenantMode`:
|
|
25
|
+
|
|
26
|
+
| Mode | Meaning | Examples | EF Filter |
|
|
27
|
+
|------|---------|----------|-----------|
|
|
28
|
+
| `strict` | Data belongs to one tenant | Employee, Order, Invoice | `TenantId == current` |
|
|
29
|
+
| `optional` | Can be shared or tenant-specific | Department, Currency, JobTitle | `TenantId == current OR TenantId == null` |
|
|
30
|
+
| `scoped` | Explicit scope rules | Settings, Workflow, EmailTemplate | `TenantId == current AND Scope == current` |
|
|
31
|
+
| `none` | Platform-wide (never filtered) | Navigation, Permission, User | No TenantId |
|
|
32
|
+
|
|
33
|
+
**Why:** Tenant mode drives EF query filters, seed data generation, and API access control.
|
|
34
|
+
|
|
35
|
+
**Reference:** See `references/smartstack-api.md` for TenantId handling patterns and `smartstack-layers.md` for seed data strategies per tenant mode.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Code Pattern Detection
|
|
40
|
+
|
|
41
|
+
For each entity found (or to be created), identify code generation needs:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
IF feature.json exists AND entity has codePattern:
|
|
45
|
+
→ Use codePattern config from feature.json (strategy, prefix, digits, etc.)
|
|
46
|
+
→ Record in analysis: entity has auto-generated code
|
|
47
|
+
|
|
48
|
+
ELSE IF feature.json exists BUT entity has NO codePattern:
|
|
49
|
+
→ Record: entity needs codePattern decision in step-02
|
|
50
|
+
→ Apply heuristic default based on entity name:
|
|
51
|
+
Invoice/Order/Receipt → timestamp-daily
|
|
52
|
+
Ticket/Incident → timestamp-minute
|
|
53
|
+
Contract/Policy → year-sequential
|
|
54
|
+
Reference/Category → uuid-short
|
|
55
|
+
Employee/Customer/Project → sequential
|
|
56
|
+
|
|
57
|
+
ELSE (no feature.json):
|
|
58
|
+
→ Propose codePattern during step-02 planning based on task description
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Why:** Code generation strategy drives CreateDto structure, service injection (ICodeGenerator<T>), and DI registration.
|
|
62
|
+
|
|
63
|
+
**Reference:** See `references/code-generation.md` for strategy table, volume-to-digits calculation, and backend patterns.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Gap Analysis
|
|
68
|
+
|
|
69
|
+
Compare what EXISTS vs what the TASK REQUIRES:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
For each element: EXISTS+COMPLETE → "skip" | EXISTS+INCOMPLETE → "modify" | MISSING → "create"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Cross-reference with step-00 challenge responses:
|
|
76
|
+
- Each entity: entity, EF config, service, controller, frontend pages → exists/missing
|
|
77
|
+
- Each section: NavigationSectionSeedData, frontend route → exists/missing
|
|
78
|
+
- If dependencies: verify FK target entities and their `?search=` support
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Scope Re-Check (after exploration)
|
|
83
|
+
|
|
84
|
+
**Re-validate scope after code exploration reveals the true entity count.**
|
|
85
|
+
Step-00 guard uses the user's description (may undercount). Now we know the actual entities.
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
IF NOT delegate_mode:
|
|
89
|
+
actual_entities = count of entities marked "create" in gap analysis
|
|
90
|
+
actual_sections = count of sections marked "create"
|
|
91
|
+
|
|
92
|
+
IF actual_entities > 6:
|
|
93
|
+
WARNING: "Code exploration reveals {actual_entities} entities.
|
|
94
|
+
This exceeds the recommended maximum (4) for a single /apex invocation.
|
|
95
|
+
Risk: incomplete migrations, lost conventions, missing pages.
|
|
96
|
+
Consider: split into {ceil(actual_entities/4)} iterations of ~4 entities each."
|
|
97
|
+
|
|
98
|
+
Ask user to confirm or re-scope.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Analysis Validation — User Checkpoint
|
|
104
|
+
|
|
105
|
+
**Objective:** Present findings and validate scope BEFORE planning.
|
|
106
|
+
|
|
107
|
+
### Present Findings
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
ANALYSIS FINDINGS
|
|
111
|
+
═══════════════════════════════════════════════════════════════
|
|
112
|
+
|
|
113
|
+
Entities expected / found / to create: {summary}
|
|
114
|
+
Sections expected / found / to create: {summary}
|
|
115
|
+
FK Relationships: {fkFields summary}
|
|
116
|
+
Dependencies: {cross-module refs or "none"}
|
|
117
|
+
Complexity: {module_complexity}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Validate with User (if NOT auto_mode)
|
|
121
|
+
|
|
122
|
+
Question template (same as step-01 section 6b):
|
|
123
|
+
- "Scope is correct" (Recommended)
|
|
124
|
+
- "Add elements" → update entities/sections, re-run gap analysis
|
|
125
|
+
- "Reduce scope" → update accordingly
|
|
126
|
+
- "Change approach" → potentially restart from step-00
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Analysis Summary Output
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
**APEX SmartStack - Analysis Complete**
|
|
134
|
+
|
|
135
|
+
Navigation: {app_name} → {module_code} → {sections[].code}
|
|
136
|
+
Entities: {entity_name → create | modify | skip}
|
|
137
|
+
Existing: entities, configs, services, controllers, pages, seed data, tests (with paths)
|
|
138
|
+
Required: create / modify / skip lists
|
|
139
|
+
Profile: complexity, dependencies, FK fields, workflow, notifications
|
|
140
|
+
ACs: AC1..ACn (inferred from PRD/feature/task/challenge)
|
|
141
|
+
```
|
|
@@ -5,26 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
## Context Detection (section 2)
|
|
9
|
-
|
|
10
|
-
If hierarchy cannot be inferred, ask the user:
|
|
11
|
-
|
|
12
|
-
```yaml
|
|
13
|
-
questions:
|
|
14
|
-
- header: "Context"
|
|
15
|
-
question: "What is the SmartStack context for this work?"
|
|
16
|
-
options:
|
|
17
|
-
- label: "Business (Recommended)"
|
|
18
|
-
description: "Business application module"
|
|
19
|
-
- label: "Platform"
|
|
20
|
-
description: "Platform administration or support"
|
|
21
|
-
- label: "Personal"
|
|
22
|
-
description: "Personal user space"
|
|
23
|
-
multiSelect: false
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
8
|
## 4a. Application Validation
|
|
29
9
|
|
|
30
10
|
If `{app_name}` was NOT clearly inferred from the task description:
|
|
@@ -37,7 +17,7 @@ questions:
|
|
|
37
17
|
- label: "<best guess from task> (Recommended)"
|
|
38
18
|
description: "Inferred from your task description"
|
|
39
19
|
- label: "New application"
|
|
40
|
-
description: "Create a new application
|
|
20
|
+
description: "Create a new application"
|
|
41
21
|
- label: "Existing application"
|
|
42
22
|
description: "Add to an existing application (specify in Other)"
|
|
43
23
|
multiSelect: false
|
|
@@ -26,15 +26,14 @@ const permissions = coreSeedData.permissions || [];
|
|
|
26
26
|
const rolePerms = coreSeedData.rolePermissions || [];
|
|
27
27
|
|
|
28
28
|
// Derived context (from guardrail or PRD)
|
|
29
|
-
const navRoute = meta.navRoute; // e.g. "
|
|
30
|
-
const contextCode = meta.contextCode; // e.g. "business"
|
|
29
|
+
const navRoute = meta.navRoute; // e.g. "human-resources.projects"
|
|
31
30
|
const appCode = meta.appCode; // e.g. "human-resources"
|
|
32
31
|
const moduleCode = task.module; // e.g. "projects"
|
|
33
32
|
|
|
34
33
|
// If _seedDataMeta is absent, fallback to PRD source
|
|
35
34
|
if (!navRoute) {
|
|
36
35
|
const prd = readJSON('.ralph/prd.json');
|
|
37
|
-
const navRoute = `${prd.source?.
|
|
36
|
+
const navRoute = `${prd.source?.application || prd.metadata?.module}.${task.module}`;
|
|
38
37
|
}
|
|
39
38
|
```
|
|
40
39
|
|
|
@@ -42,8 +41,7 @@ if (!navRoute) {
|
|
|
42
41
|
|
|
43
42
|
| Variable | Example | Source |
|
|
44
43
|
|----------|---------|--------|
|
|
45
|
-
| `navRoute` | `
|
|
46
|
-
| `contextCode` | `business` | `_seedDataMeta.contextCode` |
|
|
44
|
+
| `navRoute` | `human-resources.projects` | `_seedDataMeta.navRoute` |
|
|
47
45
|
| `appCode` | `human-resources` | `_seedDataMeta.appCode` |
|
|
48
46
|
| `moduleCode` | `projects` | `task.module` |
|
|
49
47
|
| `navModules[]` | `[{code, label, icon, route, translations}]` | `coreSeedData.navigationModules` |
|
|
@@ -72,24 +70,15 @@ From `seedDataCore.navigationApplications[0]` in feature.json (generated by BA s
|
|
|
72
70
|
| `{appLabel_xx}` | `navigationApplications[0].labels.xx` (fr, en, it, de) |
|
|
73
71
|
| `{appDesc_xx}` | `navigationApplications[0].description.xx` |
|
|
74
72
|
| `{appIcon}` | `navigationApplications[0].icon` |
|
|
75
|
-
| `{contextCode}` | `navigationApplications[0].context` or `_seedDataMeta.contextCode` |
|
|
76
73
|
|
|
77
74
|
### GUID Generation Rule
|
|
78
75
|
|
|
79
|
-
> **CRITICAL — NavigationContext IDs are NEVER generated as deterministic GUIDs.**
|
|
80
|
-
> Contexts (`business`, `platform`, `personal`) are pre-seeded by SmartStack core with hardcoded GUIDs.
|
|
81
|
-
> The `contextId` parameter in `GetApplicationEntry(Guid contextId)` is resolved at runtime
|
|
82
|
-
> by querying `db.NavigationContexts.FirstOrDefaultAsync(c => c.Code == "business", ct)`.
|
|
83
|
-
> **FORBIDDEN:** `GenerateDeterministicGuid("nav:business")` or any ContextId constant in SeedConstants.
|
|
84
76
|
|
|
85
77
|
```csharp
|
|
86
|
-
// Deterministic GUID for APPLICATION
|
|
78
|
+
// Deterministic GUID for APPLICATION
|
|
87
79
|
public static readonly Guid ApplicationId =
|
|
88
|
-
GenerateDeterministicGuid("navigation-application-{
|
|
89
|
-
// Example: GenerateDeterministicGuid("navigation-application-
|
|
90
|
-
//
|
|
91
|
-
// FORBIDDEN — Context IDs must NOT be generated:
|
|
92
|
-
// public static readonly Guid BusinessContextId = GenerateDeterministicGuid("nav:business"); // WRONG!
|
|
80
|
+
GenerateDeterministicGuid("navigation-application-{appCode}");
|
|
81
|
+
// Example: GenerateDeterministicGuid("navigation-application-human-resources")
|
|
93
82
|
```
|
|
94
83
|
|
|
95
84
|
### Template
|
|
@@ -108,23 +97,22 @@ public static class NavigationApplicationSeedData
|
|
|
108
97
|
{
|
|
109
98
|
// Deterministic GUID for this application
|
|
110
99
|
public static readonly Guid ApplicationId =
|
|
111
|
-
GenerateDeterministicGuid("navigation-application-{
|
|
100
|
+
GenerateDeterministicGuid("navigation-application-{appCode}");
|
|
112
101
|
|
|
113
102
|
/// <summary>
|
|
114
103
|
/// Returns navigation application entry for seeding into core.nav_Applications.
|
|
115
104
|
/// </summary>
|
|
116
|
-
public static NavigationApplicationSeedEntry GetApplicationEntry(
|
|
105
|
+
public static NavigationApplicationSeedEntry GetApplicationEntry()
|
|
117
106
|
{
|
|
118
107
|
return new NavigationApplicationSeedEntry
|
|
119
108
|
{
|
|
120
109
|
Id = ApplicationId,
|
|
121
|
-
ContextId = contextId,
|
|
122
110
|
Code = "{appCode}",
|
|
123
111
|
Label = "{appLabel_en}",
|
|
124
112
|
Description = "{appDesc_en}",
|
|
125
113
|
Icon = "{appIcon}", // Lucide React icon name
|
|
126
114
|
IconType = IconType.Lucide,
|
|
127
|
-
Route = ToKebabCase("/{
|
|
115
|
+
Route = ToKebabCase("/{appCode}"),
|
|
128
116
|
DisplayOrder = 1,
|
|
129
117
|
IsActive = true
|
|
130
118
|
};
|
|
@@ -245,7 +233,7 @@ private static Guid GenerateDeterministicGuid(string seed)
|
|
|
245
233
|
|
|
246
234
|
// Usage: GUIDs are derived from the navigation path
|
|
247
235
|
public static readonly Guid ModuleId = GenerateDeterministicGuid("navigation-module-{navRoute}");
|
|
248
|
-
// Example: GenerateDeterministicGuid("navigation-module-
|
|
236
|
+
// Example: GenerateDeterministicGuid("navigation-module-human-resources.projects")
|
|
249
237
|
```
|
|
250
238
|
|
|
251
239
|
### Template
|
|
@@ -279,7 +267,7 @@ public static class {ModulePascal}NavigationSeedData
|
|
|
279
267
|
Description = "{desc_en}",
|
|
280
268
|
Icon = "{icon}", // Lucide React icon name
|
|
281
269
|
IconType = IconType.Lucide,
|
|
282
|
-
Route = ToKebabCase($"/{
|
|
270
|
+
Route = ToKebabCase($"/{appCode}/{moduleCode}"),
|
|
283
271
|
DisplayOrder = {displayOrder},
|
|
284
272
|
IsActive = true
|
|
285
273
|
};
|
|
@@ -337,7 +325,7 @@ public static class {ModulePascal}NavigationSeedData
|
|
|
337
325
|
|
|
338
326
|
/// <summary>
|
|
339
327
|
/// Converts PascalCase route segments to kebab-case for web URLs.
|
|
340
|
-
/// Example: /
|
|
328
|
+
/// Example: /HumanResources/TimeManagement → /human-resources/time-management
|
|
341
329
|
/// </summary>
|
|
342
330
|
private static string ToKebabCase(string route)
|
|
343
331
|
{
|
|
@@ -406,20 +394,20 @@ public class NavigationTranslationSeedEntry
|
|
|
406
394
|
// Section GUID: deterministic from navRoute + section code
|
|
407
395
|
public static readonly Guid {SectionPascal}SectionId =
|
|
408
396
|
GenerateDeterministicGuid("navigation-section-{navRoute}.{sectionCode}");
|
|
409
|
-
// Example: GenerateDeterministicGuid("navigation-section-
|
|
397
|
+
// Example: GenerateDeterministicGuid("navigation-section-human-resources.employees.list")
|
|
410
398
|
|
|
411
399
|
// Resource GUID: deterministic from navRoute + section code + resource code
|
|
412
400
|
public static readonly Guid {ResourcePascal}ResourceId =
|
|
413
401
|
GenerateDeterministicGuid("navigation-resource-{navRoute}.{sectionCode}.{resourceCode}");
|
|
414
|
-
// Example: GenerateDeterministicGuid("navigation-resource-
|
|
402
|
+
// Example: GenerateDeterministicGuid("navigation-resource-human-resources.employees.list.employees-grid")
|
|
415
403
|
```
|
|
416
404
|
|
|
417
405
|
### Section Methods (add to {ModulePascal}NavigationSeedData.cs)
|
|
418
406
|
|
|
419
407
|
> **ROUTE SPECIAL CASES (list and detail):**
|
|
420
408
|
> The `list` and `detail` sections are view modes of the module, NOT functional sub-areas.
|
|
421
|
-
> - `list` section route = module route (e.g., `/
|
|
422
|
-
> - `detail` section route = module route + `/:id` (e.g., `/
|
|
409
|
+
> - `list` section route = module route (e.g., `/human-resources/employees`) — NO `/list` suffix
|
|
410
|
+
> - `detail` section route = module route + `/:id` (e.g., `/human-resources/employees/:id`) — NOT `/detail/:id`
|
|
423
411
|
> - FORBIDDEN: `/{module}/list`, `/{module}/detail/:id`
|
|
424
412
|
> - Other sections (dashboard, approve, import) = module route + `/{section-kebab}` (normal)
|
|
425
413
|
|
|
@@ -542,9 +530,9 @@ public static IEnumerable<NavigationResourceSeedEntry> GetResourceEntries(Guid s
|
|
|
542
530
|
// Then append: /{resource-kebab}
|
|
543
531
|
//
|
|
544
532
|
// Example: resource "export" under section "dashboard":
|
|
545
|
-
// Route = /
|
|
533
|
+
// Route = /human-resources/employees/dashboard/export
|
|
546
534
|
// Example: resource "employees-grid" under section "list":
|
|
547
|
-
// Route = /
|
|
535
|
+
// Route = /human-resources/employees/employees-grid (NOT /employees/list/employees-grid)
|
|
548
536
|
new NavigationResourceSeedEntry
|
|
549
537
|
{
|
|
550
538
|
Id = {Resource1Pascal}ResourceId,
|
|
@@ -678,22 +666,20 @@ MCP returns:
|
|
|
678
666
|
### Step B: Write Permissions.cs (Application layer)
|
|
679
667
|
|
|
680
668
|
> **CRITICAL — Permission paths use the SAME kebab-case as NavRoute codes.**
|
|
681
|
-
> `{navRoute}` is already kebab-case (e.g., `
|
|
669
|
+
> `{navRoute}` is already kebab-case (e.g., `human-resources.employees`).
|
|
682
670
|
> NEVER strip hyphens or derive codes from C# class names.
|
|
683
|
-
> FORBIDDEN: `
|
|
684
|
-
> SmartStack.app reference: `
|
|
671
|
+
> FORBIDDEN: `humanresources.employees.read` → CORRECT: `human-resources.employees.read`
|
|
672
|
+
> SmartStack.app reference: `support-client.my-tickets.read`
|
|
685
673
|
|
|
686
674
|
```csharp
|
|
687
675
|
// Add to Application/Common/Authorization/Permissions.cs
|
|
688
|
-
// IMPORTANT: {navRoute} uses kebab-case segments (e.g., "
|
|
676
|
+
// IMPORTANT: {navRoute} uses kebab-case segments (e.g., "human-resources.employees")
|
|
689
677
|
// Do NOT derive permission codes from C# identifiers — use navRoute directly
|
|
690
|
-
public static class {
|
|
678
|
+
public static class {AppPascal}
|
|
691
679
|
{
|
|
692
|
-
public const string Access = "{contextCode}.{appCode}";
|
|
693
|
-
|
|
694
680
|
public static class {ModulePascal}
|
|
695
681
|
{
|
|
696
|
-
public const string View = "{navRoute}.read"; // e.g., "
|
|
682
|
+
public const string View = "{navRoute}.read"; // e.g., "human-resources.employees.read"
|
|
697
683
|
public const string Create = "{navRoute}.create";
|
|
698
684
|
public const string Update = "{navRoute}.update";
|
|
699
685
|
public const string Delete = "{navRoute}.delete";
|
|
@@ -949,11 +935,9 @@ public class ApplicationRoleSeedEntry
|
|
|
949
935
|
|
|
950
936
|
### Context-Based Role Mapping
|
|
951
937
|
|
|
952
|
-
|
|
|
953
|
-
|
|
954
|
-
|
|
|
955
|
-
| `business.*` | CRUD | CRU | CR | R |
|
|
956
|
-
| `personal.*` | CRUD | CRU | CR | R |
|
|
938
|
+
| Application | Admin | Manager | Contributor | Viewer |
|
|
939
|
+
|-------------|-------|---------|-------------|--------|
|
|
940
|
+
| Any | CRUD | CRU | CR | R |
|
|
957
941
|
|
|
958
942
|
### Template
|
|
959
943
|
|
|
@@ -1059,7 +1043,7 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
|
|
|
1059
1043
|
// NOTE: Idempotence is at MODULE level (not application level).
|
|
1060
1044
|
// If the application already exists, we load it and continue to seed any missing modules.
|
|
1061
1045
|
// This allows adding Module 2+ to an existing application without re-running the full seed.
|
|
1062
|
-
var appEntry = NavigationApplicationSeedData.GetApplicationEntry(
|
|
1046
|
+
var appEntry = NavigationApplicationSeedData.GetApplicationEntry();
|
|
1063
1047
|
var existingApp = await context.NavigationApplications
|
|
1064
1048
|
.FirstOrDefaultAsync(a => a.Code == appEntry.Code, ct);
|
|
1065
1049
|
|
|
@@ -1070,13 +1054,8 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
|
|
|
1070
1054
|
}
|
|
1071
1055
|
else
|
|
1072
1056
|
{
|
|
1073
|
-
var parentContext = await context.NavigationContexts
|
|
1074
|
-
.FirstAsync(c => c.Code == "{contextCode}", ct);
|
|
1075
|
-
|
|
1076
|
-
// Re-get entry with resolved contextId
|
|
1077
|
-
appEntry = NavigationApplicationSeedData.GetApplicationEntry(parentContext.Id);
|
|
1078
1057
|
app = NavigationApplication.Create(
|
|
1079
|
-
appEntry.
|
|
1058
|
+
appEntry.Code, appEntry.Label,
|
|
1080
1059
|
appEntry.Description, appEntry.Icon, appEntry.IconType,
|
|
1081
1060
|
appEntry.Route, appEntry.DisplayOrder);
|
|
1082
1061
|
context.NavigationApplications.Add(app);
|
|
@@ -1218,12 +1197,12 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
|
|
|
1218
1197
|
public async Task SeedPermissionsAsync(ICoreDbContext context, CancellationToken ct)
|
|
1219
1198
|
{
|
|
1220
1199
|
var exists = await context.Permissions
|
|
1221
|
-
.AnyAsync(p => p.Path == "{
|
|
1200
|
+
.AnyAsync(p => p.Path == "{appCode}.*", ct);
|
|
1222
1201
|
if (exists) return;
|
|
1223
1202
|
|
|
1224
1203
|
// Application-level wildcard
|
|
1225
1204
|
var appWildcard = Permission.CreateWildcard(
|
|
1226
|
-
"{
|
|
1205
|
+
"{appCode}.*", PermissionLevel.Application,
|
|
1227
1206
|
"Full {appLabel_en} access");
|
|
1228
1207
|
context.Permissions.Add(appWildcard);
|
|
1229
1208
|
|
|
@@ -1245,7 +1224,7 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
|
|
|
1245
1224
|
public async Task SeedRolePermissionsAsync(ICoreDbContext context, CancellationToken ct)
|
|
1246
1225
|
{
|
|
1247
1226
|
var exists = await context.RolePermissions
|
|
1248
|
-
.AnyAsync(rp => rp.Permission!.Path.StartsWith("{
|
|
1227
|
+
.AnyAsync(rp => rp.Permission!.Path.StartsWith("{appCode}."), ct);
|
|
1249
1228
|
if (exists) return;
|
|
1250
1229
|
|
|
1251
1230
|
// CRITICAL: Resolve roles by Code from DB — NEVER use deterministic GUIDs.
|
|
@@ -1258,7 +1237,7 @@ public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
|
|
|
1258
1237
|
|
|
1259
1238
|
// Resolve permissions
|
|
1260
1239
|
var permissions = await context.Permissions
|
|
1261
|
-
.Where(p => p.Path.StartsWith("{
|
|
1240
|
+
.Where(p => p.Path.StartsWith("{appCode}."))
|
|
1262
1241
|
.ToListAsync(ct);
|
|
1263
1242
|
|
|
1264
1243
|
// Apply role-permission mappings from all modules
|
|
@@ -1349,9 +1328,8 @@ Before marking the task as completed, verify ALL:
|
|
|
1349
1328
|
|
|
1350
1329
|
**Application-Level (FIRST — before modules):**
|
|
1351
1330
|
- [ ] `NavigationApplicationSeedData.cs` created (once per application, at `Infrastructure/Persistence/Seeding/Data/`)
|
|
1352
|
-
- [ ] Application GUID is deterministic (SHA256 of `"navigation-application-{
|
|
1353
|
-
- [ ]
|
|
1354
|
-
- [ ] **SeedDataProvider queries context by code at runtime:** `db.NavigationContexts.FirstOrDefaultAsync(c => c.Code == "{contextCode}", ct)`
|
|
1331
|
+
- [ ] Application GUID is deterministic (SHA256 of `"navigation-application-{appCode}"`)
|
|
1332
|
+
- [ ] GetApplicationEntry() takes no parameters (no contextId)
|
|
1355
1333
|
- [ ] Application translations created (4 languages: fr, en, it, de, EntityType = Application)
|
|
1356
1334
|
- [ ] `IClientSeedDataProvider.SeedNavigationAsync()` uses `NavigationApplicationSeedData` (NO hardcoded `{appLabel_en}` / `{appIcon}` placeholders)
|
|
1357
1335
|
- [ ] `ApplicationRolesSeedData.ApplicationId` references `NavigationApplicationSeedData.ApplicationId` (NO `{ApplicationGuid}` placeholder)
|