@atlashub/smartstack-cli 3.37.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.
Files changed (216) hide show
  1. package/dist/index.js +16 -24
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +201 -256
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/scripts/extract-api-endpoints.ts +5 -5
  7. package/scripts/generate-doc-with-mock-ui.ts +10 -17
  8. package/templates/agents/ba-reader.md +9 -9
  9. package/templates/agents/ba-writer.md +12 -15
  10. package/templates/agents/code-reviewer.md +1 -1
  11. package/templates/agents/docs-context-reader.md +1 -1
  12. package/templates/agents/gitflow/merge.md +0 -4
  13. package/templates/agents/gitflow/pr.md +0 -4
  14. package/templates/agents/gitflow/start.md +30 -5
  15. package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +20 -20
  16. package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +16 -24
  17. package/templates/mcp-scaffolding/migrations/seed-roles.cs.hbs +2 -2
  18. package/templates/skills/_resources/mcp-validate-documentation-spec.md +3 -3
  19. package/templates/skills/_shared.md +15 -17
  20. package/templates/skills/ai-prompt/SKILL.md +1 -1
  21. package/templates/skills/ai-prompt/steps/step-00-init.md +47 -0
  22. package/templates/skills/apex/SKILL.md +3 -4
  23. package/templates/skills/apex/_shared.md +10 -20
  24. package/templates/skills/apex/references/analysis-methods.md +141 -0
  25. package/templates/skills/apex/references/challenge-questions.md +1 -21
  26. package/templates/skills/apex/references/core-seed-data.md +35 -57
  27. package/templates/skills/apex/references/examine-build-validation.md +87 -0
  28. package/templates/skills/apex/references/execution-frontend-gates.md +177 -0
  29. package/templates/skills/apex/references/execution-frontend-patterns.md +105 -0
  30. package/templates/skills/apex/references/execution-layer1-rules.md +96 -0
  31. package/templates/skills/apex/references/initialization-challenge-flow.md +110 -0
  32. package/templates/skills/apex/references/planning-layer-mapping.md +151 -0
  33. package/templates/skills/apex/references/post-checks.md +145 -40
  34. package/templates/skills/apex/references/smartstack-api.md +35 -51
  35. package/templates/skills/apex/references/smartstack-frontend.md +17 -17
  36. package/templates/skills/apex/references/smartstack-layers.md +38 -62
  37. package/templates/skills/apex/steps/step-00-init.md +14 -26
  38. package/templates/skills/apex/steps/step-01-analyze.md +10 -143
  39. package/templates/skills/apex/steps/step-02-plan.md +10 -92
  40. package/templates/skills/apex/steps/step-03-execute.md +47 -249
  41. package/templates/skills/apex/steps/step-04-examine.md +14 -78
  42. package/templates/skills/apex/steps/step-05-deep-review.md +2 -2
  43. package/templates/skills/apex/steps/step-08-run-tests.md +2 -0
  44. package/templates/skills/application/SKILL.md +6 -7
  45. package/templates/skills/application/references/backend-controller-hierarchy.md +16 -16
  46. package/templates/skills/application/references/backend-seeding-and-dto-output.md +83 -0
  47. package/templates/skills/application/references/backend-table-prefix-mapping.md +79 -0
  48. package/templates/skills/application/references/backend-verification.md +1 -1
  49. package/templates/skills/application/references/frontend-i18n-and-output.md +67 -0
  50. package/templates/skills/application/references/frontend-route-naming.md +117 -0
  51. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +107 -0
  52. package/templates/skills/application/references/frontend-verification.md +12 -12
  53. package/templates/skills/application/references/init-parameter-detection.md +120 -0
  54. package/templates/skills/application/references/migration-checklist-troubleshooting.md +100 -0
  55. package/templates/skills/application/references/nav-fallback-procedure.md +5 -6
  56. package/templates/skills/application/references/provider-template.md +2 -6
  57. package/templates/skills/application/references/roles-client-project-handling.md +55 -0
  58. package/templates/skills/application/references/roles-fallback-procedure.md +149 -0
  59. package/templates/skills/application/references/test-coverage-requirements.md +213 -0
  60. package/templates/skills/application/references/test-frontend.md +3 -3
  61. package/templates/skills/application/steps/step-00-init.md +11 -141
  62. package/templates/skills/application/steps/step-01-navigation.md +3 -3
  63. package/templates/skills/application/steps/step-02-permissions.md +4 -4
  64. package/templates/skills/application/steps/step-03-roles.md +18 -175
  65. package/templates/skills/application/steps/step-03b-provider.md +1 -2
  66. package/templates/skills/application/steps/step-04-backend.md +19 -110
  67. package/templates/skills/application/steps/step-05-frontend.md +17 -143
  68. package/templates/skills/application/steps/step-06-migration.md +12 -60
  69. package/templates/skills/application/steps/step-07-tests.md +9 -76
  70. package/templates/skills/application/templates-backend.md +29 -27
  71. package/templates/skills/application/templates-frontend.md +48 -48
  72. package/templates/skills/application/templates-seed.md +57 -131
  73. package/templates/skills/business-analyse/SKILL.md +27 -30
  74. package/templates/skills/business-analyse/_architecture.md +6 -6
  75. package/templates/skills/business-analyse/_shared.md +60 -88
  76. package/templates/skills/business-analyse/questionnaire/04-data.md +3 -3
  77. package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
  78. package/templates/skills/business-analyse/questionnaire/13-cross-module.md +1 -1
  79. package/templates/skills/business-analyse/react/application-viewer.md +12 -12
  80. package/templates/skills/business-analyse/react/components.md +8 -12
  81. package/templates/skills/business-analyse/react/schema.md +11 -11
  82. package/templates/skills/business-analyse/references/agent-module-prompt.md +2 -3
  83. package/templates/skills/business-analyse/references/analysis-semantic-checks.md +190 -0
  84. package/templates/skills/business-analyse/references/cache-warming-strategy.md +2 -2
  85. package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +41 -0
  86. package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +74 -0
  87. package/templates/skills/business-analyse/references/cadrage-shared-modules.md +69 -0
  88. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +1 -1
  89. package/templates/skills/business-analyse/references/compilation-structure-cards.md +297 -0
  90. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +2 -2
  91. package/templates/skills/business-analyse/references/deploy-modes.md +5 -5
  92. package/templates/skills/business-analyse/references/detection-strategies.md +7 -7
  93. package/templates/skills/business-analyse/references/handoff-file-templates.md +14 -22
  94. package/templates/skills/business-analyse/references/handoff-mappings.md +4 -4
  95. package/templates/skills/business-analyse/references/handoff-seeddata-generation.md +312 -0
  96. package/templates/skills/business-analyse/references/init-schema-deployment.md +3 -3
  97. package/templates/skills/business-analyse/references/naming-conventions.md +22 -24
  98. package/templates/skills/business-analyse/references/prd-generation.md +2 -2
  99. package/templates/skills/business-analyse/references/review-data-mapping.md +2 -2
  100. package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
  101. package/templates/skills/business-analyse/references/spec-auto-inference.md +3 -3
  102. package/templates/skills/business-analyse/references/team-orchestration.md +49 -6
  103. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
  104. package/templates/skills/business-analyse/references/ui-resource-cards.md +18 -18
  105. package/templates/skills/business-analyse/references/validate-incremental-html.md +2 -2
  106. package/templates/skills/business-analyse/references/validation-checklist.md +2 -2
  107. package/templates/skills/business-analyse/schemas/application-schema.json +4 -5
  108. package/templates/skills/business-analyse/schemas/project-schema.json +1 -6
  109. package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +2 -3
  110. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +4 -4
  111. package/templates/skills/business-analyse/steps/step-00-init.md +8 -17
  112. package/templates/skills/business-analyse/steps/step-01-cadrage.md +35 -198
  113. package/templates/skills/business-analyse/steps/step-01b-applications.md +16 -20
  114. package/templates/skills/business-analyse/steps/step-02-decomposition.md +1 -1
  115. package/templates/skills/business-analyse/steps/step-03a1-setup.md +4 -4
  116. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +1 -1
  117. package/templates/skills/business-analyse/steps/step-03b-ui.md +4 -4
  118. package/templates/skills/business-analyse/steps/step-03c-compile.md +66 -140
  119. package/templates/skills/business-analyse/steps/step-03d-validate.md +2 -2
  120. package/templates/skills/business-analyse/steps/step-04a-collect.md +2 -2
  121. package/templates/skills/business-analyse/steps/step-04b-analyze.md +42 -160
  122. package/templates/skills/business-analyse/steps/step-04c-decide.md +1 -1
  123. package/templates/skills/business-analyse/steps/step-05a-handoff.md +74 -104
  124. package/templates/skills/business-analyse/steps/step-05b-deploy.md +13 -11
  125. package/templates/skills/business-analyse/steps/step-06-review.md +3 -3
  126. package/templates/skills/business-analyse/templates/tpl-frd.md +13 -13
  127. package/templates/skills/business-analyse/templates/tpl-handoff.md +12 -12
  128. package/templates/skills/business-analyse/templates-frd.md +25 -25
  129. package/templates/skills/business-analyse/templates-react.md +15 -21
  130. package/templates/skills/controller/SKILL.md +1 -1
  131. package/templates/skills/controller/postman-templates.md +1 -1
  132. package/templates/skills/controller/references/controller-code-templates.md +2 -2
  133. package/templates/skills/controller/references/mcp-scaffold-workflow.md +209 -0
  134. package/templates/skills/controller/references/permission-sync-templates.md +13 -16
  135. package/templates/skills/controller/steps/step-00-init.md +11 -11
  136. package/templates/skills/controller/steps/step-03-generate.md +64 -103
  137. package/templates/skills/controller/templates.md +67 -71
  138. package/templates/skills/debug/SKILL.md +13 -218
  139. package/templates/skills/debug/steps/step-00-init.md +57 -0
  140. package/templates/skills/debug/steps/step-01-analyze.md +219 -0
  141. package/templates/skills/debug/steps/step-02-resolve.md +85 -0
  142. package/templates/skills/documentation/SKILL.md +49 -345
  143. package/templates/skills/documentation/data-schema.md +11 -8
  144. package/templates/skills/documentation/steps/step-00-init.md +70 -0
  145. package/templates/skills/documentation/steps/step-01-scan.md +113 -0
  146. package/templates/skills/documentation/steps/step-02-generate.md +231 -0
  147. package/templates/skills/documentation/steps/step-03-validate.md +238 -0
  148. package/templates/skills/documentation/templates.md +480 -322
  149. package/templates/skills/efcore/references/both-contexts.md +32 -0
  150. package/templates/skills/efcore/references/database-operations.md +67 -0
  151. package/templates/skills/efcore/references/destructive-operations.md +38 -0
  152. package/templates/skills/efcore/references/reset-operations.md +81 -0
  153. package/templates/skills/efcore/references/seed-methods.md +86 -0
  154. package/templates/skills/efcore/references/shared-init-functions.md +250 -0
  155. package/templates/skills/efcore/references/sql-objects-injection.md +61 -0
  156. package/templates/skills/efcore/references/troubleshooting.md +81 -0
  157. package/templates/skills/efcore/steps/db/step-deploy.md +1 -32
  158. package/templates/skills/efcore/steps/db/step-reset.md +7 -103
  159. package/templates/skills/efcore/steps/db/step-seed.md +10 -132
  160. package/templates/skills/efcore/steps/db/step-status.md +5 -44
  161. package/templates/skills/efcore/steps/migration/step-03-validate.md +8 -62
  162. package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +1 -57
  163. package/templates/skills/efcore/steps/shared/step-00-init.md +11 -254
  164. package/templates/skills/efcore/steps/squash/step-03-create.md +1 -58
  165. package/templates/skills/feature-full/SKILL.md +1 -1
  166. package/templates/skills/feature-full/steps/step-00-init.md +57 -0
  167. package/templates/skills/feature-full/steps/step-01-implementation.md +1 -1
  168. package/templates/skills/gitflow/SKILL.md +1 -1
  169. package/templates/skills/gitflow/_shared.md +23 -0
  170. package/templates/skills/gitflow/references/commit-message-generation.md +58 -0
  171. package/templates/skills/gitflow/references/commit-migration-validation.md +49 -0
  172. package/templates/skills/gitflow/references/finish-cleanup.md +51 -0
  173. package/templates/skills/gitflow/references/finish-version-bumping.md +45 -0
  174. package/templates/skills/gitflow/references/init-environment-detection.md +41 -0
  175. package/templates/skills/gitflow/references/init-questions.md +185 -0
  176. package/templates/skills/gitflow/references/init-structure-creation.md +71 -0
  177. package/templates/skills/gitflow/references/init-version-detection.md +21 -0
  178. package/templates/skills/gitflow/references/init-workspace-detection.md +43 -0
  179. package/templates/skills/gitflow/references/merge-ci-status.md +36 -0
  180. package/templates/skills/gitflow/references/merge-execution.md +62 -0
  181. package/templates/skills/gitflow/references/merge-pr-context.md +76 -0
  182. package/templates/skills/gitflow/references/pr-build-checks.md +60 -0
  183. package/templates/skills/gitflow/references/pr-generation.md +58 -0
  184. package/templates/skills/gitflow/references/start-branch-normalization.md +28 -0
  185. package/templates/skills/gitflow/references/start-worktree-creation.md +50 -0
  186. package/templates/skills/gitflow/references/sync-push-verify.md +44 -0
  187. package/templates/skills/gitflow/references/sync-rebase-conflicts.md +38 -0
  188. package/templates/skills/gitflow/steps/step-commit.md +12 -91
  189. package/templates/skills/gitflow/steps/step-finish.md +15 -159
  190. package/templates/skills/gitflow/steps/step-init.md +24 -326
  191. package/templates/skills/gitflow/steps/step-merge.md +17 -176
  192. package/templates/skills/gitflow/steps/step-pr.md +10 -116
  193. package/templates/skills/gitflow/steps/step-start.md +16 -109
  194. package/templates/skills/gitflow/steps/step-sync.md +6 -69
  195. package/templates/skills/ralph-loop/SKILL.md +6 -0
  196. package/templates/skills/ralph-loop/references/category-completeness.md +185 -0
  197. package/templates/skills/ralph-loop/references/compact-loop.md +1 -1
  198. package/templates/skills/ralph-loop/references/init-resume-recovery.md +127 -0
  199. package/templates/skills/ralph-loop/references/module-transition.md +151 -0
  200. package/templates/skills/ralph-loop/references/multi-module-queue.md +171 -0
  201. package/templates/skills/ralph-loop/references/parallel-execution.md +246 -0
  202. package/templates/skills/ralph-loop/references/task-transform-legacy.md +6 -9
  203. package/templates/skills/ralph-loop/references/team-orchestration.md +45 -3
  204. package/templates/skills/ralph-loop/steps/step-00-init.md +36 -109
  205. package/templates/skills/ralph-loop/steps/step-01-task.md +15 -163
  206. package/templates/skills/ralph-loop/steps/step-02-execute.md +8 -154
  207. package/templates/skills/ralph-loop/steps/step-04-check.md +21 -73
  208. package/templates/skills/review-code/references/owasp-api-top10.md +5 -5
  209. package/templates/skills/review-code/references/smartstack-conventions.md +11 -11
  210. package/templates/skills/validate-feature/references/api-smoke-tests.md +140 -0
  211. package/templates/skills/validate-feature/references/db-validation-checks.md +180 -0
  212. package/templates/skills/validate-feature/steps/step-01-compile.md +5 -2
  213. package/templates/skills/validate-feature/steps/step-04-api-smoke.md +34 -145
  214. package/templates/skills/validate-feature/steps/step-05-db-validation.md +74 -260
  215. package/templates/skills/workflow/SKILL.md +1 -1
  216. package/templates/skills/workflow/steps/step-00-init.md +57 -0
@@ -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 (context/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.
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 context, verify MCP, define hierarchy (5 levels), challenge need |
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 context detected (context/app/module)
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 | `{context}.{app}.{module}.{action}` | 3+1 segments |
76
- | Section | `{context}.{app}.{module}.{section}.{action}` | 4+1 segments |
77
- | Resource | `{context}.{app}.{module}.{section}.{resource}.{action}` | 5+1 segments |
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: `business.human-resources.employees.read` (3+1)
81
- - Section: `business.human-resources.employees.departments.read` (4+1)
82
- - Resource: `business.human-resources.employees.departments.export.execute` (5+1)
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: `business.support-client.my-tickets.read`, `platform.administration.email-templates.read`
78
+ > SmartStack.app reference: `support-client.my-tickets.read`, `administration.email-templates.read`
89
79
  >
90
- > **FORBIDDEN:** `business.humanresources.employees.read` (concatenated — no kebab-case)
91
- > **CORRECT:** `business.human-resources.employees.read` (kebab-case — matches NavRoute)
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 context/application/module structure |
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 in the {context_code} context"
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. "business.human-resources.projects"
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?.context || 'business'}.${prd.source?.application || prd.metadata?.module}.${task.module}`;
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` | `business.human-resources.projects` | `_seedDataMeta.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 (not context — contexts are pre-seeded by SmartStack core)
78
+ // Deterministic GUID for APPLICATION
87
79
  public static readonly Guid ApplicationId =
88
- GenerateDeterministicGuid("navigation-application-{contextCode}.{appCode}");
89
- // Example: GenerateDeterministicGuid("navigation-application-business.human-resources")
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-{contextCode}.{appCode}");
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(Guid contextId)
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("/{contextCode}/{appCode}"),
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-business.human-resources.projects")
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($"/{contextCode}/{appCode}/{moduleCode}"),
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: /business/HumanResources/TimeManagement → /business/human-resources/time-management
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-business.human-resources.employees.list")
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-business.human-resources.employees.list.employees-grid")
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., `/business/human-resources/employees`) — NO `/list` suffix
422
- > - `detail` section route = module route + `/:id` (e.g., `/business/human-resources/employees/:id`) — NOT `/detail/:id`
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 = /business/human-resources/employees/dashboard/export
533
+ // Route = /human-resources/employees/dashboard/export
546
534
  // Example: resource "employees-grid" under section "list":
547
- // Route = /business/human-resources/employees/employees-grid (NOT /employees/list/employees-grid)
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., `business.human-resources.employees`).
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: `business.humanresources.employees.read` → CORRECT: `business.human-resources.employees.read`
684
- > SmartStack.app reference: `business.support-client.my-tickets.read`
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., "business.human-resources.employees")
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 {ContextPascal}
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., "business.human-resources.employees.read"
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
- | Context | Admin | Manager | Contributor | Viewer |
953
- |---------|-------|---------|-------------|--------|
954
- | `platform.*` | CRUD | CRU | CR | R |
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(Guid.Empty); // contextId resolved below
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.ContextId, appEntry.Code, appEntry.Label,
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 == "{contextCode}.{appCode}.*", ct);
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
- "{contextCode}.{appCode}.*", PermissionLevel.Application,
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("{contextCode}.{appCode}."), ct);
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("{contextCode}.{appCode}."))
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-{contextCode}.{appCode}"`)
1353
- - [ ] **NO ContextId constant in SeedConstants** — Context IDs are pre-seeded by SmartStack core (hardcoded GUIDs, NOT deterministic)
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)
@@ -0,0 +1,87 @@
1
+ # Examine Build & Migration Validation
2
+
3
+ > **Loaded by:** step-04-examine.md (sections 4-5)
4
+ > **Purpose:** Build verification, migration validation, database testing procedures.
5
+
6
+ ---
7
+
8
+ ## Build Verification
9
+
10
+ ```bash
11
+ # Cleanup corrupted EF Core design-time artifacts (Roslyn BuildHost bug on Windows/WSL)
12
+ for d in src/*/bin?Debug bin?Debug; do [ -d "$d" ] && echo "Removing corrupted artifact: $d" && rm -rf "$d"; done
13
+
14
+ # Backend
15
+ dotnet clean && dotnet restore && dotnet build
16
+
17
+ # Post-build cleanup (WSL Roslyn recreates literal bin\Debug folders after each build)
18
+ for d in src/*/bin?Debug bin?Debug; do [ -d "$d" ] && rm -rf "$d"; done
19
+
20
+ # Frontend (if applicable)
21
+ npm run typecheck
22
+ ```
23
+
24
+ **BLOCKING:** Both must pass. If failure, classify error per `references/error-classification.md`:
25
+ - Category A (missing package) → `dotnet add package` → rebuild
26
+ - Category B (assembly conflict) → resolve version → rebuild
27
+ - Category C (DI missing) → fix DI registration → rebuild
28
+ - Category D (migration broken) → fix migration → rebuild
29
+ - Category E (config) → fix config → rebuild
30
+ - Category F (source code) → fix code → rebuild
31
+
32
+ ---
33
+
34
+ ## Migration Validation (if needs_migration)
35
+
36
+ ### Pending Model Changes Check
37
+
38
+ ```bash
39
+ INFRA_PROJECT=$(ls src/*Infrastructure*/*.csproj 2>/dev/null | head -1)
40
+ API_PROJECT=$(ls src/*Api*/*.csproj 2>/dev/null | head -1)
41
+
42
+ dotnet ef migrations has-pending-model-changes \
43
+ --project "$INFRA_PROJECT" \
44
+ --startup-project "$API_PROJECT"
45
+ ```
46
+
47
+ **BLOCKING** if pending changes detected → migration is missing.
48
+
49
+ ### Migration Application Test (SQL Server LocalDB)
50
+
51
+ ```bash
52
+ DB_NAME="SmartStack_Apex_Examine_$(date +%s)"
53
+ CONN_STRING="Server=(localdb)\\MSSQLLocalDB;Database=$DB_NAME;Integrated Security=true;TrustServerCertificate=true;Connect Timeout=120;"
54
+
55
+ dotnet ef database update \
56
+ --connection "$CONN_STRING" \
57
+ --project "$INFRA_PROJECT" \
58
+ --startup-project "$API_PROJECT"
59
+ ```
60
+
61
+ **BLOCKING** if migration fails on SQL Server. Common issues:
62
+ - SQLite-only syntax in migrations (fix: regenerate migration)
63
+ - Column type mismatches (fix: update EF configuration)
64
+ - Missing foreign key targets (fix: reorder migrations)
65
+
66
+ ### Integration Tests on Real SQL Server
67
+
68
+ ```bash
69
+ # Integration tests use DatabaseFixture → real SQL Server LocalDB
70
+ # This validates: LINQ→SQL, multi-tenant isolation, soft delete, EF configs
71
+ INT_TEST_PROJECT=$(ls tests/*Tests.Integration*/*.csproj 2>/dev/null | head -1)
72
+ if [ -n "$INT_TEST_PROJECT" ]; then
73
+ dotnet test "$INT_TEST_PROJECT" --no-build --verbosity normal
74
+ fi
75
+ ```
76
+
77
+ Tests running against SQL Server catch issues that SQLite misses:
78
+ - Case sensitivity in string comparisons
79
+ - Date/time function differences
80
+ - IDENTITY vs AUTOINCREMENT behavior
81
+ - Global query filter translation to T-SQL
82
+
83
+ ### Cleanup
84
+
85
+ ```bash
86
+ sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "IF DB_ID('$DB_NAME') IS NOT NULL BEGIN ALTER DATABASE [$DB_NAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [$DB_NAME]; END" 2>/dev/null
87
+ ```