@atlashub/smartstack-cli 4.80.0 → 5.0.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/.documentation/agents.html +124 -585
- package/.documentation/ba-develop.html +852 -0
- package/.documentation/ba-skills.html +465 -0
- package/.documentation/business-analyse.html +385 -1570
- package/.documentation/cli-commands.html +162 -799
- package/.documentation/commands.html +902 -1338
- package/.documentation/css/styles.css +34 -1
- package/.documentation/efcore.html +161 -2599
- package/.documentation/gitflow.html +62 -105
- package/.documentation/hooks.html +94 -343
- package/.documentation/index.html +116 -385
- package/.documentation/init.html +217 -1566
- package/.documentation/installation.html +121 -1470
- package/.documentation/license.html +90 -450
- package/.documentation/ralph-loop.html +105 -602
- package/dist/index.js +9421 -79036
- package/dist/index.js.map +1 -1
- package/package.json +5 -20
- package/scripts/generate-docs/README.md +87 -0
- package/scripts/generate-docs/index.ts +175 -0
- package/scripts/generate-docs/lib/context-builder.ts +81 -0
- package/scripts/generate-docs/lib/handlebars-setup.ts +162 -0
- package/scripts/generate-docs/lib/markdown-parser.ts +86 -0
- package/scripts/generate-docs/lib/sidebar-builder.ts +80 -0
- package/scripts/generate-docs/lib/skill-parser.ts +171 -0
- package/scripts/generate-docs/lib/stats.ts +32 -0
- package/scripts/generate-docs/lib/version.ts +17 -0
- package/scripts/generate-docs/templates/layout.hbs +33 -0
- package/scripts/generate-docs/templates/pages/_generic.hbs +12 -0
- package/scripts/generate-docs/templates/pages/ba-develop.hbs +10 -0
- package/scripts/generate-docs/templates/pages/ba-skills.hbs +8 -0
- package/scripts/generate-docs/templates/pages/business-analyse.hbs +1 -0
- package/scripts/generate-docs/templates/pages/commands.hbs +13 -0
- package/scripts/generate-docs/templates/pages/gitflow.hbs +2164 -0
- package/scripts/generate-docs/templates/pages/index.hbs +5 -0
- package/scripts/generate-docs/templates/partials/breadcrumb.hbs +6 -0
- package/scripts/generate-docs/templates/partials/header.hbs +22 -0
- package/scripts/generate-docs/templates/partials/sidebar.hbs +32 -0
- package/scripts/generate-docs/templates/partials/skill-card.hbs +22 -0
- package/scripts/generate-docs/templates/partials/skill-grid.hbs +5 -0
- package/scripts/generate-docs/templates/partials/skill-table.hbs +18 -0
- package/scripts/generate-docs/templates/partials/stats-bar.hbs +20 -0
- package/scripts/test-migration-program-cs.mts +94 -0
- package/templates/agents/explore-codebase.md +2 -3
- package/templates/agents/explore-docs.md +5 -5
- package/templates/hooks/hooks.json +0 -9
- package/templates/project/Program.cs.template +17 -5
- package/templates/project/appsettings.json.template +208 -195
- package/templates/project/claude-md/api.CLAUDE.md.template +27 -2
- package/templates/project/patch-smartstack-theme.cjs.template +42 -0
- package/templates/scripts/statusline/README.md +47 -0
- package/templates/scripts/statusline/index.js +224 -0
- package/templates/skills/CLAUDE.md +235 -0
- package/templates/skills/ba-develop/SKILL.md +310 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/__tests__/compute-page-diff.test.ts +177 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/compute-diff.ts +51 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/disk-drift.ts +55 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/index.ts +89 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/scan-pagespecs.ts +115 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/types.ts +63 -0
- package/templates/skills/ba-develop/cli/compute-page-diff/validate.ts +20 -0
- package/templates/skills/ba-develop/cli/update-snapshot/__tests__/update-snapshot.test.ts +73 -0
- package/templates/skills/ba-develop/cli/update-snapshot/execute.ts +24 -0
- package/templates/skills/ba-develop/cli/update-snapshot/index.ts +61 -0
- package/templates/skills/ba-develop/cli/update-snapshot/types.ts +40 -0
- package/templates/skills/ba-develop/cli/update-snapshot/validate.ts +17 -0
- package/templates/skills/ba-develop/references/anti-patterns.md +101 -0
- package/templates/skills/ba-develop/references/auto-healing.md +191 -0
- package/templates/skills/ba-develop/references/commit-checkpoints.md +79 -0
- package/templates/skills/ba-develop/references/gates.md +380 -0
- package/templates/skills/ba-develop/references/output-contract.md +95 -0
- package/templates/skills/ba-develop/references/phases-detail.md +592 -0
- package/templates/skills/ba-develop-plan/SKILL.md +239 -0
- package/templates/skills/ba-develop-plan/cli/preflight-develop-plan/__tests__/validate.test.ts +225 -0
- package/templates/skills/ba-develop-plan/cli/preflight-develop-plan/index.ts +102 -0
- package/templates/skills/ba-develop-plan/cli/preflight-develop-plan/types.ts +121 -0
- package/templates/skills/ba-develop-plan/cli/preflight-develop-plan/validate.ts +261 -0
- package/templates/skills/business-analyse/_workflow/README.md +34 -0
- package/templates/skills/business-analyse/_workflow/ba-files.md +174 -0
- package/templates/skills/business-analyse/_workflow/code-discipline.md +104 -0
- package/templates/skills/business-analyse/_workflow/communication.md +63 -0
- package/templates/skills/business-analyse/_workflow/completeAuto-discipline.md +79 -0
- package/templates/skills/business-analyse/_workflow/context-documents.md +45 -0
- package/templates/skills/business-analyse/_workflow/doc-templates.md +318 -0
- package/templates/skills/business-analyse/audit-actors/SKILL.md +97 -0
- package/templates/skills/business-analyse/audit-cross-dimension/SKILL.md +127 -0
- package/templates/skills/business-analyse/audit-cross-ref-code/SKILL.md +119 -0
- package/templates/skills/business-analyse/audit-data-model/SKILL.md +343 -0
- package/templates/skills/business-analyse/audit-menu/SKILL.md +97 -0
- package/templates/skills/business-analyse/audit-prd/SKILL.md +479 -0
- package/templates/skills/business-analyse/audit-pre-dev/SKILL.md +135 -0
- package/templates/skills/business-analyse/audit-rbac/SKILL.md +93 -0
- package/templates/skills/business-analyse/audit-rules/SKILL.md +182 -0
- package/templates/skills/business-analyse/audit-screens/SKILL.md +169 -0
- package/templates/skills/business-analyse/audit-sections/SKILL.md +174 -0
- package/templates/skills/business-analyse/audit-use-cases/SKILL.md +245 -0
- package/templates/skills/business-analyse/create-actors/SKILL.md +129 -0
- package/templates/skills/business-analyse/create-ba-order/SKILL.md +182 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/__tests__/generate.test.ts +151 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/__tests__/graph.test.ts +173 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/generate.ts +273 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/graph.ts +193 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/index.ts +108 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/types.ts +106 -0
- package/templates/skills/business-analyse/create-ba-order/cli/create-ba-order/validate.ts +79 -0
- package/templates/skills/business-analyse/create-business-rules/SKILL.md +302 -0
- package/templates/skills/business-analyse/create-business-rules/levels/access-rules.md +105 -0
- package/templates/skills/business-analyse/create-business-rules/levels/elaborate.md +193 -0
- package/templates/skills/business-analyse/create-business-rules/levels/identify.md +157 -0
- package/templates/skills/business-analyse/create-business-rules/levels/link.md +86 -0
- package/templates/skills/business-analyse/create-data-model/SKILL.md +319 -0
- package/templates/skills/business-analyse/create-data-model/levels/attributes.md +130 -0
- package/templates/skills/business-analyse/create-data-model/levels/identify.md +100 -0
- package/templates/skills/business-analyse/create-data-model/levels/relationships.md +97 -0
- package/templates/skills/business-analyse/create-menu/SKILL.md +191 -0
- package/templates/skills/business-analyse/create-menu/levels/applications.md +85 -0
- package/templates/skills/business-analyse/create-menu/levels/modules.md +81 -0
- package/templates/skills/business-analyse/create-menu/levels/resources.md +75 -0
- package/templates/skills/business-analyse/create-menu/levels/sections.md +82 -0
- package/templates/skills/business-analyse/create-plan-development/SKILL.md +93 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/__tests__/graph.test.ts +271 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/__tests__/parse.test.ts +177 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/generate.ts +317 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/graph.ts +233 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/index.ts +106 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/parse.ts +346 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/types.ts +160 -0
- package/templates/skills/business-analyse/create-plan-development/cli/create-plan-development/validate.ts +118 -0
- package/templates/skills/business-analyse/create-prd/SKILL.md +228 -0
- package/templates/skills/business-analyse/create-rbac/SKILL.md +255 -0
- package/templates/skills/business-analyse/create-rbac/levels/detail.md +86 -0
- package/templates/skills/business-analyse/create-rbac/levels/discovery.md +63 -0
- package/templates/skills/business-analyse/create-rbac/levels/review.md +66 -0
- package/templates/skills/business-analyse/create-screen/SKILL.md +386 -0
- package/templates/skills/business-analyse/create-screen/levels/dashboard-screens.md +94 -0
- package/templates/skills/business-analyse/create-screen/levels/form-screens.md +142 -0
- package/templates/skills/business-analyse/create-screen/levels/home-screens.md +151 -0
- package/templates/skills/business-analyse/create-screen/levels/kanban-screens.md +86 -0
- package/templates/skills/business-analyse/create-screen/levels/list-screens.md +134 -0
- package/templates/skills/business-analyse/create-screen/references/post-check.md +101 -0
- package/templates/skills/business-analyse/create-screen/references/react-templates.md +252 -0
- package/templates/skills/business-analyse/create-screen/references/smartcomponents.md +419 -0
- package/templates/skills/business-analyse/create-screen/references/type-mapping.md +150 -0
- package/templates/skills/business-analyse/create-use-case/SKILL.md +347 -0
- package/templates/skills/business-analyse/create-use-case/levels/detail.md +136 -0
- package/templates/skills/business-analyse/create-use-case/levels/discovery.md +110 -0
- package/templates/skills/business-analyse/loop/SKILL.md +401 -0
- package/templates/skills/business-analyse/modeling-detail/SKILL.md +241 -0
- package/templates/skills/business-analyse/modeling-inventory/SKILL.md +174 -0
- package/templates/skills/business-analyse/reconcile-menu/SKILL.md +180 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/__tests__/clean.test.ts +266 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/__tests__/detect.test.ts +231 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/__tests__/scan.test.ts +154 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/clean.ts +319 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/detect.ts +256 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/index.ts +126 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/scan.ts +175 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/types.ts +136 -0
- package/templates/skills/business-analyse/reconcile-menu/cli/reconcile-menu/validate.ts +32 -0
- package/templates/skills/check-version/SKILL.md +196 -196
- package/templates/skills/cli-app-sync/SKILL.md +9 -9
- package/templates/skills/cli-app-sync/references/comparison-map.md +4 -4
- package/templates/skills/cli-app-sync/references/diff-entities.md +6 -6
- package/templates/skills/conventions/SKILL.md +64 -0
- package/templates/skills/dev-start/SKILL.md +190 -237
- package/templates/skills/development/SKILL.md +87 -0
- package/templates/skills/development/audit/SKILL.md +156 -0
- package/templates/skills/development/audit/routing-dynamic/SKILL.md +196 -0
- package/templates/skills/development/audit-dev-api/SKILL.md +331 -0
- package/templates/skills/development/audit-dev-api/cli/audit-dev-api/__tests__/end-to-end.test.ts +364 -0
- package/templates/skills/development/audit-dev-api/cli/audit-dev-api/audit.ts +646 -0
- package/templates/skills/development/audit-dev-api/cli/audit-dev-api/index.ts +140 -0
- package/templates/skills/development/audit-dev-api/cli/audit-dev-api/types.ts +158 -0
- package/templates/skills/development/audit-dev-api/cli/audit-dev-api/validate.ts +45 -0
- package/templates/skills/development/audit-dev-core/SKILL.md +182 -0
- package/templates/skills/development/audit-dev-data/SKILL.md +195 -0
- package/templates/skills/development/audit-dev-domain/SKILL.md +184 -0
- package/templates/skills/development/audit-dev-frontend/SKILL.md +530 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-actions-alignment/__tests__/end-to-end.test.ts +202 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-actions-alignment/apply.ts +31 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-actions-alignment/audit.ts +734 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-actions-alignment/index.ts +125 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-actions-alignment/types.ts +165 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-actions-alignment/validate.ts +36 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-frontend/__tests__/dev-ui-022.test.ts +193 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-frontend/apply.ts +374 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-frontend/audit.ts +1126 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-frontend/index.ts +141 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-frontend/types.ts +218 -0
- package/templates/skills/development/audit-dev-frontend/cli/audit-dev-frontend/validate.ts +80 -0
- package/templates/skills/development/audit-dev-tests/SKILL.md +82 -0
- package/templates/skills/development/audit-dev-tests/cli/audit-dev-tests/__tests__/audit.test.ts +220 -0
- package/templates/skills/development/audit-dev-tests/cli/audit-dev-tests/audit.ts +185 -0
- package/templates/skills/development/audit-dev-tests/cli/audit-dev-tests/index.ts +84 -0
- package/templates/skills/development/audit-dev-tests/cli/audit-dev-tests/types.ts +48 -0
- package/templates/skills/development/audit-dev-tests/cli/audit-dev-tests/validate.ts +36 -0
- package/templates/skills/development/audit-dev-wire/SKILL.md +144 -0
- package/templates/skills/development/audit-dev-wire/cli/audit-dev-wire/__tests__/audit.test.ts +171 -0
- package/templates/skills/development/audit-dev-wire/cli/audit-dev-wire/audit.ts +307 -0
- package/templates/skills/development/audit-dev-wire/cli/audit-dev-wire/index.ts +139 -0
- package/templates/skills/development/audit-dev-wire/cli/audit-dev-wire/types.ts +110 -0
- package/templates/skills/development/audit-dev-wire/cli/audit-dev-wire/validate.ts +16 -0
- package/templates/skills/development/backend/business-layer/SKILL.md +255 -0
- package/templates/skills/development/backend/business-layer/cli/scaffold-business/__tests__/generate.test.ts +254 -0
- package/templates/skills/development/backend/business-layer/cli/scaffold-business/generate.ts +842 -0
- package/templates/skills/development/backend/business-layer/cli/scaffold-business/index.ts +56 -0
- package/templates/skills/development/backend/business-layer/cli/scaffold-business/types.ts +112 -0
- package/templates/skills/development/backend/business-layer/cli/scaffold-business/validate.ts +24 -0
- package/templates/skills/development/backend/controller/SKILL.md +154 -0
- package/templates/skills/development/backend/controller/cli/scaffold-controller/__tests__/generate.test.ts +345 -0
- package/templates/skills/development/backend/controller/cli/scaffold-controller/generate.ts +280 -0
- package/templates/skills/development/backend/controller/cli/scaffold-controller/index.ts +49 -0
- package/templates/skills/development/backend/controller/cli/scaffold-controller/types.ts +72 -0
- package/templates/skills/development/backend/controller/cli/scaffold-controller/validate.ts +14 -0
- package/templates/skills/development/backend/core-seed/SKILL.md +177 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/__tests__/build-spec.test.ts +163 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/__tests__/generate.test.ts +330 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/__tests__/validate.test.ts +126 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/build-spec.ts +287 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/generate.ts +826 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/index.ts +188 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/types.ts +163 -0
- package/templates/skills/development/backend/core-seed/cli/scaffold-core-seed/validate.ts +129 -0
- package/templates/skills/development/backend/data-layer/SKILL.md +163 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-entity/__tests__/generate.test.ts +155 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-entity/generate.ts +232 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-entity/index.ts +34 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-entity/types.ts +60 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-entity/validate.ts +42 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-migration/execute.ts +13 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-migration/index.ts +25 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-migration/types.ts +11 -0
- package/templates/skills/development/backend/data-layer/cli/scaffold-migration/validate.ts +9 -0
- package/templates/skills/development/backend/screen-controller/SKILL.md +169 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/__tests__/generate.test.ts +329 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/__tests__/hub-views.test.ts +105 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/__tests__/parse-pagespec.test.ts +137 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/generate.ts +437 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/index.ts +108 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/parse-pagespec.ts +104 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/types.ts +101 -0
- package/templates/skills/development/backend/screen-controller/cli/scaffold-screen-controller/validate.ts +26 -0
- package/templates/skills/development/backend/seed-data/SKILL.md +91 -0
- package/templates/skills/development/backend/seed-data/cli/scaffold-seed/generate.ts +471 -0
- package/templates/skills/development/backend/seed-data/cli/scaffold-seed/index.ts +74 -0
- package/templates/skills/development/backend/seed-data/cli/scaffold-seed/types.ts +104 -0
- package/templates/skills/development/backend/seed-data/cli/scaffold-seed/validate.ts +63 -0
- package/templates/skills/development/backend/structure/SKILL.md +47 -0
- package/templates/skills/development/debug/SKILL.md +62 -0
- package/templates/skills/development/debug/audit-bug/SKILL.md +185 -0
- package/templates/skills/development/debug/backend/SKILL.md +114 -0
- package/templates/skills/development/debug/discuss-bug/SKILL.md +193 -0
- package/templates/skills/development/debug/fix-bug/SKILL.md +172 -0
- package/templates/skills/development/debug/frontend/SKILL.md +215 -0
- package/templates/skills/development/frontend/api-client/SKILL.md +158 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/__tests__/generate.test.ts +1180 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/__tests__/screen-strata-contract.test.ts +261 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/__tests__/url-parity.test.ts +201 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/generate.ts +875 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/index.ts +36 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/types.ts +251 -0
- package/templates/skills/development/frontend/api-client/cli/scaffold-api-client/validate.ts +10 -0
- package/templates/skills/development/frontend/auth/SKILL.md +77 -0
- package/templates/skills/development/frontend/auth/cli/scaffold-frontend-auth/generate.ts +306 -0
- package/templates/skills/development/frontend/auth/cli/scaffold-frontend-auth/index.ts +179 -0
- package/templates/skills/development/frontend/auth/cli/scaffold-frontend-auth/types.ts +22 -0
- package/templates/skills/development/frontend/auth/cli/scaffold-frontend-auth/validate.ts +37 -0
- package/templates/skills/development/frontend/component/SKILL.md +347 -0
- package/templates/skills/development/frontend/component/cli/scaffold-component/__tests__/generate.test.ts +1237 -0
- package/templates/skills/development/frontend/component/cli/scaffold-component/generate.ts +1923 -0
- package/templates/skills/development/frontend/component/cli/scaffold-component/index.ts +155 -0
- package/templates/skills/development/frontend/component/cli/scaffold-component/types.ts +290 -0
- package/templates/skills/development/frontend/component/cli/scaffold-component/validate.ts +16 -0
- package/templates/skills/development/frontend/component/cli/validate-page/__tests__/execute.test.ts +231 -0
- package/templates/skills/development/frontend/component/cli/validate-page/execute.ts +598 -0
- package/templates/skills/development/frontend/component/cli/validate-page/index.ts +88 -0
- package/templates/skills/development/frontend/component/cli/validate-page/types.ts +58 -0
- package/templates/skills/development/frontend/component/cli/validate-page/validate.ts +28 -0
- package/templates/skills/development/frontend/component/patterns/README.md +42 -0
- package/templates/skills/development/frontend/component/patterns/detail-page.md +133 -0
- package/templates/skills/development/frontend/component/patterns/entity-card.md +148 -0
- package/templates/skills/development/frontend/component/patterns/form-page.md +191 -0
- package/templates/skills/development/frontend/component/patterns/kanban-board.md +195 -0
- package/templates/skills/development/frontend/component/patterns/list-page.md +175 -0
- package/templates/skills/development/frontend/extension-config/SKILL.md +108 -0
- package/templates/skills/development/frontend/extension-config/cli/scaffold-extension-config/generate.ts +64 -0
- package/templates/skills/development/frontend/extension-config/cli/scaffold-extension-config/index.ts +70 -0
- package/templates/skills/development/frontend/extension-config/cli/scaffold-extension-config/types.ts +27 -0
- package/templates/skills/development/frontend/extension-config/cli/scaffold-extension-config/validate.ts +16 -0
- package/templates/skills/development/frontend/layout/SKILL.md +52 -0
- package/templates/skills/development/frontend/layout/cli/scaffold-layout/__tests__/generate.test.ts +66 -0
- package/templates/skills/development/frontend/layout/cli/scaffold-layout/generate.ts +175 -0
- package/templates/skills/development/frontend/layout/cli/scaffold-layout/index.ts +104 -0
- package/templates/skills/development/frontend/layout/cli/scaffold-layout/types.ts +17 -0
- package/templates/skills/development/frontend/layout/cli/scaffold-layout/validate.ts +37 -0
- package/templates/skills/development/frontend/routes/SKILL.md +152 -0
- package/templates/skills/development/frontend/routes/cli/aggregate-component-registry/generate.ts +216 -0
- package/templates/skills/development/frontend/routes/cli/aggregate-component-registry/index.ts +121 -0
- package/templates/skills/development/frontend/routes/cli/aggregate-component-registry/types.ts +69 -0
- package/templates/skills/development/frontend/routes/cli/aggregate-component-registry/validate.ts +23 -0
- package/templates/skills/development/frontend/routes/cli/scaffold-routes/__tests__/generate.test.ts +292 -0
- package/templates/skills/development/frontend/routes/cli/scaffold-routes/generate.ts +270 -0
- package/templates/skills/development/frontend/routes/cli/scaffold-routes/index.ts +42 -0
- package/templates/skills/development/frontend/routes/cli/scaffold-routes/types.ts +114 -0
- package/templates/skills/development/frontend/routes/cli/scaffold-routes/validate.ts +68 -0
- package/templates/skills/development/frontend/structure/SKILL.md +119 -0
- package/templates/skills/development/frontend/theme/SKILL.md +48 -0
- package/templates/skills/development/frontend/theme/cli/scaffold-theme/__tests__/generate.test.ts +53 -0
- package/templates/skills/development/frontend/theme/cli/scaffold-theme/generate.ts +129 -0
- package/templates/skills/development/frontend/theme/cli/scaffold-theme/index.ts +102 -0
- package/templates/skills/development/frontend/theme/cli/scaffold-theme/types.ts +48 -0
- package/templates/skills/development/frontend/theme/cli/scaffold-theme/validate.ts +37 -0
- package/templates/skills/development/frontend/ui-polish/SKILL.md +192 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/__tests__/r18.test.ts +153 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/__tests__/r19.test.ts +307 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/__tests__/r20.test.ts +167 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/__tests__/shared-scan.test.ts +262 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/apply.ts +580 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/audit.ts +825 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/index.ts +133 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/types.ts +121 -0
- package/templates/skills/development/frontend/ui-polish/cli/ui-polish/validate.ts +73 -0
- package/templates/skills/development/frontend/ui-polish/tokens.json +292 -0
- package/templates/skills/development/frontend/ui-primitives/SKILL.md +88 -0
- package/templates/skills/development/frontend/ui-primitives/cli/scaffold-ui-primitives/__tests__/generate.test.ts +158 -0
- package/templates/skills/development/frontend/ui-primitives/cli/scaffold-ui-primitives/generate.ts +345 -0
- package/templates/skills/development/frontend/ui-primitives/cli/scaffold-ui-primitives/index.ts +142 -0
- package/templates/skills/development/frontend/ui-primitives/cli/scaffold-ui-primitives/types.ts +27 -0
- package/templates/skills/development/frontend/ui-primitives/cli/scaffold-ui-primitives/validate.ts +37 -0
- package/templates/skills/development/run/SKILL.md +61 -0
- package/templates/skills/development/run/backend/SKILL.md +106 -0
- package/templates/skills/development/run/frontend/SKILL.md +116 -0
- package/templates/skills/development/smoke-test/SKILL.md +99 -0
- package/templates/skills/development/smoke-test/cli/run-smoke/execute.ts +424 -0
- package/templates/skills/development/smoke-test/cli/run-smoke/index.ts +75 -0
- package/templates/skills/development/smoke-test/cli/run-smoke/types.ts +100 -0
- package/templates/skills/development/testing/SKILL.md +148 -0
- package/templates/skills/development/testing/cli/scaffold-tests/generate.ts +530 -0
- package/templates/skills/development/testing/cli/scaffold-tests/index.ts +83 -0
- package/templates/skills/development/testing/cli/scaffold-tests/types.ts +51 -0
- package/templates/skills/development/testing/cli/scaffold-tests/validate.ts +33 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/__tests__/generate.test.ts +188 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/__tests__/parse-ac.test.ts +191 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/generate.ts +190 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/index.ts +138 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/parse-ac.ts +172 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/types.ts +104 -0
- package/templates/skills/development/testing/cli/scaffold-tests-from-ac/validate.ts +57 -0
- package/templates/skills/development/testing/cli/test-report/execute.ts +140 -0
- package/templates/skills/development/testing/cli/test-report/index.ts +96 -0
- package/templates/skills/development/testing/cli/test-report/types.ts +52 -0
- package/templates/skills/development/testing/cli/test-report/validate.ts +26 -0
- package/templates/skills/development/testing/fix-build/SKILL.md +81 -0
- package/templates/skills/development/testing/smoke-http/SKILL.md +123 -0
- package/templates/skills/development/testing/smoke-http/cli/smoke-http/execute.ts +129 -0
- package/templates/skills/development/testing/smoke-http/cli/smoke-http/index.ts +113 -0
- package/templates/skills/development/testing/smoke-http/cli/smoke-http/types.ts +62 -0
- package/templates/skills/development/testing/smoke-http/cli/smoke-http/validate.ts +36 -0
- package/templates/skills/development/testing/ui-test/SKILL.md +128 -0
- package/templates/skills/development/testing/ui-test/cli/build-manifest/generate.ts +129 -0
- package/templates/skills/development/testing/ui-test/cli/build-manifest/index.ts +80 -0
- package/templates/skills/development/testing/ui-test/cli/build-manifest/types.ts +72 -0
- package/templates/skills/development/testing/ui-test/cli/build-manifest/validate.ts +44 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/execute.ts +136 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/index.ts +75 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/lib/dev-browser-driver.ts +250 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/templates/delete.js.hbs +83 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/templates/detail.js.hbs +87 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/templates/edit.js.hbs +91 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/templates/form-submit.js.hbs +82 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/templates/list.js.hbs +125 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/templates/permission-negative.js.hbs +65 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/types.ts +57 -0
- package/templates/skills/development/testing/ui-test/cli/run-ui-test/validate.ts +56 -0
- package/templates/skills/documentation/SKILL.md +168 -139
- package/templates/skills/documentation/cli/extract-doc/__tests__/forbidden.test.ts +136 -0
- package/templates/skills/documentation/cli/extract-doc/__tests__/overflow.test.ts +76 -0
- package/templates/skills/documentation/cli/extract-doc/__tests__/required.test.ts +147 -0
- package/templates/skills/documentation/cli/extract-doc/extract.ts +657 -0
- package/templates/skills/documentation/cli/extract-doc/index.ts +102 -0
- package/templates/skills/documentation/cli/extract-doc/types.ts +133 -0
- package/templates/skills/documentation/cli/extract-doc/validate.ts +35 -0
- package/templates/skills/documentation/cli/scaffold-doc/generate.ts +198 -0
- package/templates/skills/documentation/cli/scaffold-doc/index.ts +61 -0
- package/templates/skills/documentation/cli/scaffold-doc/types.ts +72 -0
- package/templates/skills/documentation/cli/scaffold-doc/validate.ts +33 -0
- package/templates/skills/documentation/data-schema.md +18 -38
- package/templates/skills/documentation/steps/step-01-scan.md +59 -113
- package/templates/skills/documentation/steps/step-02-generate.md +158 -231
- package/templates/skills/documentation/steps/step-03-validate.md +101 -280
- package/templates/skills/documentation/templates.md +403 -92
- package/templates/skills/efcore/SKILL.md +88 -308
- package/templates/skills/efcore/_shared.md +140 -0
- package/templates/skills/efcore/agents/create.md +69 -0
- package/templates/skills/efcore/agents/db-update.md +58 -0
- package/templates/skills/efcore/agents/list.md +35 -0
- package/templates/skills/efcore/agents/rebase-snapshot.md +50 -0
- package/templates/skills/efcore/agents/recreate-db.md +78 -0
- package/templates/skills/efcore/agents/squash.md +78 -0
- package/templates/skills/efcore/agents/status.md +35 -0
- package/templates/skills/efcore/cli/create/execute.ts +164 -0
- package/templates/skills/efcore/cli/create/index.ts +51 -0
- package/templates/skills/efcore/cli/create/types.ts +35 -0
- package/templates/skills/efcore/cli/create/validate.ts +29 -0
- package/templates/skills/efcore/cli/lib/detect-dbcontexts.ts +195 -0
- package/templates/skills/efcore/cli/lib/ef-runner.ts +144 -0
- package/templates/skills/efcore/cli/lib/migration-name.ts +56 -0
- package/templates/skills/efcore/cli/lib/parse-csproj-version.ts +45 -0
- package/templates/skills/efcore/cli/list/execute.ts +83 -0
- package/templates/skills/efcore/cli/list/index.ts +60 -0
- package/templates/skills/efcore/cli/list/types.ts +46 -0
- package/templates/skills/efcore/cli/list/validate.ts +20 -0
- package/templates/skills/efcore/cli/rebase-snapshot/execute.ts +21 -0
- package/templates/skills/efcore/cli/rebase-snapshot/index.ts +53 -0
- package/templates/skills/efcore/cli/rebase-snapshot/types.ts +20 -0
- package/templates/skills/efcore/cli/rebase-snapshot/validate.ts +25 -0
- package/templates/skills/efcore/cli/squash/execute.ts +298 -0
- package/templates/skills/efcore/cli/squash/index.ts +57 -0
- package/templates/skills/efcore/cli/squash/types.ts +38 -0
- package/templates/skills/efcore/cli/squash/validate.ts +30 -0
- package/templates/skills/efcore/cli/status/execute.ts +152 -0
- package/templates/skills/efcore/cli/status/index.ts +45 -0
- package/templates/skills/efcore/cli/status/types.ts +32 -0
- package/templates/skills/efcore/cli/status/validate.ts +20 -0
- package/templates/skills/external/context7/SKILL.md +121 -0
- package/templates/skills/external/dev-browser/SKILL.md +134 -0
- package/templates/skills/gitflow/SKILL.md +139 -392
- package/templates/skills/gitflow/_shared.md +24 -620
- package/templates/skills/gitflow/agents/abort.md +47 -0
- package/templates/skills/gitflow/agents/cleanup.md +50 -0
- package/templates/skills/gitflow/agents/commit.md +41 -0
- package/templates/skills/gitflow/agents/finish.md +47 -0
- package/templates/skills/gitflow/agents/init.md +41 -0
- package/templates/skills/gitflow/agents/merge.md +44 -0
- package/templates/skills/gitflow/agents/pr.md +39 -0
- package/templates/skills/gitflow/agents/start.md +42 -0
- package/templates/skills/gitflow/agents/status.md +39 -0
- package/templates/skills/gitflow/agents/sync.md +38 -0
- package/templates/skills/gitflow/cli/abort/execute.ts +61 -0
- package/templates/skills/gitflow/cli/abort/index.ts +116 -0
- package/templates/skills/gitflow/cli/abort/types.ts +21 -0
- package/templates/skills/gitflow/cli/abort/validate.ts +38 -0
- package/templates/skills/gitflow/cli/cleanup/execute.ts +107 -0
- package/templates/skills/gitflow/cli/cleanup/index.ts +122 -0
- package/templates/skills/gitflow/cli/cleanup/types.ts +26 -0
- package/templates/skills/gitflow/cli/cleanup/validate.ts +33 -0
- package/templates/skills/gitflow/cli/commit/execute.ts +146 -0
- package/templates/skills/gitflow/cli/commit/index.ts +77 -0
- package/templates/skills/gitflow/cli/commit/types.ts +36 -0
- package/templates/skills/gitflow/cli/commit/validate.ts +38 -0
- package/templates/skills/gitflow/cli/finish/execute.ts +127 -0
- package/templates/skills/gitflow/cli/finish/index.ts +106 -0
- package/templates/skills/gitflow/cli/finish/types.ts +25 -0
- package/templates/skills/gitflow/cli/finish/validate.ts +44 -0
- package/templates/skills/gitflow/cli/generate-msg/execute.ts +51 -0
- package/templates/skills/gitflow/cli/generate-msg/index.ts +73 -0
- package/templates/skills/gitflow/cli/generate-msg/types.ts +37 -0
- package/templates/skills/gitflow/cli/generate-msg/validate.ts +42 -0
- package/templates/skills/gitflow/cli/init/execute.ts +186 -0
- package/templates/skills/gitflow/cli/init/index.ts +127 -0
- package/templates/skills/gitflow/cli/init/types.ts +63 -0
- package/templates/skills/gitflow/cli/init/validate.ts +56 -0
- package/templates/skills/gitflow/cli/lib/branch.ts +83 -0
- package/templates/skills/gitflow/cli/lib/config.ts +149 -0
- package/templates/skills/gitflow/cli/lib/efcore.ts +136 -0
- package/templates/skills/gitflow/cli/lib/git.ts +212 -0
- package/templates/skills/gitflow/cli/lib/output.ts +49 -0
- package/templates/skills/gitflow/cli/lib/paths.ts +54 -0
- package/templates/skills/gitflow/cli/lib/platform.ts +44 -0
- package/templates/skills/gitflow/cli/lib/provider.ts +147 -0
- package/templates/skills/gitflow/cli/lib/types.ts +189 -0
- package/templates/skills/gitflow/cli/lib/version.ts +152 -0
- package/templates/skills/gitflow/cli/lib/worktree.ts +170 -0
- package/templates/skills/gitflow/cli/merge/execute.ts +93 -0
- package/templates/skills/gitflow/cli/merge/index.ts +109 -0
- package/templates/skills/gitflow/cli/merge/types.ts +24 -0
- package/templates/skills/gitflow/cli/merge/validate.ts +33 -0
- package/templates/skills/gitflow/cli/pr/execute.ts +131 -0
- package/templates/skills/gitflow/cli/pr/index.ts +115 -0
- package/templates/skills/gitflow/cli/pr/types.ts +27 -0
- package/templates/skills/gitflow/cli/pr/validate.ts +27 -0
- package/templates/skills/gitflow/cli/start/execute.ts +98 -0
- package/templates/skills/gitflow/cli/start/index.ts +75 -0
- package/templates/skills/gitflow/cli/start/types.ts +26 -0
- package/templates/skills/gitflow/cli/start/validate.ts +47 -0
- package/templates/skills/gitflow/cli/status/execute.ts +251 -0
- package/templates/skills/gitflow/cli/status/index.ts +154 -0
- package/templates/skills/gitflow/cli/status/types.ts +75 -0
- package/templates/skills/gitflow/cli/status/validate.ts +38 -0
- package/templates/skills/gitflow/cli/sync/execute.ts +84 -0
- package/templates/skills/gitflow/cli/sync/index.ts +75 -0
- package/templates/skills/gitflow/cli/sync/types.ts +25 -0
- package/templates/skills/gitflow/cli/sync/validate.ts +34 -0
- package/templates/skills/gitflow/commit-message.md +46 -0
- package/templates/skills/init/SKILL.md +54 -0
- package/templates/skills/lib/__tests__/canonical-hash.test.ts +45 -0
- package/templates/skills/lib/__tests__/page-spec-actions.test.ts +232 -0
- package/templates/skills/lib/canonical-hash.ts +40 -0
- package/templates/skills/lib/detector.ts +243 -0
- package/templates/skills/lib/dotnet.ts +238 -0
- package/templates/skills/lib/frontend-fixers.ts +151 -0
- package/templates/skills/lib/fs.ts +238 -0
- package/templates/skills/lib/git.ts +134 -0
- package/templates/skills/lib/graph.ts +138 -0
- package/templates/skills/lib/navroute-parser.ts +51 -0
- package/templates/skills/lib/output.ts +117 -0
- package/templates/skills/lib/page-spec-actions.ts +350 -0
- package/templates/skills/lib/skill-slug.ts +121 -0
- package/templates/skills/lib/string-utils.ts +140 -0
- package/templates/skills/lib/template-loader.ts +115 -0
- package/templates/skills/lib/url-conventions.ts +151 -0
- package/templates/skills/package.json +5 -0
- package/templates/skills/quick-search/SKILL.md +99 -99
- package/templates/skills/review/SKILL.md +56 -0
- package/templates/skills/smoke-generation/SKILL.md +18 -16
- package/templates/skills/ui-components/SKILL.md +136 -457
- package/templates/skills/upgrade/SKILL.md +36 -0
- package/templates/skills/utils/SKILL.md +45 -44
- package/templates/skills/utils/subcommands/test-web-config.md +152 -152
- package/templates/skills/utils/subcommands/test-web.md +123 -123
- package/templates/skills/validate-feature/SKILL.md +102 -101
- package/templates/skills/validate-feature/references/api-smoke-tests.md +140 -140
- package/templates/skills/validate-feature/references/db-validation-checks.md +180 -180
- package/templates/skills/validate-feature/steps/step-00-dependencies.md +121 -121
- package/templates/skills/validate-feature/steps/step-01-compile.md +39 -39
- package/templates/skills/validate-feature/steps/step-02-unit-tests.md +45 -45
- package/templates/skills/validate-feature/steps/step-03-integration-tests.md +53 -53
- package/templates/skills/validate-feature/steps/step-04-api-smoke.md +94 -94
- package/templates/skills/validate-feature/steps/step-05-db-validation.md +149 -149
- package/templates/skills/validation/conventions/SKILL.md +193 -0
- package/templates/skills/validation/conventions/cli/validate-conventions/execute.ts +368 -0
- package/templates/skills/validation/conventions/cli/validate-conventions/index.ts +67 -0
- package/templates/skills/validation/conventions/cli/validate-conventions/types.ts +91 -0
- package/templates/skills/validation/conventions/cli/validate-conventions/validate.ts +36 -0
- package/templates/skills/validation/cross-validate/SKILL.md +83 -0
- package/templates/skills/validation/cross-validate/cli/execute.ts +576 -0
- package/templates/skills/validation/cross-validate/cli/index.ts +87 -0
- package/templates/skills/validation/cross-validate/cli/types.ts +85 -0
- package/templates/skills/validation/cross-validate/cli/validate.ts +54 -0
- package/templates/skills/validation/eslint/SKILL.md +65 -0
- package/templates/skills/validation/eslint/cli/execute.ts +413 -0
- package/templates/skills/validation/eslint/cli/index.ts +102 -0
- package/templates/skills/validation/eslint/cli/types.ts +48 -0
- package/templates/skills/validation/eslint/cli/validate.ts +43 -0
- package/templates/skills/validation/project-inventory/SKILL.md +166 -0
- package/templates/skills/validation/project-inventory/cli/project-inventory/execute.ts +397 -0
- package/templates/skills/validation/project-inventory/cli/project-inventory/index.ts +80 -0
- package/templates/skills/validation/project-inventory/cli/project-inventory/types.ts +89 -0
- package/templates/skills/validation/project-inventory/cli/project-inventory/validate.ts +35 -0
- package/templates/skills/validation/readiness-report/SKILL.md +109 -0
- package/templates/skills/validation/readiness-report/cli/execute.ts +236 -0
- package/templates/skills/validation/readiness-report/cli/index.ts +234 -0
- package/templates/skills/validation/readiness-report/cli/types.ts +61 -0
- package/templates/skills/validation/readiness-report/cli/validate.ts +54 -0
- package/templates/skills/validation/roslyn/SKILL.md +103 -0
- package/templates/skills/validation/roslyn/cli/execute.ts +616 -0
- package/templates/skills/validation/roslyn/cli/index.ts +86 -0
- package/templates/skills/validation/roslyn/cli/types.ts +50 -0
- package/templates/skills/validation/roslyn/cli/validate.ts +43 -0
- package/.documentation/apex.html +0 -649
- package/dist/mcp-entry.mjs +0 -68888
- package/dist/mcp-entry.mjs.map +0 -1
- package/scripts/extract-api-endpoints.ts +0 -325
- package/scripts/extract-business-rules.ts +0 -440
- package/scripts/generate-doc-with-mock-ui.ts +0 -804
- package/templates/agents/ba-reader.md +0 -386
- package/templates/agents/ba-writer.md +0 -810
- package/templates/agents/efcore/migration.md +0 -204
- package/templates/agents/efcore/rebase-snapshot.md +0 -202
- package/templates/agents/efcore/squash.md +0 -269
- package/templates/agents/gitflow/abort.md +0 -45
- package/templates/agents/gitflow/cleanup.md +0 -107
- package/templates/agents/gitflow/commit.md +0 -236
- package/templates/agents/gitflow/exec.md +0 -48
- package/templates/agents/gitflow/finish.md +0 -146
- package/templates/agents/gitflow/init-clone.md +0 -199
- package/templates/agents/gitflow/init-detect.md +0 -137
- package/templates/agents/gitflow/init-validate.md +0 -225
- package/templates/agents/gitflow/init.md +0 -509
- package/templates/agents/gitflow/merge.md +0 -145
- package/templates/agents/gitflow/plan.md +0 -42
- package/templates/agents/gitflow/pr.md +0 -191
- package/templates/agents/gitflow/review.md +0 -49
- package/templates/agents/gitflow/start.md +0 -147
- package/templates/agents/gitflow/status.md +0 -95
- package/templates/agents/mcp-healthcheck.md +0 -163
- package/templates/hooks/docs-drift-check.md +0 -96
- package/templates/hooks/ef-migration-check.md +0 -139
- package/templates/hooks/mcp-check.md +0 -64
- package/templates/hooks/ralph-mcp-logger.sh +0 -46
- package/templates/mcp-scaffolding/component.tsx.hbs +0 -318
- package/templates/mcp-scaffolding/controller.cs.hbs +0 -118
- package/templates/mcp-scaffolding/entity-extension.cs.hbs +0 -239
- package/templates/mcp-scaffolding/frontend/api-client.ts.hbs +0 -117
- package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +0 -133
- package/templates/mcp-scaffolding/migrations/seed-roles.cs.hbs +0 -261
- package/templates/mcp-scaffolding/service-extension.cs.hbs +0 -53
- package/templates/mcp-scaffolding/tests/controller.test.cs.hbs +0 -436
- package/templates/mcp-scaffolding/tests/entity.test.cs.hbs +0 -239
- package/templates/mcp-scaffolding/tests/repository.test.cs.hbs +0 -441
- package/templates/mcp-scaffolding/tests/security.test.cs.hbs +0 -442
- package/templates/mcp-scaffolding/tests/service.test.cs.hbs +0 -402
- package/templates/mcp-scaffolding/tests/validator.test.cs.hbs +0 -428
- package/templates/skills/_resources/config-safety.md +0 -61
- package/templates/skills/_resources/context-digest-template.md +0 -53
- package/templates/skills/_resources/doc-context-cache.md +0 -60
- package/templates/skills/_resources/docs-manifest-schema.md +0 -155
- package/templates/skills/_resources/formatting-guide.md +0 -124
- package/templates/skills/_resources/mcp-validate-documentation-spec.md +0 -181
- package/templates/skills/_shared.md +0 -228
- package/templates/skills/admin/SKILL.md +0 -48
- package/templates/skills/ai-prompt/SKILL.md +0 -171
- package/templates/skills/ai-prompt/references/ai-agent-modes.md +0 -89
- package/templates/skills/ai-prompt/references/eval-framework.md +0 -129
- package/templates/skills/ai-prompt/steps/step-00-init.md +0 -47
- package/templates/skills/ai-prompt/steps/step-01-implementation.md +0 -122
- package/templates/skills/apex/SKILL.md +0 -234
- package/templates/skills/apex/_shared.md +0 -197
- package/templates/skills/apex/references/analysis-methods.md +0 -178
- package/templates/skills/apex/references/challenge-questions.md +0 -359
- package/templates/skills/apex/references/checks/architecture-checks.sh +0 -154
- package/templates/skills/apex/references/checks/backend-checks.sh +0 -208
- package/templates/skills/apex/references/checks/frontend-checks.sh +0 -560
- package/templates/skills/apex/references/checks/infrastructure-checks.sh +0 -292
- package/templates/skills/apex/references/checks/security-checks.sh +0 -153
- package/templates/skills/apex/references/checks/seed-checks.sh +0 -610
- package/templates/skills/apex/references/code-generation.md +0 -412
- package/templates/skills/apex/references/core-seed-data.md +0 -1502
- package/templates/skills/apex/references/domain-events-pattern.md +0 -45
- package/templates/skills/apex/references/entity-hooks-pattern.md +0 -68
- package/templates/skills/apex/references/error-classification.md +0 -168
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +0 -91
- package/templates/skills/apex/references/licensing-enforcement.md +0 -52
- package/templates/skills/apex/references/parallel-execution.md +0 -187
- package/templates/skills/apex/references/person-extension-pattern.md +0 -619
- package/templates/skills/apex/references/post-checks.md +0 -162
- package/templates/skills/apex/references/smartstack-api.md +0 -591
- package/templates/skills/apex/references/smartstack-frontend-compliance.md +0 -616
- package/templates/skills/apex/references/smartstack-frontend.md +0 -442
- package/templates/skills/apex/references/smartstack-layers.md +0 -551
- package/templates/skills/apex/steps/step-00-init.md +0 -405
- package/templates/skills/apex/steps/step-01-analyze.md +0 -210
- package/templates/skills/apex/steps/step-02-plan.md +0 -303
- package/templates/skills/apex/steps/step-03-execute.md +0 -194
- package/templates/skills/apex/steps/step-03a-layer0-domain.md +0 -144
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +0 -339
- package/templates/skills/apex/steps/step-03c-layer2-backend.md +0 -401
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +0 -562
- package/templates/skills/apex/steps/step-03e-layer4-devdata.md +0 -46
- package/templates/skills/apex/steps/step-04-examine.md +0 -404
- package/templates/skills/apex/steps/step-05-deep-review.md +0 -140
- package/templates/skills/apex/steps/step-06-resolve.md +0 -120
- package/templates/skills/apex/steps/step-07-tests.md +0 -271
- package/templates/skills/apex/steps/step-08-run-tests.md +0 -135
- package/templates/skills/apex-verify/SKILL.md +0 -110
- package/templates/skills/apex-verify/references/audit-rules.md +0 -50
- package/templates/skills/apex-verify/steps/step-00-init.md +0 -119
- package/templates/skills/apex-verify/steps/step-01-nav-audit.md +0 -96
- package/templates/skills/apex-verify/steps/step-02-crud-audit.md +0 -127
- package/templates/skills/apex-verify/steps/step-03-perm-audit.md +0 -119
- package/templates/skills/apex-verify/steps/step-04-route-audit.md +0 -98
- package/templates/skills/apex-verify/steps/step-05-report.md +0 -110
- package/templates/skills/application/SKILL.md +0 -241
- package/templates/skills/application/references/application-roles-template.md +0 -228
- package/templates/skills/application/references/backend-controller-hierarchy.md +0 -68
- package/templates/skills/application/references/backend-entity-seeding.md +0 -73
- package/templates/skills/application/references/backend-seeding-and-dto-output.md +0 -83
- package/templates/skills/application/references/backend-table-prefix-mapping.md +0 -80
- package/templates/skills/application/references/backend-verification.md +0 -88
- package/templates/skills/application/references/contexts-cheatsheet.md +0 -86
- package/templates/skills/application/references/extensions-system.md +0 -158
- package/templates/skills/application/references/frontend-i18n-and-output.md +0 -67
- package/templates/skills/application/references/frontend-route-naming.md +0 -123
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +0 -91
- package/templates/skills/application/references/frontend-verification.md +0 -158
- package/templates/skills/application/references/init-parameter-detection.md +0 -121
- package/templates/skills/application/references/migration-checklist-troubleshooting.md +0 -88
- package/templates/skills/application/references/nav-fallback-procedure.md +0 -198
- package/templates/skills/application/references/provider-template.md +0 -191
- package/templates/skills/application/references/roles-client-project-handling.md +0 -55
- package/templates/skills/application/references/roles-fallback-procedure.md +0 -144
- package/templates/skills/application/references/smartstack-provider.md +0 -118
- package/templates/skills/application/references/test-coverage-requirements.md +0 -213
- package/templates/skills/application/references/test-frontend.md +0 -73
- package/templates/skills/application/references/test-prerequisites.md +0 -72
- package/templates/skills/application/references/themes-db-driven.md +0 -484
- package/templates/skills/application/steps/step-00-init.md +0 -130
- package/templates/skills/application/steps/step-01-navigation.md +0 -170
- package/templates/skills/application/steps/step-02-permissions.md +0 -196
- package/templates/skills/application/steps/step-03-roles.md +0 -182
- package/templates/skills/application/steps/step-03b-provider.md +0 -134
- package/templates/skills/application/steps/step-04-backend.md +0 -174
- package/templates/skills/application/steps/step-05-frontend.md +0 -189
- package/templates/skills/application/steps/step-06-migration.md +0 -189
- package/templates/skills/application/steps/step-07-tests.md +0 -356
- package/templates/skills/application/steps/step-08-documentation.md +0 -137
- package/templates/skills/application/templates-backend.md +0 -463
- package/templates/skills/application/templates-frontend.md +0 -950
- package/templates/skills/application/templates-i18n.md +0 -520
- package/templates/skills/application/templates-seed.md +0 -1110
- package/templates/skills/audit-route/SKILL.md +0 -107
- package/templates/skills/audit-route/references/routing-pattern.md +0 -131
- package/templates/skills/audit-route/steps/step-00-init.md +0 -128
- package/templates/skills/audit-route/steps/step-01-inventory.md +0 -157
- package/templates/skills/audit-route/steps/step-02-conformity.md +0 -193
- package/templates/skills/audit-route/steps/step-03-report.md +0 -201
- package/templates/skills/business-analyse/SKILL.md +0 -252
- package/templates/skills/business-analyse/_shared.md +0 -276
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +0 -560
- package/templates/skills/business-analyse/questionnaire/01-context.md +0 -43
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +0 -111
- package/templates/skills/business-analyse/questionnaire/03-data-ui.md +0 -125
- package/templates/skills/business-analyse/questionnaire/04-risks-metrics.md +0 -6
- package/templates/skills/business-analyse/questionnaire/05-cross-module.md +0 -69
- package/templates/skills/business-analyse/questionnaire.md +0 -156
- package/templates/skills/business-analyse/react/application-viewer.md +0 -242
- package/templates/skills/business-analyse/react/components.md +0 -532
- package/templates/skills/business-analyse/react/i18n-template.md +0 -306
- package/templates/skills/business-analyse/react/schema.md +0 -831
- package/templates/skills/business-analyse/references/03-json-schemas.md +0 -221
- package/templates/skills/business-analyse/references/03-post-check-validation.md +0 -208
- package/templates/skills/business-analyse/references/03-smartstack-entity-guards.md +0 -32
- package/templates/skills/business-analyse/references/04-cross-module-validation.md +0 -95
- package/templates/skills/business-analyse/references/04-file-allocation.md +0 -162
- package/templates/skills/business-analyse/references/04-naming-audit-checks.md +0 -174
- package/templates/skills/business-analyse/references/04-semantic-validation-matrix.md +0 -118
- package/templates/skills/business-analyse/references/acceptance-criteria.md +0 -164
- package/templates/skills/business-analyse/references/analysis-semantic-checks.md +0 -190
- package/templates/skills/business-analyse/references/canonical-json-formats.md +0 -204
- package/templates/skills/business-analyse/references/compilation-structure-cards.md +0 -297
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +0 -124
- package/templates/skills/business-analyse/references/detection-strategies.md +0 -424
- package/templates/skills/business-analyse/references/domain-research-playbook.md +0 -234
- package/templates/skills/business-analyse/references/entity-architecture-decision.md +0 -240
- package/templates/skills/business-analyse/references/entity-sourcing-presentation.md +0 -166
- package/templates/skills/business-analyse/references/init-resume-logic.md +0 -70
- package/templates/skills/business-analyse/references/init-schema-deployment.md +0 -65
- package/templates/skills/business-analyse/references/module-completeness-challenge.md +0 -174
- package/templates/skills/business-analyse/references/multi-app-detection.md +0 -149
- package/templates/skills/business-analyse/references/naming-conventions.md +0 -253
- package/templates/skills/business-analyse/references/portal-classification.md +0 -52
- package/templates/skills/business-analyse/references/robustness-checks.md +0 -426
- package/templates/skills/business-analyse/references/ui-dashboard-spec.md +0 -85
- package/templates/skills/business-analyse/references/ui-resource-cards.md +0 -259
- package/templates/skills/business-analyse/references/validation-checklist.md +0 -378
- package/templates/skills/business-analyse/schemas/application-schema.json +0 -481
- package/templates/skills/business-analyse/schemas/feature-schema.json +0 -53
- package/templates/skills/business-analyse/schemas/index-schema.json +0 -47
- package/templates/skills/business-analyse/schemas/project-schema.json +0 -481
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +0 -245
- package/templates/skills/business-analyse/schemas/sections/discovery-schema.json +0 -80
- package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +0 -82
- package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +0 -70
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +0 -567
- package/templates/skills/business-analyse/schemas/sections/validation-schema.json +0 -93
- package/templates/skills/business-analyse/schemas/shared/common-defs.json +0 -227
- package/templates/skills/business-analyse/steps/step-00-init.md +0 -463
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +0 -901
- package/templates/skills/business-analyse/steps/step-02-structure.md +0 -315
- package/templates/skills/business-analyse/steps/step-03-specify.md +0 -986
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +0 -928
- package/templates/skills/business-analyse/templates/tpl-frd.md +0 -168
- package/templates/skills/business-analyse/templates/tpl-handoff.md +0 -189
- package/templates/skills/business-analyse/templates/tpl-launch-displays.md +0 -59
- package/templates/skills/business-analyse/templates-frd.md +0 -476
- package/templates/skills/business-analyse/templates-react.md +0 -574
- package/templates/skills/business-analyse-design/SKILL.md +0 -101
- package/templates/skills/business-analyse-design/references/screens-post-check.md +0 -221
- package/templates/skills/business-analyse-design/references/screens-type-mapping.md +0 -138
- package/templates/skills/business-analyse-design/references/smartcomponents-templates.md +0 -225
- package/templates/skills/business-analyse-design/references/spec-auto-inference.md +0 -117
- package/templates/skills/business-analyse-design/steps/step-01-screens.md +0 -108
- package/templates/skills/business-analyse-design/steps/step-02-wireframes.md +0 -155
- package/templates/skills/business-analyse-design/steps/step-03-navigation.md +0 -189
- package/templates/skills/business-analyse-develop/SKILL.md +0 -250
- package/templates/skills/business-analyse-develop/references/category-completeness.md +0 -326
- package/templates/skills/business-analyse-develop/references/category-rules.md +0 -109
- package/templates/skills/business-analyse-develop/references/compact-loop.md +0 -478
- package/templates/skills/business-analyse-develop/references/handoff-quality-gate.md +0 -132
- package/templates/skills/business-analyse-develop/references/init-resume-recovery.md +0 -183
- package/templates/skills/business-analyse-develop/references/module-transition.md +0 -246
- package/templates/skills/business-analyse-develop/references/multi-module-queue.md +0 -171
- package/templates/skills/business-analyse-develop/references/parallel-execution.md +0 -246
- package/templates/skills/business-analyse-develop/references/prd-v3-transformation.md +0 -326
- package/templates/skills/business-analyse-develop/references/quality-gates.md +0 -160
- package/templates/skills/business-analyse-develop/references/report-reconciliation.md +0 -140
- package/templates/skills/business-analyse-develop/references/report-template.md +0 -142
- package/templates/skills/business-analyse-develop/references/section-splitting.md +0 -439
- package/templates/skills/business-analyse-develop/references/task-transform-legacy.md +0 -256
- package/templates/skills/business-analyse-develop/references/team-orchestration.md +0 -547
- package/templates/skills/business-analyse-develop/steps/step-00-init.md +0 -242
- package/templates/skills/business-analyse-develop/steps/step-01-task.md +0 -182
- package/templates/skills/business-analyse-develop/steps/step-01-v4-execute.md +0 -139
- package/templates/skills/business-analyse-develop/steps/step-02-execute.md +0 -216
- package/templates/skills/business-analyse-develop/steps/step-02-v4-verify.md +0 -176
- package/templates/skills/business-analyse-develop/steps/step-03-commit.md +0 -107
- package/templates/skills/business-analyse-develop/steps/step-04-check.md +0 -419
- package/templates/skills/business-analyse-develop/steps/step-05-report.md +0 -137
- package/templates/skills/business-analyse-handoff/SKILL.md +0 -101
- package/templates/skills/business-analyse-handoff/references/acceptance-criteria.md +0 -318
- package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +0 -211
- package/templates/skills/business-analyse-handoff/references/context-isolation-pattern.md +0 -47
- package/templates/skills/business-analyse-handoff/references/entity-canonicalization.md +0 -158
- package/templates/skills/business-analyse-handoff/references/entity-domain-mapping.md +0 -115
- package/templates/skills/business-analyse-handoff/references/handoff-file-inventory.md +0 -49
- package/templates/skills/business-analyse-handoff/references/handoff-file-templates.md +0 -197
- package/templates/skills/business-analyse-handoff/references/handoff-global-validation.md +0 -142
- package/templates/skills/business-analyse-handoff/references/handoff-mappings.md +0 -108
- package/templates/skills/business-analyse-handoff/references/handoff-seeddata-generation.md +0 -314
- package/templates/skills/business-analyse-handoff/references/prd-generation.md +0 -362
- package/templates/skills/business-analyse-handoff/references/prd-validation-checks.md +0 -125
- package/templates/skills/business-analyse-handoff/references/project-index-update.md +0 -98
- package/templates/skills/business-analyse-handoff/references/readiness-scoring.md +0 -95
- package/templates/skills/business-analyse-handoff/schemas/handoff-schema.json +0 -95
- package/templates/skills/business-analyse-handoff/steps/step-00-validate.md +0 -158
- package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +0 -85
- package/templates/skills/business-analyse-handoff/steps/step-02-export.md +0 -169
- package/templates/skills/business-analyse-handoff/templates/tpl-progress.md +0 -172
- package/templates/skills/business-analyse-html/SKILL.md +0 -89
- package/templates/skills/business-analyse-html/html/ba-interactive.html +0 -6134
- package/templates/skills/business-analyse-html/html/build-html.js +0 -137
- package/templates/skills/business-analyse-html/html/src/partials/cadrage-context.html +0 -34
- package/templates/skills/business-analyse-html/html/src/partials/cadrage-scope.html +0 -27
- package/templates/skills/business-analyse-html/html/src/partials/cadrage-stakeholders.html +0 -55
- package/templates/skills/business-analyse-html/html/src/partials/cadrage-success.html +0 -34
- package/templates/skills/business-analyse-html/html/src/partials/consol-datamodel.html +0 -8
- package/templates/skills/business-analyse-html/html/src/partials/consol-flows.html +0 -29
- package/templates/skills/business-analyse-html/html/src/partials/consol-interactions.html +0 -8
- package/templates/skills/business-analyse-html/html/src/partials/consol-permissions.html +0 -8
- package/templates/skills/business-analyse-html/html/src/partials/decomp-dependencies.html +0 -38
- package/templates/skills/business-analyse-html/html/src/partials/decomp-modules.html +0 -43
- package/templates/skills/business-analyse-html/html/src/partials/handoff-summary.html +0 -24
- package/templates/skills/business-analyse-html/html/src/partials/module-spec-container.html +0 -4
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +0 -313
- package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +0 -316
- package/templates/skills/business-analyse-html/html/src/scripts/03-render-cadrage.js +0 -162
- package/templates/skills/business-analyse-html/html/src/scripts/04-render-modules.js +0 -203
- package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +0 -866
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +0 -196
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +0 -564
- package/templates/skills/business-analyse-html/html/src/scripts/07-render-handoff.js +0 -108
- package/templates/skills/business-analyse-html/html/src/scripts/08-editing.js +0 -137
- package/templates/skills/business-analyse-html/html/src/scripts/09-export.js +0 -138
- package/templates/skills/business-analyse-html/html/src/scripts/10-comments.js +0 -221
- package/templates/skills/business-analyse-html/html/src/scripts/11-review-panel.js +0 -167
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +0 -162
- package/templates/skills/business-analyse-html/html/src/styles/01-variables.css +0 -38
- package/templates/skills/business-analyse-html/html/src/styles/02-layout.css +0 -216
- package/templates/skills/business-analyse-html/html/src/styles/03-navigation.css +0 -120
- package/templates/skills/business-analyse-html/html/src/styles/04-cards.css +0 -194
- package/templates/skills/business-analyse-html/html/src/styles/05-modules.css +0 -518
- package/templates/skills/business-analyse-html/html/src/styles/06-wireframes.css +0 -263
- package/templates/skills/business-analyse-html/html/src/styles/07-comments.css +0 -184
- package/templates/skills/business-analyse-html/html/src/styles/08-review-panel.css +0 -241
- package/templates/skills/business-analyse-html/html/src/styles/09-mockups-html.css +0 -220
- package/templates/skills/business-analyse-html/html/src/styles/10-diagrams.css +0 -73
- package/templates/skills/business-analyse-html/html/src/template.html +0 -449
- package/templates/skills/business-analyse-html/references/02-embedded-artifacts-building.md +0 -144
- package/templates/skills/business-analyse-html/references/02-feature-data-building.md +0 -143
- package/templates/skills/business-analyse-html/references/02-mapping-tables.md +0 -442
- package/templates/skills/business-analyse-html/references/02-normalization-helpers.md +0 -139
- package/templates/skills/business-analyse-html/references/02-screen-format-detection.md +0 -283
- package/templates/skills/business-analyse-html/references/02-self-check-validation.md +0 -199
- package/templates/skills/business-analyse-html/references/data-build.md +0 -215
- package/templates/skills/business-analyse-html/references/data-mapping.md +0 -452
- package/templates/skills/business-analyse-html/references/output-modes.md +0 -119
- package/templates/skills/business-analyse-html/references/wireframe-svg-style-guide.md +0 -335
- package/templates/skills/business-analyse-html/steps/step-01-collect.md +0 -140
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +0 -76
- package/templates/skills/business-analyse-html/steps/step-03-render.md +0 -95
- package/templates/skills/business-analyse-html/steps/step-04-verify.md +0 -224
- package/templates/skills/business-analyse-quick/SKILL.md +0 -807
- package/templates/skills/business-analyse-quick/references/domain-heuristics.md +0 -172
- package/templates/skills/business-analyse-quick/references/prd-schema.md +0 -268
- package/templates/skills/business-analyse-review/SKILL.md +0 -71
- package/templates/skills/business-analyse-review/references/review-data-mapping.md +0 -367
- package/templates/skills/business-analyse-review/steps/step-00-init.md +0 -111
- package/templates/skills/business-analyse-review/steps/step-01-apply.md +0 -304
- package/templates/skills/business-analyse-status/SKILL.md +0 -136
- package/templates/skills/cc-agent/SKILL.md +0 -129
- package/templates/skills/cc-agent/references/agent-behavior-patterns.md +0 -95
- package/templates/skills/cc-agent/references/agent-frontmatter.md +0 -213
- package/templates/skills/cc-agent/references/permission-modes.md +0 -102
- package/templates/skills/cc-agent/references/tools-reference.md +0 -144
- package/templates/skills/cc-agent/steps/step-00-init.md +0 -134
- package/templates/skills/cc-agent/steps/step-01-design.md +0 -186
- package/templates/skills/cc-agent/steps/step-02-generate.md +0 -131
- package/templates/skills/cc-agent/steps/step-03-validate.md +0 -130
- package/templates/skills/cc-agent/templates/agent-categorized.md +0 -67
- package/templates/skills/cc-agent/templates/agent-standalone.md +0 -56
- package/templates/skills/cc-agent/templates/agent-with-skills.md +0 -94
- package/templates/skills/cc-audit/SKILL.md +0 -108
- package/templates/skills/cc-audit/references/agent-checklist.md +0 -91
- package/templates/skills/cc-audit/references/hook-checklist.md +0 -110
- package/templates/skills/cc-audit/references/skill-checklist.md +0 -70
- package/templates/skills/cc-audit/steps/step-00-init.md +0 -98
- package/templates/skills/cc-audit/steps/step-01-scan.md +0 -142
- package/templates/skills/cc-audit/steps/step-02-analyze.md +0 -158
- package/templates/skills/cc-audit/steps/step-03-report.md +0 -142
- package/templates/skills/cc-skill/SKILL.md +0 -134
- package/templates/skills/cc-skill/references/best-practices.md +0 -167
- package/templates/skills/cc-skill/references/frontmatter-reference.md +0 -182
- package/templates/skills/cc-skill/references/skill-patterns.md +0 -199
- package/templates/skills/cc-skill/steps/step-00-init.md +0 -119
- package/templates/skills/cc-skill/steps/step-01-design.md +0 -199
- package/templates/skills/cc-skill/steps/step-02-generate.md +0 -145
- package/templates/skills/cc-skill/steps/step-03-steps.md +0 -151
- package/templates/skills/cc-skill/steps/step-04-validate.md +0 -124
- package/templates/skills/cc-skill/templates/skill-forked.md +0 -85
- package/templates/skills/cc-skill/templates/skill-progressive.md +0 -102
- package/templates/skills/cc-skill/templates/skill-simple.md +0 -75
- package/templates/skills/cc-skill/templates/step-template.md +0 -82
- package/templates/skills/controller/SKILL.md +0 -162
- package/templates/skills/controller/postman-templates.md +0 -614
- package/templates/skills/controller/references/controller-code-templates.md +0 -162
- package/templates/skills/controller/references/mcp-scaffold-workflow.md +0 -237
- package/templates/skills/controller/references/permission-sync-templates.md +0 -149
- package/templates/skills/controller/steps/step-00-init.md +0 -193
- package/templates/skills/controller/steps/step-01-analyze.md +0 -152
- package/templates/skills/controller/steps/step-02-plan.md +0 -176
- package/templates/skills/controller/steps/step-03-generate.md +0 -189
- package/templates/skills/controller/steps/step-04-perms.md +0 -80
- package/templates/skills/controller/steps/step-05-validate.md +0 -107
- package/templates/skills/controller/templates.md +0 -1556
- package/templates/skills/debug/SKILL.md +0 -70
- package/templates/skills/debug/references/team-protocol.md +0 -232
- package/templates/skills/debug/steps/step-00-init.md +0 -57
- package/templates/skills/debug/steps/step-01-analyze.md +0 -219
- package/templates/skills/debug/steps/step-02-resolve.md +0 -85
- package/templates/skills/efcore/references/database-operations.md +0 -66
- package/templates/skills/efcore/references/reset-operations.md +0 -81
- package/templates/skills/efcore/references/seed-methods.md +0 -86
- package/templates/skills/efcore/references/shared-init-functions.md +0 -250
- package/templates/skills/efcore/references/sql-objects-injection.md +0 -19
- package/templates/skills/efcore/references/troubleshooting.md +0 -81
- package/templates/skills/efcore/references/zero-downtime-patterns.md +0 -229
- package/templates/skills/explore/SKILL.md +0 -98
- package/templates/skills/feature-full/SKILL.md +0 -111
- package/templates/skills/feature-full/steps/step-00-init.md +0 -57
- package/templates/skills/feature-full/steps/step-01-implementation.md +0 -133
- package/templates/skills/gitflow/phases/abort.md +0 -189
- package/templates/skills/gitflow/phases/cleanup.md +0 -264
- package/templates/skills/gitflow/phases/status.md +0 -192
- package/templates/skills/gitflow/references/commit-message-generation.md +0 -58
- package/templates/skills/gitflow/references/commit-migration-validation.md +0 -53
- package/templates/skills/gitflow/references/finish-cleanup.md +0 -55
- package/templates/skills/gitflow/references/finish-version-bumping.md +0 -45
- package/templates/skills/gitflow/references/init-config-template.md +0 -143
- package/templates/skills/gitflow/references/init-environment-detection.md +0 -41
- package/templates/skills/gitflow/references/init-name-normalization.md +0 -118
- package/templates/skills/gitflow/references/init-questions.md +0 -193
- package/templates/skills/gitflow/references/init-structure-creation.md +0 -75
- package/templates/skills/gitflow/references/init-version-detection.md +0 -23
- package/templates/skills/gitflow/references/init-workspace-detection.md +0 -43
- package/templates/skills/gitflow/references/merge-ci-status.md +0 -36
- package/templates/skills/gitflow/references/merge-execution.md +0 -62
- package/templates/skills/gitflow/references/merge-pr-context.md +0 -76
- package/templates/skills/gitflow/references/plan-template.md +0 -69
- package/templates/skills/gitflow/references/pr-build-checks.md +0 -60
- package/templates/skills/gitflow/references/pr-generation.md +0 -58
- package/templates/skills/gitflow/references/start-branch-normalization.md +0 -28
- package/templates/skills/gitflow/references/start-efcore-preflight.md +0 -70
- package/templates/skills/gitflow/references/start-local-config.md +0 -113
- package/templates/skills/gitflow/references/start-worktree-creation.md +0 -50
- package/templates/skills/gitflow/references/sync-push-verify.md +0 -44
- package/templates/skills/gitflow/references/sync-rebase-conflicts.md +0 -38
- package/templates/skills/gitflow/steps/step-commit.md +0 -199
- package/templates/skills/gitflow/steps/step-finish.md +0 -147
- package/templates/skills/gitflow/steps/step-init.md +0 -230
- package/templates/skills/gitflow/steps/step-merge.md +0 -85
- package/templates/skills/gitflow/steps/step-plan.md +0 -151
- package/templates/skills/gitflow/steps/step-pr.md +0 -247
- package/templates/skills/gitflow/steps/step-start.md +0 -195
- package/templates/skills/gitflow/steps/step-sync.md +0 -161
- package/templates/skills/gitflow/templates/config.json +0 -72
- package/templates/skills/mcp/SKILL.md +0 -62
- package/templates/skills/mcp/steps/step-01-healthcheck.md +0 -108
- package/templates/skills/mcp/steps/step-02-tools.md +0 -73
- package/templates/skills/migrate/SKILL.md +0 -312
- package/templates/skills/migrate/references/v3.34-to-v3.46.md +0 -289
- package/templates/skills/notification/SKILL.md +0 -173
- package/templates/skills/refactor/SKILL.md +0 -56
- package/templates/skills/refactor/steps/step-01-discover.md +0 -60
- package/templates/skills/refactor/steps/step-02-execute.md +0 -67
- package/templates/skills/review-code/SKILL.md +0 -95
- package/templates/skills/review-code/references/clean-code-principles.md +0 -292
- package/templates/skills/review-code/references/code-quality-metrics.md +0 -174
- package/templates/skills/review-code/references/feedback-patterns.md +0 -149
- package/templates/skills/review-code/references/owasp-api-top10.md +0 -243
- package/templates/skills/review-code/references/security-checklist.md +0 -212
- package/templates/skills/review-code/references/smartstack-conventions.md +0 -568
- package/templates/skills/review-code/steps/step-01-smartstack.md +0 -96
- package/templates/skills/review-code/steps/step-02-detailed-review.md +0 -80
- package/templates/skills/review-code/steps/step-03-react.md +0 -44
- package/templates/skills/sketch/SKILL.md +0 -34
- package/templates/skills/ui-components/accessibility.md +0 -170
- package/templates/skills/ui-components/patterns/dashboard-chart.md +0 -327
- package/templates/skills/ui-components/patterns/data-table.md +0 -175
- package/templates/skills/ui-components/patterns/entity-card.md +0 -77
- package/templates/skills/ui-components/patterns/grid-layout.md +0 -91
- package/templates/skills/ui-components/patterns/kanban.md +0 -43
- package/templates/skills/ui-components/references/component-catalog.md +0 -82
- package/templates/skills/ui-components/responsive-guidelines.md +0 -278
- package/templates/skills/ui-components/style-guide.md +0 -113
- package/templates/skills/validate/SKILL.md +0 -181
- package/templates/skills/workflow/SKILL.md +0 -196
- package/templates/skills/workflow/steps/step-00-init.md +0 -57
- package/templates/skills/workflow/steps/step-01-implementation.md +0 -84
|
@@ -1,1502 +0,0 @@
|
|
|
1
|
-
# Core Seed Data - Execution Reference
|
|
2
|
-
|
|
3
|
-
> **Loaded by:** apex step-03-execute (ALWAYS for Layer 1) and step-04-examine
|
|
4
|
-
> **Condition:** Seed data generation — infrastructure or seedData category tasks
|
|
5
|
-
> **Applies to:** Client projects only (seeding_strategy = "provider", ExtensionsDbContext)
|
|
6
|
-
>
|
|
7
|
-
> **Source of truth:** `/application` skill `templates-seed.md` (lines 608-916)
|
|
8
|
-
> **Moved from:** `business-analyse-develop/references/core-seed-data.md` (delegation refactoring)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## 1. Parameter Extraction
|
|
13
|
-
|
|
14
|
-
> **IMPORTANT — `navRoute` in seed data = permission root (2 segments: `app.module`).**
|
|
15
|
-
> This matches the controller `[NavRoute]` attribute for module-level controllers (also 2 segments: `app.module`).
|
|
16
|
-
> The seed data `navRoute` serves as the base for module-level permissions (`navRoute.read`, `navRoute.create`).
|
|
17
|
-
> Section-level permissions extend it: `navRoute.{sectionCode}.read`.
|
|
18
|
-
|
|
19
|
-
Extract navigation hierarchy from the task's `_seedDataMeta` (populated by guardrail 1e):
|
|
20
|
-
|
|
21
|
-
```javascript
|
|
22
|
-
const task = currentTask;
|
|
23
|
-
const meta = task._seedDataMeta || task._providerMeta || {};
|
|
24
|
-
const coreSeedData = meta.coreSeedData || {};
|
|
25
|
-
|
|
26
|
-
// Navigation hierarchy
|
|
27
|
-
const navModules = coreSeedData.navigationModules || coreSeedData.navigation || [];
|
|
28
|
-
const navSections = coreSeedData.navigationSections || [];
|
|
29
|
-
const navResources = coreSeedData.navigationResources || [];
|
|
30
|
-
const permissions = coreSeedData.permissions || [];
|
|
31
|
-
const rolePerms = coreSeedData.rolePermissions || [];
|
|
32
|
-
|
|
33
|
-
// Derived context (from guardrail or PRD)
|
|
34
|
-
// NOTE: navRoute here = permission root (2 segments), same as module-level controller NavRoute
|
|
35
|
-
const navRoute = meta.navRoute; // e.g. "human-resources.projects" (permission root)
|
|
36
|
-
const appCode = meta.appCode; // e.g. "human-resources"
|
|
37
|
-
const moduleCode = task.module; // e.g. "projects"
|
|
38
|
-
|
|
39
|
-
// If _seedDataMeta is absent, fallback to PRD source
|
|
40
|
-
if (!navRoute) {
|
|
41
|
-
const prd = readJSON('.ralph/prd.json');
|
|
42
|
-
const navRoute = `${prd.source?.application || prd.metadata?.module}.${task.module}`;
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**State variables after extraction:**
|
|
47
|
-
|
|
48
|
-
| Variable | Example | Source |
|
|
49
|
-
|----------|---------|--------|
|
|
50
|
-
| `navRoute` | `human-resources.projects` (permission root, 2 segments) | `_seedDataMeta.navRoute` |
|
|
51
|
-
| `appCode` | `human-resources` | `_seedDataMeta.appCode` |
|
|
52
|
-
| `moduleCode` | `projects` | `task.module` |
|
|
53
|
-
| `navModules[]` | `[{code, label, icon, route, translations}]` | `coreSeedData.navigationModules` |
|
|
54
|
-
| `navSections[]` | `[{code, label, icon, route, parentCode, permission, sort}]` | `coreSeedData.navigationSections` |
|
|
55
|
-
| `navResources[]` | `[{code, type, entity, parentCode, permission}]` | `coreSeedData.navigationResources` |
|
|
56
|
-
| `permissions[]` | `[{path, action, description}]` | `coreSeedData.permissions` |
|
|
57
|
-
| `rolePerms[]` | `[{role, permissions[]}]` | `coreSeedData.rolePermissions` |
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## 1b. NavigationApplicationSeedData.cs (ONCE per application)
|
|
62
|
-
|
|
63
|
-
**File:** `Infrastructure/Persistence/Seeding/Data/NavigationApplicationSeedData.cs`
|
|
64
|
-
|
|
65
|
-
> Create this file BEFORE any module seed data.
|
|
66
|
-
> Without it, modules have no parent ApplicationId and ApplicationRolesSeedData has no GUID reference.
|
|
67
|
-
> This file is created once per application (not per module).
|
|
68
|
-
|
|
69
|
-
### Data Source
|
|
70
|
-
|
|
71
|
-
From `seedDataCore.navigationApplications[0]` in feature.json (generated by BA step-05a):
|
|
72
|
-
|
|
73
|
-
| Placeholder | Source |
|
|
74
|
-
|-------------|--------|
|
|
75
|
-
| `{appCode}` | `navigationApplications[0].code` |
|
|
76
|
-
| `{appLabel_xx}` | `navigationApplications[0].labels.xx` (fr, en, it, de) |
|
|
77
|
-
| `{appDesc_xx}` | `navigationApplications[0].description.xx` |
|
|
78
|
-
| `{appIcon}` | `navigationApplications[0].icon` |
|
|
79
|
-
|
|
80
|
-
### GUID Generation Rule
|
|
81
|
-
|
|
82
|
-
```csharp
|
|
83
|
-
// Random GUID — idempotence handled by Code-based lookups
|
|
84
|
-
public static readonly Guid ApplicationId = Guid.NewGuid();
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Template
|
|
88
|
-
|
|
89
|
-
```csharp
|
|
90
|
-
using SmartStack.Domain.Navigation;
|
|
91
|
-
|
|
92
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
|
|
93
|
-
|
|
94
|
-
/// <summary>
|
|
95
|
-
/// Navigation seed data for {AppLabel_en} application.
|
|
96
|
-
/// Consumed by IClientSeedDataProvider at application startup.
|
|
97
|
-
/// Created ONCE per application — modules reference ApplicationId as parent.
|
|
98
|
-
/// </summary>
|
|
99
|
-
public static class NavigationApplicationSeedData
|
|
100
|
-
{
|
|
101
|
-
// Random GUID — resolved by Code at runtime for idempotence
|
|
102
|
-
public static readonly Guid ApplicationId = Guid.NewGuid();
|
|
103
|
-
|
|
104
|
-
/// <summary>
|
|
105
|
-
/// Returns navigation application entry for seeding into core.nav_Applications.
|
|
106
|
-
/// </summary>
|
|
107
|
-
public static NavigationApplicationSeedEntry GetApplicationEntry()
|
|
108
|
-
{
|
|
109
|
-
return new NavigationApplicationSeedEntry
|
|
110
|
-
{
|
|
111
|
-
Id = ApplicationId,
|
|
112
|
-
Code = "{appCode}",
|
|
113
|
-
Label = "{appLabel_en}",
|
|
114
|
-
Description = "{appDesc_en}",
|
|
115
|
-
Icon = "{appIcon}", // Lucide React icon name
|
|
116
|
-
IconType = IconType.Lucide,
|
|
117
|
-
Route = ToKebabCase("/{appCode}"),
|
|
118
|
-
DisplayOrder = 1,
|
|
119
|
-
IsActive = true,
|
|
120
|
-
IsOpen = false, // true => bypass permission checks (system apps only)
|
|
121
|
-
IsPersonal = false // true => belongs to user personal scope (myspace)
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/// <summary>
|
|
126
|
-
/// Returns 4-language translations for this application.
|
|
127
|
-
/// </summary>
|
|
128
|
-
public static IEnumerable<NavigationTranslationSeedEntry> GetTranslationEntries()
|
|
129
|
-
{
|
|
130
|
-
var appId = ApplicationId;
|
|
131
|
-
return new[]
|
|
132
|
-
{
|
|
133
|
-
new NavigationTranslationSeedEntry
|
|
134
|
-
{
|
|
135
|
-
EntityType = NavigationEntityType.Application,
|
|
136
|
-
EntityId = appId,
|
|
137
|
-
LanguageCode = "fr",
|
|
138
|
-
Label = "{appLabel_fr}",
|
|
139
|
-
Description = "{appDesc_fr}"
|
|
140
|
-
},
|
|
141
|
-
new NavigationTranslationSeedEntry
|
|
142
|
-
{
|
|
143
|
-
EntityType = NavigationEntityType.Application,
|
|
144
|
-
EntityId = appId,
|
|
145
|
-
LanguageCode = "en",
|
|
146
|
-
Label = "{appLabel_en}",
|
|
147
|
-
Description = "{appDesc_en}"
|
|
148
|
-
},
|
|
149
|
-
new NavigationTranslationSeedEntry
|
|
150
|
-
{
|
|
151
|
-
EntityType = NavigationEntityType.Application,
|
|
152
|
-
EntityId = appId,
|
|
153
|
-
LanguageCode = "it",
|
|
154
|
-
Label = "{appLabel_it}",
|
|
155
|
-
Description = "{appDesc_it}"
|
|
156
|
-
},
|
|
157
|
-
new NavigationTranslationSeedEntry
|
|
158
|
-
{
|
|
159
|
-
EntityType = NavigationEntityType.Application,
|
|
160
|
-
EntityId = appId,
|
|
161
|
-
LanguageCode = "de",
|
|
162
|
-
Label = "{appLabel_de}",
|
|
163
|
-
Description = "{appDesc_de}"
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// No deterministic GUID generation — all IDs are random via Guid.NewGuid()
|
|
169
|
-
// Idempotence is handled by Code-based lookups at runtime
|
|
170
|
-
|
|
171
|
-
/// <summary>
|
|
172
|
-
/// Converts PascalCase route segments to kebab-case for web URLs.
|
|
173
|
-
/// </summary>
|
|
174
|
-
private static string ToKebabCase(string route)
|
|
175
|
-
{
|
|
176
|
-
if (string.IsNullOrEmpty(route)) return route;
|
|
177
|
-
|
|
178
|
-
var segments = route.Split('/');
|
|
179
|
-
var kebabSegments = new List<string>();
|
|
180
|
-
|
|
181
|
-
foreach (var segment in segments)
|
|
182
|
-
{
|
|
183
|
-
if (string.IsNullOrEmpty(segment))
|
|
184
|
-
{
|
|
185
|
-
kebabSegments.Add(segment);
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
var kebab = System.Text.RegularExpressions.Regex
|
|
190
|
-
.Replace(segment, "([a-z])([A-Z])", "$1-$2")
|
|
191
|
-
.ToLowerInvariant();
|
|
192
|
-
kebabSegments.Add(kebab);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return string.Join("/", kebabSegments);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/// <summary>Seed entry DTO for navigation application.</summary>
|
|
200
|
-
public class NavigationApplicationSeedEntry
|
|
201
|
-
{
|
|
202
|
-
public Guid Id { get; init; }
|
|
203
|
-
public string Code { get; init; } = null!;
|
|
204
|
-
public string Label { get; init; } = null!;
|
|
205
|
-
public string? Description { get; init; }
|
|
206
|
-
public string? Icon { get; init; }
|
|
207
|
-
public IconType IconType { get; init; }
|
|
208
|
-
public string? Route { get; init; }
|
|
209
|
-
public int DisplayOrder { get; init; }
|
|
210
|
-
public bool IsActive { get; init; }
|
|
211
|
-
// v3.46+ : ApplicationZone enum removed. Replaced by 2 boolean flags.
|
|
212
|
-
public bool IsOpen { get; init; } // true => app accessible without permission checks
|
|
213
|
-
public bool IsPersonal { get; init; } // true => app in user personal scope (myspace)
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Replace placeholders** with values from `seedDataCore.navigationApplications[0]`.
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## 2. NavigationModuleSeedData.cs
|
|
222
|
-
|
|
223
|
-
**File:** `Infrastructure/Persistence/Seeding/Data/{ModulePascal}/NavigationModuleSeedData.cs`
|
|
224
|
-
|
|
225
|
-
### GUID Generation Rule
|
|
226
|
-
|
|
227
|
-
```csharp
|
|
228
|
-
// Use Guid.NewGuid() — avoids conflicts between projects/tenants/environments
|
|
229
|
-
public static readonly Guid ModuleId = Guid.NewGuid();
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### FK Resolution Safety Rule
|
|
233
|
-
|
|
234
|
-
When seed data references a parent entity (e.g., Module references Application, Section references Module), use `FirstOrDefaultAsync` with a null-guard that gives a clear diagnostic:
|
|
235
|
-
|
|
236
|
-
```csharp
|
|
237
|
-
// CORRECT: null-guard with clear error message
|
|
238
|
-
var parentModule = await context.NavigationModules
|
|
239
|
-
.FirstOrDefaultAsync(m => m.Code == "target-module" && m.ApplicationId == app.Id, ct)
|
|
240
|
-
?? throw new InvalidOperationException(
|
|
241
|
-
$"Seed data dependency missing: NavigationModule 'target-module' not found. " +
|
|
242
|
-
$"Run the target module's seed data provider first.");
|
|
243
|
-
|
|
244
|
-
// WRONG: FirstAsync with generic error
|
|
245
|
-
var parentModule = await context.NavigationModules
|
|
246
|
-
.FirstAsync(m => m.Code == "target-module", ct);
|
|
247
|
-
// → Throws "Sequence contains no elements" — hard to debug
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
This applies to ALL cross-entity FK lookups in seed data: modules, sections, resources, roles, permissions.
|
|
251
|
-
|
|
252
|
-
### Template
|
|
253
|
-
|
|
254
|
-
```csharp
|
|
255
|
-
using SmartStack.Domain.Navigation;
|
|
256
|
-
|
|
257
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{ModulePascal};
|
|
258
|
-
|
|
259
|
-
/// <summary>
|
|
260
|
-
/// Navigation seed data for {ModuleLabel} module.
|
|
261
|
-
/// Consumed by IClientSeedDataProvider at application startup.
|
|
262
|
-
/// </summary>
|
|
263
|
-
public static class {ModulePascal}NavigationSeedData
|
|
264
|
-
{
|
|
265
|
-
// Random GUID — resolved by Code at runtime for idempotence
|
|
266
|
-
public static readonly Guid {ModulePascal}ModuleId = Guid.NewGuid();
|
|
267
|
-
|
|
268
|
-
/// <summary>
|
|
269
|
-
/// Returns navigation module entry for seeding into core.nav_Modules.
|
|
270
|
-
/// </summary>
|
|
271
|
-
public static NavigationModuleSeedEntry GetModuleEntry(Guid applicationId)
|
|
272
|
-
{
|
|
273
|
-
return new NavigationModuleSeedEntry
|
|
274
|
-
{
|
|
275
|
-
Id = {ModulePascal}ModuleId,
|
|
276
|
-
ApplicationId = applicationId,
|
|
277
|
-
Code = "{moduleCode}",
|
|
278
|
-
Label = "{label_en}",
|
|
279
|
-
Description = "{desc_en}",
|
|
280
|
-
Icon = "{icon}", // Lucide React icon name
|
|
281
|
-
IconType = IconType.Lucide,
|
|
282
|
-
Route = ToKebabCase($"/{appCode}/{moduleCode}"), // Absolute path for sidebar navigation (App.tsx routes are RELATIVE to module root)
|
|
283
|
-
DisplayOrder = {displayOrder},
|
|
284
|
-
IsActive = true
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/// <summary>
|
|
289
|
-
/// Returns 4-language translations for this module.
|
|
290
|
-
/// </summary>
|
|
291
|
-
public static IEnumerable<NavigationTranslationSeedEntry> GetTranslationEntries()
|
|
292
|
-
{
|
|
293
|
-
var moduleId = {ModulePascal}ModuleId;
|
|
294
|
-
return new[]
|
|
295
|
-
{
|
|
296
|
-
new NavigationTranslationSeedEntry
|
|
297
|
-
{
|
|
298
|
-
EntityType = NavigationEntityType.Module,
|
|
299
|
-
EntityId = moduleId,
|
|
300
|
-
LanguageCode = "fr",
|
|
301
|
-
Label = "{label_fr}",
|
|
302
|
-
Description = "{desc_fr}"
|
|
303
|
-
},
|
|
304
|
-
new NavigationTranslationSeedEntry
|
|
305
|
-
{
|
|
306
|
-
EntityType = NavigationEntityType.Module,
|
|
307
|
-
EntityId = moduleId,
|
|
308
|
-
LanguageCode = "en",
|
|
309
|
-
Label = "{label_en}",
|
|
310
|
-
Description = "{desc_en}"
|
|
311
|
-
},
|
|
312
|
-
new NavigationTranslationSeedEntry
|
|
313
|
-
{
|
|
314
|
-
EntityType = NavigationEntityType.Module,
|
|
315
|
-
EntityId = moduleId,
|
|
316
|
-
LanguageCode = "it",
|
|
317
|
-
Label = "{label_it}",
|
|
318
|
-
Description = "{desc_it}"
|
|
319
|
-
},
|
|
320
|
-
new NavigationTranslationSeedEntry
|
|
321
|
-
{
|
|
322
|
-
EntityType = NavigationEntityType.Module,
|
|
323
|
-
EntityId = moduleId,
|
|
324
|
-
LanguageCode = "de",
|
|
325
|
-
Label = "{label_de}",
|
|
326
|
-
Description = "{desc_de}"
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// No deterministic GUID generation — all IDs are random via Guid.NewGuid()
|
|
332
|
-
|
|
333
|
-
/// <summary>
|
|
334
|
-
/// Converts PascalCase route segments to kebab-case for web URLs.
|
|
335
|
-
/// Example: /HumanResources/TimeManagement → /human-resources/time-management
|
|
336
|
-
/// </summary>
|
|
337
|
-
private static string ToKebabCase(string route)
|
|
338
|
-
{
|
|
339
|
-
if (string.IsNullOrEmpty(route)) return route;
|
|
340
|
-
|
|
341
|
-
var segments = route.Split('/');
|
|
342
|
-
var kebabSegments = new List<string>();
|
|
343
|
-
|
|
344
|
-
foreach (var segment in segments)
|
|
345
|
-
{
|
|
346
|
-
if (string.IsNullOrEmpty(segment))
|
|
347
|
-
{
|
|
348
|
-
kebabSegments.Add(segment);
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// Convert PascalCase to kebab-case: HumanResources → human-resources
|
|
353
|
-
var kebab = System.Text.RegularExpressions.Regex
|
|
354
|
-
.Replace(segment, "([a-z])([A-Z])", "$1-$2")
|
|
355
|
-
.ToLowerInvariant();
|
|
356
|
-
kebabSegments.Add(kebab);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return string.Join("/", kebabSegments);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/// <summary>Seed entry DTO for navigation module.</summary>
|
|
364
|
-
public class NavigationModuleSeedEntry
|
|
365
|
-
{
|
|
366
|
-
public Guid Id { get; init; }
|
|
367
|
-
public Guid ApplicationId { get; init; }
|
|
368
|
-
public string Code { get; init; } = null!;
|
|
369
|
-
public string Label { get; init; } = null!;
|
|
370
|
-
public string Description { get; init; } = null!;
|
|
371
|
-
public string Icon { get; init; } = null!;
|
|
372
|
-
public IconType IconType { get; init; }
|
|
373
|
-
public string Route { get; init; } = null!;
|
|
374
|
-
public int DisplayOrder { get; init; }
|
|
375
|
-
public bool IsActive { get; init; }
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/// <summary>Seed entry DTO for navigation translation.</summary>
|
|
379
|
-
public class NavigationTranslationSeedEntry
|
|
380
|
-
{
|
|
381
|
-
public NavigationEntityType EntityType { get; init; }
|
|
382
|
-
public Guid EntityId { get; init; }
|
|
383
|
-
public string LanguageCode { get; init; } = null!;
|
|
384
|
-
public string Label { get; init; } = null!;
|
|
385
|
-
public string Description { get; init; } = null!;
|
|
386
|
-
}
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
**Replace placeholders** with values from `navModules[]` and PRD `project` metadata.
|
|
390
|
-
|
|
391
|
-
---
|
|
392
|
-
|
|
393
|
-
## 2b. Navigation Sections & Resources (in same NavigationSeedData.cs)
|
|
394
|
-
|
|
395
|
-
> **CONDITIONAL:** Only generate if `seedDataCore.navigationSections[]` exists and is non-empty in feature.json.
|
|
396
|
-
> Sections and resources are added as additional methods in the **same** `{ModulePascal}NavigationSeedData.cs` file.
|
|
397
|
-
|
|
398
|
-
### GUID Generation Rules
|
|
399
|
-
|
|
400
|
-
```csharp
|
|
401
|
-
// Section GUID: random
|
|
402
|
-
public static readonly Guid {SectionPascal}SectionId = Guid.NewGuid();
|
|
403
|
-
|
|
404
|
-
// Resource GUID: random
|
|
405
|
-
public static readonly Guid {ResourcePascal}ResourceId = Guid.NewGuid();
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
### Section Methods (add to {ModulePascal}NavigationSeedData.cs)
|
|
409
|
-
|
|
410
|
-
> **ROUTE CONVENTION:**
|
|
411
|
-
> ALL sections use a UNIFORM route pattern: module route + `/{section-code}`.
|
|
412
|
-
> - `list` section route = module route + `/list` (e.g., `/human-resources/employees/list`)
|
|
413
|
-
> - `detail` section route = module route + `/:id` (e.g., `/human-resources/employees/:id`) — NOT `/detail/:id` (detail is an implicit route, not a section)
|
|
414
|
-
> - Other sections (dashboard, approve, import) = module route + `/{section-kebab}` (same rule)
|
|
415
|
-
|
|
416
|
-
```csharp
|
|
417
|
-
// --- Add AFTER GetTranslationEntries() in {ModulePascal}NavigationSeedData.cs ---
|
|
418
|
-
|
|
419
|
-
// Random GUIDs for sections
|
|
420
|
-
public static readonly Guid {Section1Pascal}SectionId = Guid.NewGuid();
|
|
421
|
-
// Repeat for each section...
|
|
422
|
-
|
|
423
|
-
/// <summary>
|
|
424
|
-
/// Returns navigation section entries for seeding into core.nav_Sections.
|
|
425
|
-
/// </summary>
|
|
426
|
-
public static IEnumerable<NavigationSectionSeedEntry> GetSectionEntries(Guid moduleId)
|
|
427
|
-
{
|
|
428
|
-
return new[]
|
|
429
|
-
{
|
|
430
|
-
new NavigationSectionSeedEntry
|
|
431
|
-
{
|
|
432
|
-
Id = {Section1Pascal}SectionId,
|
|
433
|
-
ModuleId = moduleId,
|
|
434
|
-
Code = "{section1Code}",
|
|
435
|
-
Label = "{section1_label_en}",
|
|
436
|
-
Description = "{section1_desc_en}",
|
|
437
|
-
Icon = "{section1_icon}",
|
|
438
|
-
IconType = IconType.Lucide,
|
|
439
|
-
// ROUTE CONVENTION: ALL sections use module route + "/{section-code}" (uniform rule)
|
|
440
|
-
// - "list" section → module route + "/list" (e.g., /human-resources/employees/list)
|
|
441
|
-
// - Other sections → module route + "/{section-kebab}" (same rule)
|
|
442
|
-
// Implicit routes (detail, create, edit) are NOT sections — registered by DynamicRouter convention
|
|
443
|
-
Route = "{section_route}", // From seedDataCore.navigationSections[].route
|
|
444
|
-
DisplayOrder = {section1_sort},
|
|
445
|
-
// VISIBILITY RULE (MANDATORY):
|
|
446
|
-
// Reserved codes ("detail", "create", "edit") and codes containing "-detail"
|
|
447
|
-
// are internal route targets, NOT sidebar menu items.
|
|
448
|
-
// → IsActive = false for these codes (DynamicRouter resolves them by convention)
|
|
449
|
-
// → IsActive = true for all other sections (visible in sidebar menu)
|
|
450
|
-
IsActive = true // Set to FALSE if section code is "detail", "create", "edit", or "*-detail"
|
|
451
|
-
}
|
|
452
|
-
// Repeat for each section...
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/// <summary>
|
|
457
|
-
/// Returns 4-language translations for sections.
|
|
458
|
-
/// </summary>
|
|
459
|
-
public static IEnumerable<NavigationTranslationSeedEntry> GetSectionTranslationEntries()
|
|
460
|
-
{
|
|
461
|
-
var entries = new List<NavigationTranslationSeedEntry>();
|
|
462
|
-
|
|
463
|
-
// Section: {section1Code}
|
|
464
|
-
var sec1Id = {Section1Pascal}SectionId;
|
|
465
|
-
entries.AddRange(new[]
|
|
466
|
-
{
|
|
467
|
-
new NavigationTranslationSeedEntry
|
|
468
|
-
{
|
|
469
|
-
EntityType = NavigationEntityType.Section,
|
|
470
|
-
EntityId = sec1Id,
|
|
471
|
-
LanguageCode = "fr",
|
|
472
|
-
Label = "{section1_label_fr}",
|
|
473
|
-
Description = "{section1_desc_fr}"
|
|
474
|
-
},
|
|
475
|
-
new NavigationTranslationSeedEntry
|
|
476
|
-
{
|
|
477
|
-
EntityType = NavigationEntityType.Section,
|
|
478
|
-
EntityId = sec1Id,
|
|
479
|
-
LanguageCode = "en",
|
|
480
|
-
Label = "{section1_label_en}",
|
|
481
|
-
Description = "{section1_desc_en}"
|
|
482
|
-
},
|
|
483
|
-
new NavigationTranslationSeedEntry
|
|
484
|
-
{
|
|
485
|
-
EntityType = NavigationEntityType.Section,
|
|
486
|
-
EntityId = sec1Id,
|
|
487
|
-
LanguageCode = "it",
|
|
488
|
-
Label = "{section1_label_it}",
|
|
489
|
-
Description = "{section1_desc_it}"
|
|
490
|
-
},
|
|
491
|
-
new NavigationTranslationSeedEntry
|
|
492
|
-
{
|
|
493
|
-
EntityType = NavigationEntityType.Section,
|
|
494
|
-
EntityId = sec1Id,
|
|
495
|
-
LanguageCode = "de",
|
|
496
|
-
Label = "{section1_label_de}",
|
|
497
|
-
Description = "{section1_desc_de}"
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
// Repeat for each section...
|
|
501
|
-
|
|
502
|
-
return entries;
|
|
503
|
-
}
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
### Resource Methods (add to {ModulePascal}NavigationSeedData.cs)
|
|
507
|
-
|
|
508
|
-
> **CONDITIONAL:** Only generate if `seedDataCore.navigationResources[]` exists and is non-empty.
|
|
509
|
-
|
|
510
|
-
```csharp
|
|
511
|
-
// --- Add AFTER GetSectionTranslationEntries() ---
|
|
512
|
-
|
|
513
|
-
// Random GUIDs for resources
|
|
514
|
-
public static readonly Guid {Resource1Pascal}ResourceId = Guid.NewGuid();
|
|
515
|
-
// Repeat for each resource...
|
|
516
|
-
|
|
517
|
-
/// <summary>
|
|
518
|
-
/// Returns navigation resource entries for a given section.
|
|
519
|
-
/// </summary>
|
|
520
|
-
public static IEnumerable<NavigationResourceSeedEntry> GetResourceEntries(Guid sectionId)
|
|
521
|
-
{
|
|
522
|
-
var entries = new List<NavigationResourceSeedEntry>();
|
|
523
|
-
|
|
524
|
-
// Resources for section: {section1Code}
|
|
525
|
-
if (sectionId == {Section1Pascal}SectionId)
|
|
526
|
-
{
|
|
527
|
-
entries.AddRange(new[]
|
|
528
|
-
{
|
|
529
|
-
// RESOURCE ROUTE CONVENTION:
|
|
530
|
-
// Resources inherit their parent section's resolved route as base:
|
|
531
|
-
// - Under "list" section → base = module route + /list
|
|
532
|
-
// - Under other sections → base = module route + /{section-kebab}
|
|
533
|
-
// Then append: /{resource-kebab}
|
|
534
|
-
//
|
|
535
|
-
// Example: resource "export" under section "dashboard":
|
|
536
|
-
// Route = /human-resources/employees/dashboard/export
|
|
537
|
-
// Example: resource "employees-grid" under section "list":
|
|
538
|
-
// Route = /human-resources/employees/list/employees-grid
|
|
539
|
-
new NavigationResourceSeedEntry
|
|
540
|
-
{
|
|
541
|
-
Id = {Resource1Pascal}ResourceId,
|
|
542
|
-
SectionId = sectionId,
|
|
543
|
-
Code = "{resource1Code}",
|
|
544
|
-
Label = "{resource1_label_en}",
|
|
545
|
-
EntityType = "{resource1_entity}",
|
|
546
|
-
// Use parent section's resolved route + /{resource-kebab}
|
|
547
|
-
// For "list" sections, route = module route + /list. "detail" is implicit (not a section).
|
|
548
|
-
Route = "{resource_route}", // From seedDataCore: parent section route + /{resource-kebab}
|
|
549
|
-
DisplayOrder = 1
|
|
550
|
-
}
|
|
551
|
-
// Repeat for each resource in this section...
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
// Repeat if-block for each section with resources...
|
|
555
|
-
|
|
556
|
-
return entries;
|
|
557
|
-
}
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
### Additional DTO Classes (add to bottom of file)
|
|
561
|
-
|
|
562
|
-
```csharp
|
|
563
|
-
/// <summary>Seed entry DTO for navigation section.</summary>
|
|
564
|
-
public class NavigationSectionSeedEntry
|
|
565
|
-
{
|
|
566
|
-
public Guid Id { get; init; }
|
|
567
|
-
public Guid ModuleId { get; init; }
|
|
568
|
-
public string Code { get; init; } = null!;
|
|
569
|
-
public string Label { get; init; } = null!;
|
|
570
|
-
public string Description { get; init; } = null!;
|
|
571
|
-
public string Icon { get; init; } = null!;
|
|
572
|
-
public IconType IconType { get; init; }
|
|
573
|
-
public string Route { get; init; } = null!;
|
|
574
|
-
public int DisplayOrder { get; init; }
|
|
575
|
-
public bool IsActive { get; init; }
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/// <summary>Seed entry DTO for navigation resource.</summary>
|
|
579
|
-
public class NavigationResourceSeedEntry
|
|
580
|
-
{
|
|
581
|
-
public Guid Id { get; init; }
|
|
582
|
-
public Guid SectionId { get; init; }
|
|
583
|
-
public string Code { get; init; } = null!;
|
|
584
|
-
public string Label { get; init; } = null!;
|
|
585
|
-
public string? EntityType { get; init; }
|
|
586
|
-
public string? Route { get; init; }
|
|
587
|
-
public int DisplayOrder { get; init; }
|
|
588
|
-
}
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
### Placeholder Values Source
|
|
592
|
-
|
|
593
|
-
| Placeholder | Source in feature.json |
|
|
594
|
-
|-------------|----------------------|
|
|
595
|
-
| `{sectionCode}` | `seedDataCore.navigationSections[].code` |
|
|
596
|
-
| `{section_label_xx}` | `specification.navigation.entries[]` where `level == "section"` → `labels.xx` |
|
|
597
|
-
| `{section_icon}` | `seedDataCore.navigationSections[].icon` |
|
|
598
|
-
| `{section_sort}` | `seedDataCore.navigationSections[].sort` |
|
|
599
|
-
| `{section_route}` | `seedDataCore.navigationSections[].route` — ALL sections use uniform rule: module route + `/{section-code}` (`list` → module route + `/list`). `detail` is implicit (not a section): module route + `/:id`. |
|
|
600
|
-
| `{resourceCode}` | `seedDataCore.navigationResources[].code` |
|
|
601
|
-
| `{resource_entity}` | `seedDataCore.navigationResources[].entity` |
|
|
602
|
-
| `{resource_route}` | Computed from parent section route + `/{resource-kebab}`. For `list` parent → module route + `/list/{resource-kebab}`. For other parents → module route + `/{section-kebab}/{resource-kebab}`. |
|
|
603
|
-
| `{parentSectionCode}` | `seedDataCore.navigationResources[].parentCode` |
|
|
604
|
-
|
|
605
|
-
---
|
|
606
|
-
|
|
607
|
-
## 3. PermissionsSeedData.cs — MCP-First
|
|
608
|
-
|
|
609
|
-
### PermissionAction Safety Rules
|
|
610
|
-
|
|
611
|
-
> Do not use `Enum.Parse<PermissionAction>("...")` — this causes runtime crashes if the string is invalid.
|
|
612
|
-
> The error only manifests at application startup, not at compile time.
|
|
613
|
-
|
|
614
|
-
**Valid PermissionAction values (from SmartStack.Domain.Authorization):**
|
|
615
|
-
|
|
616
|
-
| Enum Value | Int | Description |
|
|
617
|
-
|------------|-----|-------------|
|
|
618
|
-
| `PermissionAction.Access` | 0 | Wildcard permissions only (IsWildcard = true) |
|
|
619
|
-
| `PermissionAction.Read` | 1 | GET/HEAD — View data |
|
|
620
|
-
| `PermissionAction.Create` | 2 | POST — Create new records |
|
|
621
|
-
| `PermissionAction.Update` | 3 | PUT/PATCH — Modify existing records |
|
|
622
|
-
| `PermissionAction.Delete` | 4 | DELETE — Remove records |
|
|
623
|
-
| `PermissionAction.Export` | 5 | Export data (CSV, Excel, etc.) |
|
|
624
|
-
| `PermissionAction.Import` | 6 | Import data |
|
|
625
|
-
| `PermissionAction.Approve` | 7 | Approve workflow items |
|
|
626
|
-
| `PermissionAction.Reject` | 8 | Reject workflow items |
|
|
627
|
-
| `PermissionAction.Assign` | 9 | Assign items to users |
|
|
628
|
-
| `PermissionAction.Execute` | 10 | Execute actions (sync, run, etc.) |
|
|
629
|
-
|
|
630
|
-
**Anti-patterns:**
|
|
631
|
-
|
|
632
|
-
```csharp
|
|
633
|
-
// Runtime crash if string is not a valid enum value
|
|
634
|
-
Enum.Parse<PermissionAction>("Validate"); // ArgumentException at startup
|
|
635
|
-
(PermissionAction)Enum.Parse(typeof(PermissionAction), "Validate"); // Same crash
|
|
636
|
-
|
|
637
|
-
// String-based action in anonymous objects
|
|
638
|
-
new { Action = "read" }; // Not type-safe, silent mismatch possible
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
**Correct patterns:**
|
|
642
|
-
|
|
643
|
-
```csharp
|
|
644
|
-
// ALWAYS use the typed enum directly — compile-time safe
|
|
645
|
-
Action = PermissionAction.Read // Compile-time checked
|
|
646
|
-
Action = PermissionAction.Create // Compile-time checked
|
|
647
|
-
Action = PermissionAction.Approve // Compile-time checked
|
|
648
|
-
|
|
649
|
-
// For custom actions beyond standard CRUD, pick from the enum:
|
|
650
|
-
// Export, Import, Approve, Reject, Assign, Execute
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
**MCP validation:** `validate_conventions` with `checks: ["permissions"]` will detect and flag these anti-patterns.
|
|
654
|
-
|
|
655
|
-
### Step A: Call MCP (PRIMARY)
|
|
656
|
-
|
|
657
|
-
```
|
|
658
|
-
Tool: mcp__smartstack__generate_permissions
|
|
659
|
-
Args:
|
|
660
|
-
navRoute: "{navRoute}"
|
|
661
|
-
includeStandardActions: true
|
|
662
|
-
includeWildcard: true
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
MCP returns:
|
|
666
|
-
- `Permissions.cs` nested class (Application layer constants)
|
|
667
|
-
- Permission seed entries with random GUIDs
|
|
668
|
-
|
|
669
|
-
### Step B: Write Permissions.cs (Application layer)
|
|
670
|
-
|
|
671
|
-
> Permission paths use the SAME kebab-case as NavRoute codes.
|
|
672
|
-
> `{navRoute}` is already kebab-case (e.g., `human-resources.employees`).
|
|
673
|
-
> Do not strip hyphens or derive codes from C# class names.
|
|
674
|
-
> Use `human-resources.employees.read` not `humanresources.employees.read`.
|
|
675
|
-
> SmartStack.app reference: `support-client.my-tickets.read`
|
|
676
|
-
|
|
677
|
-
```csharp
|
|
678
|
-
// Add to Application/Common/Authorization/Permissions.cs
|
|
679
|
-
// IMPORTANT: {navRoute} uses kebab-case segments (e.g., "human-resources.employees")
|
|
680
|
-
// Do NOT derive permission codes from C# identifiers — use navRoute directly
|
|
681
|
-
public static class {AppPascal}
|
|
682
|
-
{
|
|
683
|
-
public static class {ModulePascal}
|
|
684
|
-
{
|
|
685
|
-
public const string View = "{navRoute}.read"; // e.g., "human-resources.employees.read"
|
|
686
|
-
public const string Create = "{navRoute}.create";
|
|
687
|
-
public const string Update = "{navRoute}.update";
|
|
688
|
-
public const string Delete = "{navRoute}.delete";
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
### Step C: Write PermissionsSeedData.cs (Infrastructure layer)
|
|
694
|
-
|
|
695
|
-
**File:** `Infrastructure/Persistence/Seeding/Data/{ModulePascal}/PermissionsSeedData.cs`
|
|
696
|
-
|
|
697
|
-
```csharp
|
|
698
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{ModulePascal};
|
|
699
|
-
|
|
700
|
-
/// <summary>
|
|
701
|
-
/// Permission seed data for {ModuleLabel} module.
|
|
702
|
-
/// Consumed by IClientSeedDataProvider at application startup.
|
|
703
|
-
/// </summary>
|
|
704
|
-
public static class {ModulePascal}PermissionsSeedData
|
|
705
|
-
{
|
|
706
|
-
// Random GUIDs for permissions
|
|
707
|
-
public static readonly Guid WildcardPermId = Guid.NewGuid();
|
|
708
|
-
public static readonly Guid ReadPermId = Guid.NewGuid();
|
|
709
|
-
public static readonly Guid CreatePermId = Guid.NewGuid();
|
|
710
|
-
public static readonly Guid UpdatePermId = Guid.NewGuid();
|
|
711
|
-
public static readonly Guid DeletePermId = Guid.NewGuid();
|
|
712
|
-
|
|
713
|
-
public static IEnumerable<PermissionSeedEntry> GetPermissionEntries(Guid moduleId)
|
|
714
|
-
{
|
|
715
|
-
return new[]
|
|
716
|
-
{
|
|
717
|
-
new PermissionSeedEntry { Id = WildcardPermId, Path = "{navRoute}.*", Level = PermissionLevel.Module, Action = PermissionAction.Access, IsWildcard = true, ModuleId = moduleId, Description = "Full {moduleLabel} access" },
|
|
718
|
-
new PermissionSeedEntry { Id = ReadPermId, Path = "{navRoute}.read", Level = PermissionLevel.Module, Action = PermissionAction.Read, IsWildcard = false, ModuleId = moduleId, Description = "View {moduleLabel}" },
|
|
719
|
-
new PermissionSeedEntry { Id = CreatePermId, Path = "{navRoute}.create", Level = PermissionLevel.Module, Action = PermissionAction.Create, IsWildcard = false, ModuleId = moduleId, Description = "Create {moduleLabel}" },
|
|
720
|
-
new PermissionSeedEntry { Id = UpdatePermId, Path = "{navRoute}.update", Level = PermissionLevel.Module, Action = PermissionAction.Update, IsWildcard = false, ModuleId = moduleId, Description = "Update {moduleLabel}" },
|
|
721
|
-
new PermissionSeedEntry { Id = DeletePermId, Path = "{navRoute}.delete", Level = PermissionLevel.Module, Action = PermissionAction.Delete, IsWildcard = false, ModuleId = moduleId, Description = "Delete {moduleLabel}" }
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// No deterministic GUID generation — all IDs are random via Guid.NewGuid()
|
|
726
|
-
// Permissions are resolved by Path at runtime, not by fixed GUIDs
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
public class PermissionSeedEntry
|
|
730
|
-
{
|
|
731
|
-
public Guid Id { get; init; }
|
|
732
|
-
public string Path { get; init; } = null!;
|
|
733
|
-
public PermissionLevel Level { get; init; }
|
|
734
|
-
public PermissionAction Action { get; init; }
|
|
735
|
-
public bool IsWildcard { get; init; }
|
|
736
|
-
public Guid ModuleId { get; init; }
|
|
737
|
-
public string Description { get; init; } = null!;
|
|
738
|
-
}
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
### Step C2: Section-Level Permissions (CONDITIONAL — filtered by `permissionMode`)
|
|
742
|
-
|
|
743
|
-
> When `seedDataCore.navigationSections` exists and is non-empty in feature.json,
|
|
744
|
-
> add section-level permission GUIDs and entries to `PermissionsSeedData.cs`.
|
|
745
|
-
>
|
|
746
|
-
> **Permission generation is conditional on each section's `permissionMode`:**
|
|
747
|
-
>
|
|
748
|
-
> | permissionMode | Permissions generated |
|
|
749
|
-
> |---|---|
|
|
750
|
-
> | `crud` | wildcard + read + create + update + delete |
|
|
751
|
-
> | `custom:action1,action2` | wildcard + read + custom actions |
|
|
752
|
-
> | `read-only` | read only (NO CRUD wildcard) |
|
|
753
|
-
> | `inherit` | NO section-level permissions (inherits from module) |
|
|
754
|
-
>
|
|
755
|
-
> **Default inference (when `permissionMode` is absent):**
|
|
756
|
-
> - `code === "detail"` → `inherit`
|
|
757
|
-
> - `code === "dashboard"` → `read-only`
|
|
758
|
-
> - otherwise → `crud`
|
|
759
|
-
>
|
|
760
|
-
> **IMPORTANT:** Sections with `permissionMode: inherit` MUST be skipped entirely.
|
|
761
|
-
> Do NOT generate any permission GUIDs, entries, or constants for them.
|
|
762
|
-
|
|
763
|
-
```csharp
|
|
764
|
-
// --- Add to {ModulePascal}PermissionsSeedData class AFTER module-level permissions ---
|
|
765
|
-
// FILTER: Only generate for sections where permissionMode is NOT "inherit"
|
|
766
|
-
// For "read-only" sections: generate ONLY ReadPermId (no Wildcard, Create, Update, Delete)
|
|
767
|
-
// For "custom:x,y" sections: generate Wildcard + Read + custom action GUIDs
|
|
768
|
-
|
|
769
|
-
// Section-level permissions (for each section in navSections[])
|
|
770
|
-
public static readonly Guid {SectionPascal}WildcardPermId = Guid.NewGuid();
|
|
771
|
-
public static readonly Guid {SectionPascal}ReadPermId = Guid.NewGuid();
|
|
772
|
-
public static readonly Guid {SectionPascal}CreatePermId = Guid.NewGuid();
|
|
773
|
-
public static readonly Guid {SectionPascal}UpdatePermId = Guid.NewGuid();
|
|
774
|
-
public static readonly Guid {SectionPascal}DeletePermId = Guid.NewGuid();
|
|
775
|
-
// Repeat for each section...
|
|
776
|
-
|
|
777
|
-
// Add to GetPermissionEntries() — AFTER module-level entries:
|
|
778
|
-
// Section: {sectionCode}
|
|
779
|
-
new PermissionSeedEntry { Id = {SectionPascal}WildcardPermId, Path = "{navRoute}.{sectionCode}.*", Level = PermissionLevel.Section, Action = PermissionAction.Access, IsWildcard = true, ModuleId = moduleId, Description = "Full {sectionLabel} access" },
|
|
780
|
-
new PermissionSeedEntry { Id = {SectionPascal}ReadPermId, Path = "{navRoute}.{sectionCode}.read", Level = PermissionLevel.Section, Action = PermissionAction.Read, IsWildcard = false, ModuleId = moduleId, Description = "View {sectionLabel}" },
|
|
781
|
-
new PermissionSeedEntry { Id = {SectionPascal}CreatePermId, Path = "{navRoute}.{sectionCode}.create", Level = PermissionLevel.Section, Action = PermissionAction.Create, IsWildcard = false, ModuleId = moduleId, Description = "Create {sectionLabel}" },
|
|
782
|
-
new PermissionSeedEntry { Id = {SectionPascal}UpdatePermId, Path = "{navRoute}.{sectionCode}.update", Level = PermissionLevel.Section, Action = PermissionAction.Update, IsWildcard = false, ModuleId = moduleId, Description = "Update {sectionLabel}" },
|
|
783
|
-
new PermissionSeedEntry { Id = {SectionPascal}DeletePermId, Path = "{navRoute}.{sectionCode}.delete", Level = PermissionLevel.Section, Action = PermissionAction.Delete, IsWildcard = false, ModuleId = moduleId, Description = "Delete {sectionLabel}" },
|
|
784
|
-
// Repeat for each section...
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
Also add section-level constants to `Permissions.cs` (Application layer):
|
|
788
|
-
|
|
789
|
-
```csharp
|
|
790
|
-
public static class {ModulePascal}
|
|
791
|
-
{
|
|
792
|
-
// ... existing module-level permissions ...
|
|
793
|
-
|
|
794
|
-
// Section-level (for each section in navSections[])
|
|
795
|
-
public static class {SectionPascal}
|
|
796
|
-
{
|
|
797
|
-
public const string View = "{navRoute}.{sectionCode}.read";
|
|
798
|
-
public const string Create = "{navRoute}.{sectionCode}.create";
|
|
799
|
-
public const string Update = "{navRoute}.{sectionCode}.update";
|
|
800
|
-
public const string Delete = "{navRoute}.{sectionCode}.delete";
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
```
|
|
804
|
-
|
|
805
|
-
### Step D: MCP Fallback
|
|
806
|
-
|
|
807
|
-
If MCP `generate_permissions` fails, use the template above directly with values derived from the PRD `coreSeedData.permissions[]`.
|
|
808
|
-
|
|
809
|
-
---
|
|
810
|
-
|
|
811
|
-
## 4. ApplicationRolesSeedData.cs (Application-Level, Once per Application)
|
|
812
|
-
|
|
813
|
-
**File:** `Infrastructure/Persistence/Seeding/Data/ApplicationRolesSeedData.cs`
|
|
814
|
-
|
|
815
|
-
### Purpose
|
|
816
|
-
|
|
817
|
-
Creates the 4 standard application-scoped roles: Admin, Manager, Contributor, Viewer.
|
|
818
|
-
|
|
819
|
-
> SmartStack core MAY already provide system roles (admin, manager, contributor, viewer).
|
|
820
|
-
> If system roles already exist in `auth_Roles`, do not create duplicates.
|
|
821
|
-
> `SeedRolesAsync()` must check existence by Code, not just by ApplicationId.
|
|
822
|
-
> For RolePermission mappings: always look up roles by Code at runtime (in `SeedRolePermissionsAsync()`).
|
|
823
|
-
> Do not use `GenerateRoleGuid()`, `DeterministicGuid("role:admin")`, or any hardcoded role GUID
|
|
824
|
-
> when creating RolePermission entries. The role GUIDs may differ from what's in the database.
|
|
825
|
-
|
|
826
|
-
This file is created once per application (not per module).
|
|
827
|
-
|
|
828
|
-
### GUID Generation Rule
|
|
829
|
-
|
|
830
|
-
> **NOTE:** Role GUIDs are random (`Guid.NewGuid()`). Roles are resolved by Code at runtime.
|
|
831
|
-
> RolePermission mapping MUST look up roles by Code, not by GUID.
|
|
832
|
-
|
|
833
|
-
```csharp
|
|
834
|
-
// All role GUIDs are random — always resolve roles by Code at runtime
|
|
835
|
-
// Do not use hardcoded GUIDs in RolePermission mapping
|
|
836
|
-
var role = roles.FirstOrDefault(r => r.Code == "admin");
|
|
837
|
-
```
|
|
838
|
-
|
|
839
|
-
### Template
|
|
840
|
-
|
|
841
|
-
```csharp
|
|
842
|
-
using SmartStack.Domain.Platform.Administration.Roles;
|
|
843
|
-
|
|
844
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
|
|
845
|
-
|
|
846
|
-
/// <summary>
|
|
847
|
-
/// Application-scoped role seed data for {AppLabel}.
|
|
848
|
-
/// Defines the 4 standard application roles: Admin, Manager, Contributor, Viewer.
|
|
849
|
-
/// Consumed by IClientSeedDataProvider at application startup.
|
|
850
|
-
/// </summary>
|
|
851
|
-
public static class ApplicationRolesSeedData
|
|
852
|
-
{
|
|
853
|
-
// Application ID from NavigationApplicationSeedData
|
|
854
|
-
public static readonly Guid ApplicationId = NavigationApplicationSeedData.ApplicationId;
|
|
855
|
-
|
|
856
|
-
public static readonly Guid AdminRoleId = Guid.NewGuid();
|
|
857
|
-
public static readonly Guid ManagerRoleId = Guid.NewGuid();
|
|
858
|
-
public static readonly Guid ContributorRoleId = Guid.NewGuid();
|
|
859
|
-
public static readonly Guid ViewerRoleId = Guid.NewGuid();
|
|
860
|
-
|
|
861
|
-
public static IEnumerable<ApplicationRoleSeedEntry> GetRoleEntries()
|
|
862
|
-
{
|
|
863
|
-
yield return new ApplicationRoleSeedEntry
|
|
864
|
-
{
|
|
865
|
-
Id = AdminRoleId,
|
|
866
|
-
Code = "admin",
|
|
867
|
-
Name = "{AppLabel} Admin",
|
|
868
|
-
Description = "Full administrative access to {AppLabel}",
|
|
869
|
-
ApplicationId = ApplicationId,
|
|
870
|
-
IsSystem = false,
|
|
871
|
-
IsActive = true,
|
|
872
|
-
DisplayOrder = 1
|
|
873
|
-
};
|
|
874
|
-
|
|
875
|
-
yield return new ApplicationRoleSeedEntry
|
|
876
|
-
{
|
|
877
|
-
Id = ManagerRoleId,
|
|
878
|
-
Code = "manager",
|
|
879
|
-
Name = "{AppLabel} Manager",
|
|
880
|
-
Description = "Management access to {AppLabel} (Create, Read, Update)",
|
|
881
|
-
ApplicationId = ApplicationId,
|
|
882
|
-
IsSystem = false,
|
|
883
|
-
IsActive = true,
|
|
884
|
-
DisplayOrder = 2
|
|
885
|
-
};
|
|
886
|
-
|
|
887
|
-
yield return new ApplicationRoleSeedEntry
|
|
888
|
-
{
|
|
889
|
-
Id = ContributorRoleId,
|
|
890
|
-
Code = "contributor",
|
|
891
|
-
Name = "{AppLabel} Contributor",
|
|
892
|
-
Description = "Contributor access to {AppLabel} (Create, Read)",
|
|
893
|
-
ApplicationId = ApplicationId,
|
|
894
|
-
IsSystem = false,
|
|
895
|
-
IsActive = true,
|
|
896
|
-
DisplayOrder = 3
|
|
897
|
-
};
|
|
898
|
-
|
|
899
|
-
yield return new ApplicationRoleSeedEntry
|
|
900
|
-
{
|
|
901
|
-
Id = ViewerRoleId,
|
|
902
|
-
Code = "viewer",
|
|
903
|
-
Name = "{AppLabel} Viewer",
|
|
904
|
-
Description = "Read-only access to {AppLabel}",
|
|
905
|
-
ApplicationId = ApplicationId,
|
|
906
|
-
IsSystem = false,
|
|
907
|
-
IsActive = true,
|
|
908
|
-
DisplayOrder = 4
|
|
909
|
-
};
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
// No deterministic GUID generation — all IDs are random via Guid.NewGuid()
|
|
913
|
-
// Roles are resolved by Code at runtime
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
public class ApplicationRoleSeedEntry
|
|
917
|
-
{
|
|
918
|
-
public Guid Id { get; init; }
|
|
919
|
-
public string Code { get; init; } = null!;
|
|
920
|
-
public string Name { get; init; } = null!;
|
|
921
|
-
public string Description { get; init; } = null!;
|
|
922
|
-
public Guid ApplicationId { get; init; }
|
|
923
|
-
public bool IsSystem { get; init; }
|
|
924
|
-
public bool IsActive { get; init; }
|
|
925
|
-
public int DisplayOrder { get; init; }
|
|
926
|
-
}
|
|
927
|
-
```
|
|
928
|
-
|
|
929
|
-
**Replace placeholders** with values from PRD and navigation metadata.
|
|
930
|
-
|
|
931
|
-
---
|
|
932
|
-
|
|
933
|
-
## 5. {Module}RolesSeedData.cs (Per Module)
|
|
934
|
-
|
|
935
|
-
**File:** `Infrastructure/Persistence/Seeding/Data/{ModulePascal}/RolesSeedData.cs`
|
|
936
|
-
|
|
937
|
-
> This file uses `RoleCode` (string), not role GUIDs.
|
|
938
|
-
> Roles are resolved by Code at runtime in `SeedRolePermissionsAsync()`.
|
|
939
|
-
> Do not use `DeterministicGuid("role:admin")`, `GenerateRoleGuid("admin")`, or any hardcoded Guid for roles.
|
|
940
|
-
> SmartStack core pre-seeds system roles — their IDs are not deterministic from the client perspective.
|
|
941
|
-
|
|
942
|
-
### Context-Based Role Mapping
|
|
943
|
-
|
|
944
|
-
| Application | Admin | Manager | Contributor | Viewer |
|
|
945
|
-
|-------------|-------|---------|-------------|--------|
|
|
946
|
-
| Any | CRUD | CRU | CR | R |
|
|
947
|
-
|
|
948
|
-
### Template
|
|
949
|
-
|
|
950
|
-
```csharp
|
|
951
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{ModulePascal};
|
|
952
|
-
|
|
953
|
-
/// <summary>
|
|
954
|
-
/// Role-permission mapping seed data for {ModuleLabel} module.
|
|
955
|
-
/// Maps permissions to application-scoped roles (Admin, Manager, Contributor, Viewer).
|
|
956
|
-
/// Consumed by IClientSeedDataProvider at application startup.
|
|
957
|
-
/// </summary>
|
|
958
|
-
public static class {ModulePascal}RolesSeedData
|
|
959
|
-
{
|
|
960
|
-
/// <summary>
|
|
961
|
-
/// Returns role-permission mappings for this module.
|
|
962
|
-
/// Roles are resolved at runtime by Code (not hardcoded GUIDs).
|
|
963
|
-
/// </summary>
|
|
964
|
-
public static IEnumerable<RolePermissionSeedEntry> GetRolePermissionEntries()
|
|
965
|
-
{
|
|
966
|
-
// Admin: wildcard access
|
|
967
|
-
yield return new RolePermissionSeedEntry { RoleCode = "admin", PermissionPath = "{navRoute}.*" };
|
|
968
|
-
|
|
969
|
-
// Manager: CRU (read + create + update — no delete)
|
|
970
|
-
yield return new RolePermissionSeedEntry { RoleCode = "manager", PermissionPath = "{navRoute}.read" };
|
|
971
|
-
yield return new RolePermissionSeedEntry { RoleCode = "manager", PermissionPath = "{navRoute}.create" };
|
|
972
|
-
yield return new RolePermissionSeedEntry { RoleCode = "manager", PermissionPath = "{navRoute}.update" };
|
|
973
|
-
|
|
974
|
-
// Contributor: CR
|
|
975
|
-
yield return new RolePermissionSeedEntry { RoleCode = "contributor", PermissionPath = "{navRoute}.read" };
|
|
976
|
-
yield return new RolePermissionSeedEntry { RoleCode = "contributor", PermissionPath = "{navRoute}.create" };
|
|
977
|
-
|
|
978
|
-
// Viewer: R
|
|
979
|
-
yield return new RolePermissionSeedEntry { RoleCode = "viewer", PermissionPath = "{navRoute}.read" };
|
|
980
|
-
|
|
981
|
-
// --- Section-level role mappings (CONDITIONAL: for each section in navSections[]) ---
|
|
982
|
-
// Admin: wildcard per section
|
|
983
|
-
yield return new RolePermissionSeedEntry { RoleCode = "admin", PermissionPath = "{navRoute}.{sectionCode}.*" };
|
|
984
|
-
|
|
985
|
-
// Manager: CRU per section (read + create + update — no delete)
|
|
986
|
-
yield return new RolePermissionSeedEntry { RoleCode = "manager", PermissionPath = "{navRoute}.{sectionCode}.read" };
|
|
987
|
-
yield return new RolePermissionSeedEntry { RoleCode = "manager", PermissionPath = "{navRoute}.{sectionCode}.create" };
|
|
988
|
-
yield return new RolePermissionSeedEntry { RoleCode = "manager", PermissionPath = "{navRoute}.{sectionCode}.update" };
|
|
989
|
-
|
|
990
|
-
// Contributor: CR per section
|
|
991
|
-
yield return new RolePermissionSeedEntry { RoleCode = "contributor", PermissionPath = "{navRoute}.{sectionCode}.read" };
|
|
992
|
-
yield return new RolePermissionSeedEntry { RoleCode = "contributor", PermissionPath = "{navRoute}.{sectionCode}.create" };
|
|
993
|
-
|
|
994
|
-
// Viewer: R per section
|
|
995
|
-
yield return new RolePermissionSeedEntry { RoleCode = "viewer", PermissionPath = "{navRoute}.{sectionCode}.read" };
|
|
996
|
-
// Repeat block for each section in navSections[]...
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
public class RolePermissionSeedEntry
|
|
1001
|
-
{
|
|
1002
|
-
public string RoleCode { get; init; } = null!;
|
|
1003
|
-
public string PermissionPath { get; init; } = null!;
|
|
1004
|
-
}
|
|
1005
|
-
```
|
|
1006
|
-
|
|
1007
|
-
---
|
|
1008
|
-
|
|
1009
|
-
## 6. IClientSeedDataProvider Implementation
|
|
1010
|
-
|
|
1011
|
-
> **IMPORTANT — HasData vs Seed*Async: TWO DIFFERENT MECHANISMS**
|
|
1012
|
-
>
|
|
1013
|
-
> | Mechanism | Where | When | Purpose |
|
|
1014
|
-
> |-----------|-------|------|---------|
|
|
1015
|
-
> | **EF Core `HasData()`** | `*Configuration.cs` (Infrastructure) | At migration time | Seeds static reference data into tables via `INSERT` in migration SQL. Data is part of the migration — no runtime code needed. |
|
|
1016
|
-
> | **`IClientSeedDataProvider.Seed*Async()`** | `*SeedDataProvider.cs` (Infrastructure) | At runtime startup | Seeds navigation, roles, permissions, role-permissions into the **Core** schema. Runs AFTER `MigrateAsync()` in `Program.cs`. |
|
|
1017
|
-
>
|
|
1018
|
-
> **Common mistake:** Generating `HasData()` calls for navigation/permissions instead of `Seed*Async()` methods.
|
|
1019
|
-
> Navigation and permission data goes into the **Core** schema (`core.nav_*`, `core.auth_*`) which is managed
|
|
1020
|
-
> by SmartStack, not by the client's migration. Only `IClientSeedDataProvider` can write to Core tables at runtime.
|
|
1021
|
-
>
|
|
1022
|
-
> **ANTI-STUB WARNING:** Each of the 4 Seed methods MUST contain real `context.{DbSet}.Add()` calls.
|
|
1023
|
-
> If ANY method is just `return Task.CompletedTask;`, the module will be **invisible** in the UI (empty menu).
|
|
1024
|
-
> This happens when this reference file is evicted from context by compression — see step-03b safeguard.
|
|
1025
|
-
|
|
1026
|
-
**File:** `Infrastructure/Persistence/Seeding/{AppPascalName}SeedDataProvider.cs`
|
|
1027
|
-
|
|
1028
|
-
### Critical Rules
|
|
1029
|
-
|
|
1030
|
-
| Rule | Description |
|
|
1031
|
-
|------|-------------|
|
|
1032
|
-
| Factory methods | `NavigationApplication.Create(zone, ...)`, `Role.Create(name, shortName, category, ...)`, `Permission.CreateForModule(...)` — NEVER `new Entity()` |
|
|
1033
|
-
| Idempotence | Each Seed method checks existence before inserting |
|
|
1034
|
-
| Execution order | Navigation → Roles → Permissions → RolePermissions (roles MUST exist before mapping) |
|
|
1035
|
-
| SaveChanges per group | Navigation -> save -> Roles -> save -> Permissions -> save -> RolePermissions -> save |
|
|
1036
|
-
| FK resolution by Code | Parent entities (applications, modules, roles) found by `Code` from DB, not seed-time GUID |
|
|
1037
|
-
| Translation EntityId | ALWAYS use actual DB ID (`app.Id`, `mod1Entity.Id`, `actualSection.Id`), NEVER seed-time GUID from SeedData classes |
|
|
1038
|
-
| DI registration | `services.AddScoped<IClientSeedDataProvider, {AppPascalName}SeedDataProvider>()` |
|
|
1039
|
-
|
|
1040
|
-
### Template
|
|
1041
|
-
|
|
1042
|
-
```csharp
|
|
1043
|
-
using Microsoft.EntityFrameworkCore;
|
|
1044
|
-
using SmartStack.Application.Common.Interfaces;
|
|
1045
|
-
using SmartStack.Application.Common.Interfaces.Seeding;
|
|
1046
|
-
using SmartStack.Domain.Navigation;
|
|
1047
|
-
using SmartStack.Domain.Platform.Administration.Roles;
|
|
1048
|
-
using {BaseNamespace}.Infrastructure.Persistence.Seeding.Data;
|
|
1049
|
-
using {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{Module1Pascal};
|
|
1050
|
-
// using {BaseNamespace}.Infrastructure.Persistence.Seeding.Data.{Module2Pascal}; // Add per module
|
|
1051
|
-
|
|
1052
|
-
namespace {BaseNamespace}.Infrastructure.Persistence.Seeding;
|
|
1053
|
-
|
|
1054
|
-
/// <summary>
|
|
1055
|
-
/// Seeds {AppLabel} navigation, roles, permissions, and role-permission data
|
|
1056
|
-
/// into the SmartStack Core schema at application startup.
|
|
1057
|
-
/// </summary>
|
|
1058
|
-
public class {AppPascalName}SeedDataProvider : IClientSeedDataProvider
|
|
1059
|
-
{
|
|
1060
|
-
public int Order => 100;
|
|
1061
|
-
|
|
1062
|
-
public async Task SeedNavigationAsync(ICoreDbContext context, CancellationToken ct)
|
|
1063
|
-
{
|
|
1064
|
-
// --- Application (from NavigationApplicationSeedData) ---
|
|
1065
|
-
// NOTE: Idempotence is at MODULE level (not application level).
|
|
1066
|
-
// If the application already exists, we load it and continue to seed any missing modules.
|
|
1067
|
-
// This allows adding Module 2+ to an existing application without re-running the full seed.
|
|
1068
|
-
var appEntry = NavigationApplicationSeedData.GetApplicationEntry();
|
|
1069
|
-
var existingApp = await context.NavigationApplications
|
|
1070
|
-
.FirstOrDefaultAsync(a => a.Code == appEntry.Code, ct);
|
|
1071
|
-
|
|
1072
|
-
NavigationApplication app;
|
|
1073
|
-
if (existingApp != null)
|
|
1074
|
-
{
|
|
1075
|
-
app = existingApp; // Application already seeded — reuse it for module seeding below
|
|
1076
|
-
}
|
|
1077
|
-
else
|
|
1078
|
-
{
|
|
1079
|
-
app = NavigationApplication.Create(
|
|
1080
|
-
appEntry.Zone, appEntry.Code, appEntry.Label,
|
|
1081
|
-
appEntry.Description, appEntry.Icon, appEntry.IconType,
|
|
1082
|
-
appEntry.Route, appEntry.DisplayOrder);
|
|
1083
|
-
context.NavigationApplications.Add(app);
|
|
1084
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1085
|
-
|
|
1086
|
-
// --- Application translations (4 languages, from NavigationApplicationSeedData) ---
|
|
1087
|
-
foreach (var t in NavigationApplicationSeedData.GetTranslationEntries())
|
|
1088
|
-
{
|
|
1089
|
-
context.NavigationTranslations.Add(
|
|
1090
|
-
NavigationTranslation.Create(t.EntityType, app.Id, t.LanguageCode, t.Label, t.Description));
|
|
1091
|
-
}
|
|
1092
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
// --- Modules (idempotent per-module — allows adding Module 2+ later) ---
|
|
1096
|
-
// Module: {Module1}
|
|
1097
|
-
var mod1Exists = await context.NavigationModules
|
|
1098
|
-
.AnyAsync(m => m.Code == "{module1Code}" && m.ApplicationId == app.Id, ct);
|
|
1099
|
-
if (!mod1Exists)
|
|
1100
|
-
{
|
|
1101
|
-
var mod1Entry = {Module1Pascal}NavigationSeedData.GetModuleEntry(app.Id);
|
|
1102
|
-
var mod1 = NavigationModule.Create(
|
|
1103
|
-
mod1Entry.ApplicationId, mod1Entry.Code, mod1Entry.Label,
|
|
1104
|
-
mod1Entry.Description, mod1Entry.Icon, mod1Entry.IconType,
|
|
1105
|
-
mod1Entry.Route, mod1Entry.DisplayOrder);
|
|
1106
|
-
context.NavigationModules.Add(mod1);
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// Repeat for each module (each with its own idempotence check)...
|
|
1110
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1111
|
-
|
|
1112
|
-
// Resolve module entities for section/resource seeding (works for both new AND existing modules)
|
|
1113
|
-
var mod1Entity = await context.NavigationModules
|
|
1114
|
-
.FirstOrDefaultAsync(m => m.Code == "{module1Code}" && m.ApplicationId == app.Id, ct)
|
|
1115
|
-
?? throw new InvalidOperationException(
|
|
1116
|
-
$"Seed data dependency missing: NavigationModule '{"{module1Code}"}' not found for app '{app.Code}'. " +
|
|
1117
|
-
$"Ensure the module was created in the navigation seeding step above.");
|
|
1118
|
-
// Repeat for each module...
|
|
1119
|
-
|
|
1120
|
-
// --- Module translations (idempotent — unique index IX_nav_Translations_EntityType_EntityId_LanguageCode) ---
|
|
1121
|
-
// Always check existence before inserting translations to avoid duplicate key errors
|
|
1122
|
-
// on re-runs, partial failures, or DB reset scenarios.
|
|
1123
|
-
// CRITICAL: Use mod1Entity.Id (actual DB ID), NOT seed-time GUID from SeedData class.
|
|
1124
|
-
if (!await context.NavigationTranslations.AnyAsync(
|
|
1125
|
-
t => t.EntityId == mod1Entity.Id
|
|
1126
|
-
&& t.EntityType == NavigationEntityType.Module, ct))
|
|
1127
|
-
{
|
|
1128
|
-
foreach (var t in {Module1Pascal}NavigationSeedData.GetTranslationEntries())
|
|
1129
|
-
{
|
|
1130
|
-
context.NavigationTranslations.Add(
|
|
1131
|
-
NavigationTranslation.Create(t.EntityType, mod1Entity.Id, t.LanguageCode, t.Label, t.Description));
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
// Repeat for each module...
|
|
1135
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1136
|
-
|
|
1137
|
-
// --- Sections (idempotent — check each section before inserting) ---
|
|
1138
|
-
// Module 1 sections
|
|
1139
|
-
foreach (var secEntry in {Module1Pascal}NavigationSeedData.GetSectionEntries(mod1Entity.Id))
|
|
1140
|
-
{
|
|
1141
|
-
var secExists = await context.NavigationSections
|
|
1142
|
-
.AnyAsync(s => s.Code == secEntry.Code && s.ModuleId == mod1Entity.Id, ct);
|
|
1143
|
-
if (!secExists)
|
|
1144
|
-
{
|
|
1145
|
-
var sec = NavigationSection.Create(
|
|
1146
|
-
secEntry.ModuleId, secEntry.Code, secEntry.Label,
|
|
1147
|
-
secEntry.Description, secEntry.Icon, secEntry.IconType,
|
|
1148
|
-
secEntry.Route, secEntry.DisplayOrder);
|
|
1149
|
-
context.NavigationSections.Add(sec);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
// Repeat for each module that has sections...
|
|
1153
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1154
|
-
|
|
1155
|
-
// --- Section translations (idempotent — check before inserting) ---
|
|
1156
|
-
// CRITICAL: secEntry.Id is a seed-time GUID ≠ actual DB ID.
|
|
1157
|
-
// Resolve actual section from DB by Code+ModuleId to get the real ID.
|
|
1158
|
-
foreach (var secEntry in {Module1Pascal}NavigationSeedData.GetSectionEntries(mod1Entity.Id))
|
|
1159
|
-
{
|
|
1160
|
-
var actualSection = await context.NavigationSections
|
|
1161
|
-
.FirstAsync(s => s.Code == secEntry.Code && s.ModuleId == mod1Entity.Id, ct);
|
|
1162
|
-
|
|
1163
|
-
if (!await context.NavigationTranslations.AnyAsync(
|
|
1164
|
-
t => t.EntityId == actualSection.Id && t.EntityType == NavigationEntityType.Section, ct))
|
|
1165
|
-
{
|
|
1166
|
-
foreach (var t in {Module1Pascal}NavigationSeedData.GetSectionTranslationEntries()
|
|
1167
|
-
.Where(st => st.EntityId == secEntry.Id))
|
|
1168
|
-
{
|
|
1169
|
-
context.NavigationTranslations.Add(
|
|
1170
|
-
NavigationTranslation.Create(t.EntityType, actualSection.Id, t.LanguageCode, t.Label, t.Description));
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
// Repeat for each module that has sections...
|
|
1175
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1176
|
-
|
|
1177
|
-
// --- Resources (idempotent — use ACTUAL section IDs from DB, not deterministic seed IDs) ---
|
|
1178
|
-
// NavigationSection.Create() generates its own ID in DB.
|
|
1179
|
-
// The GUID from GetSectionEntries() is not the actual SectionId in DB.
|
|
1180
|
-
// Query the real section by Code+ModuleId to get the actual DB ID,
|
|
1181
|
-
// otherwise FK_nav_Resources_nav_Sections_SectionId will fail.
|
|
1182
|
-
foreach (var secEntry in {Module1Pascal}NavigationSeedData.GetSectionEntries(mod1Entity.Id))
|
|
1183
|
-
{
|
|
1184
|
-
var actualSection = await context.NavigationSections
|
|
1185
|
-
.FirstAsync(s => s.Code == secEntry.Code && s.ModuleId == mod1Entity.Id, ct);
|
|
1186
|
-
|
|
1187
|
-
foreach (var resEntry in {Module1Pascal}NavigationSeedData.GetResourceEntries(secEntry.Id))
|
|
1188
|
-
{
|
|
1189
|
-
var resExists = await context.NavigationResources
|
|
1190
|
-
.AnyAsync(r => r.Code == resEntry.Code && r.SectionId == actualSection.Id, ct);
|
|
1191
|
-
if (!resExists)
|
|
1192
|
-
{
|
|
1193
|
-
var res = NavigationResource.Create(
|
|
1194
|
-
actualSection.Id, resEntry.Code, resEntry.Label,
|
|
1195
|
-
resEntry.EntityType, resEntry.Route, resEntry.DisplayOrder);
|
|
1196
|
-
context.NavigationResources.Add(res);
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
// Repeat for each module that has resources...
|
|
1201
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
public async Task SeedRolesAsync(ICoreDbContext context, CancellationToken ct)
|
|
1205
|
-
{
|
|
1206
|
-
// Resolve application from DB by Code — NOT seed-time GUID
|
|
1207
|
-
var app = await context.NavigationApplications
|
|
1208
|
-
.FirstAsync(a => a.Code == "{appCode}", ct);
|
|
1209
|
-
|
|
1210
|
-
// Check idempotence — verify by Code, scoped by actual DB ApplicationId
|
|
1211
|
-
var existingRoleCodes = await context.Roles
|
|
1212
|
-
.Where(r => r.ApplicationId == app.Id
|
|
1213
|
-
&& (r.Code == "admin" || r.Code == "manager" || r.Code == "contributor" || r.Code == "viewer"))
|
|
1214
|
-
.Select(r => r.Code)
|
|
1215
|
-
.ToListAsync(ct);
|
|
1216
|
-
|
|
1217
|
-
// Only create roles that don't already exist (SmartStack core may pre-seed system roles)
|
|
1218
|
-
foreach (var entry in ApplicationRolesSeedData.GetRoleEntries())
|
|
1219
|
-
{
|
|
1220
|
-
if (existingRoleCodes.Contains(entry.Code)) continue; // Skip if already exists
|
|
1221
|
-
|
|
1222
|
-
var role = Role.Create(
|
|
1223
|
-
name: entry.Name,
|
|
1224
|
-
shortName: entry.Code,
|
|
1225
|
-
category: RoleCategory.Application,
|
|
1226
|
-
description: entry.Description,
|
|
1227
|
-
isSystem: entry.IsSystem,
|
|
1228
|
-
applicationId: app.Id,
|
|
1229
|
-
code: entry.Code);
|
|
1230
|
-
context.Roles.Add(role);
|
|
1231
|
-
}
|
|
1232
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
public async Task SeedPermissionsAsync(ICoreDbContext context, CancellationToken ct)
|
|
1236
|
-
{
|
|
1237
|
-
var exists = await context.Permissions
|
|
1238
|
-
.AnyAsync(p => p.Path == "{appCode}.*", ct);
|
|
1239
|
-
if (exists) return;
|
|
1240
|
-
|
|
1241
|
-
// Application-level wildcard
|
|
1242
|
-
var appWildcard = Permission.CreateWildcard(
|
|
1243
|
-
"{appCode}.*", PermissionLevel.Application,
|
|
1244
|
-
"Full {appLabel_en} access");
|
|
1245
|
-
context.Permissions.Add(appWildcard);
|
|
1246
|
-
|
|
1247
|
-
// Module permissions
|
|
1248
|
-
var mod1 = await context.NavigationModules
|
|
1249
|
-
.FirstAsync(m => m.Code == "{module1Code}", ct);
|
|
1250
|
-
foreach (var entry in {Module1Pascal}PermissionsSeedData.GetPermissionEntries(mod1.Id))
|
|
1251
|
-
{
|
|
1252
|
-
var perm = entry.IsWildcard
|
|
1253
|
-
? Permission.CreateWildcard(entry.Path, entry.Level, entry.Description)
|
|
1254
|
-
: Permission.CreateForModule(entry.Path, entry.Level, entry.Action, false, entry.ModuleId, entry.Description);
|
|
1255
|
-
context.Permissions.Add(perm);
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
// Repeat for each module...
|
|
1259
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1262
|
-
public async Task SeedRolePermissionsAsync(ICoreDbContext context, CancellationToken ct)
|
|
1263
|
-
{
|
|
1264
|
-
var exists = await context.RolePermissions
|
|
1265
|
-
.AnyAsync(rp => rp.Permission!.Path.StartsWith("{appCode}."), ct);
|
|
1266
|
-
if (exists) return;
|
|
1267
|
-
|
|
1268
|
-
// Resolve application from DB by Code — NOT seed-time GUID
|
|
1269
|
-
var app = await context.NavigationApplications
|
|
1270
|
-
.FirstAsync(a => a.Code == "{appCode}", ct);
|
|
1271
|
-
|
|
1272
|
-
// Resolve roles by Code from DB — do not use hardcoded GUIDs.
|
|
1273
|
-
// Application-scoped roles (admin, manager, contributor, viewer) are created by
|
|
1274
|
-
// SeedRolesAsync() above. System roles use their own IDs that do not match
|
|
1275
|
-
// DeterministicGuid("role:admin").
|
|
1276
|
-
// Load THIS application's roles + system roles only
|
|
1277
|
-
var roles = await context.Roles
|
|
1278
|
-
.Where(r => r.ApplicationId == app.Id || r.IsSystem)
|
|
1279
|
-
.ToListAsync(ct);
|
|
1280
|
-
|
|
1281
|
-
// Resolve permissions
|
|
1282
|
-
var permissions = await context.Permissions
|
|
1283
|
-
.Where(p => p.Path.StartsWith("{appCode}."))
|
|
1284
|
-
.ToListAsync(ct);
|
|
1285
|
-
|
|
1286
|
-
// Apply role-permission mappings from all modules
|
|
1287
|
-
var allMappings = new List<RolePermissionSeedEntry>();
|
|
1288
|
-
allMappings.AddRange({Module1Pascal}RolesSeedData.GetRolePermissionEntries());
|
|
1289
|
-
// allMappings.AddRange({Module2Pascal}RolesSeedData.GetRolePermissionEntries()); // per module
|
|
1290
|
-
|
|
1291
|
-
foreach (var mapping in allMappings)
|
|
1292
|
-
{
|
|
1293
|
-
var role = roles.FirstOrDefault(r => r.Code == mapping.RoleCode);
|
|
1294
|
-
var perm = permissions.FirstOrDefault(p => p.Path == mapping.PermissionPath);
|
|
1295
|
-
|
|
1296
|
-
if (role == null)
|
|
1297
|
-
{
|
|
1298
|
-
// Role not found — SeedRolesAsync() may not have run.
|
|
1299
|
-
// This causes silent permission failure → 401 on protected pages.
|
|
1300
|
-
Console.WriteLine($"[SEED WARNING] Role '{mapping.RoleCode}' not found. Role-permission mapping skipped for '{mapping.PermissionPath}'.");
|
|
1301
|
-
continue;
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
if (perm == null)
|
|
1305
|
-
{
|
|
1306
|
-
Console.WriteLine($"[SEED WARNING] Permission '{mapping.PermissionPath}' not found. Role-permission mapping skipped for role '{mapping.RoleCode}'.");
|
|
1307
|
-
continue;
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
context.RolePermissions.Add(RolePermission.Create(role.Id, perm.Id, "system"));
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
await ((DbContext)context).SaveChangesAsync(ct);
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
```
|
|
1317
|
-
|
|
1318
|
-
### DI Registration
|
|
1319
|
-
|
|
1320
|
-
```csharp
|
|
1321
|
-
// In Infrastructure/DependencyInjection.cs — add:
|
|
1322
|
-
using SmartStack.Application.Common.Interfaces.Seeding;
|
|
1323
|
-
|
|
1324
|
-
// In the registration method:
|
|
1325
|
-
services.AddScoped<IClientSeedDataProvider, {AppPascalName}SeedDataProvider>();
|
|
1326
|
-
```
|
|
1327
|
-
|
|
1328
|
-
---
|
|
1329
|
-
|
|
1330
|
-
## 7. Multi-Module Handling
|
|
1331
|
-
|
|
1332
|
-
When processing multiple modules in the same business-analyse-develop run:
|
|
1333
|
-
|
|
1334
|
-
### Module 1 (first): Creates everything from scratch
|
|
1335
|
-
|
|
1336
|
-
0. `NavigationApplicationSeedData.cs` (**application-level**, once per app — FIRST FILE, provides ApplicationId)
|
|
1337
|
-
1. `ApplicationRolesSeedData.cs` (application-level, once per app — references NavigationApplicationSeedData.ApplicationId)
|
|
1338
|
-
2. `{Module1}NavigationSeedData.cs` (module + sections + resources + all translations)
|
|
1339
|
-
3. `{Module1}PermissionsSeedData.cs`
|
|
1340
|
-
4. `{Module1}RolesSeedData.cs`
|
|
1341
|
-
5. `{AppPascalName}SeedDataProvider.cs` (new, with 4 methods — including section/resource seeding)
|
|
1342
|
-
6. DI registration (new)
|
|
1343
|
-
|
|
1344
|
-
### Module 2+ (subsequent): Append to existing provider
|
|
1345
|
-
|
|
1346
|
-
0. `NavigationApplicationSeedData.cs` (already exists — skip)
|
|
1347
|
-
1. `ApplicationRolesSeedData.cs` (already exists — skip)
|
|
1348
|
-
2. `{Module2}NavigationSeedData.cs` (new file — include sections + resources if defined in feature.json)
|
|
1349
|
-
3. `{Module2}PermissionsSeedData.cs` (new file)
|
|
1350
|
-
4. `{Module2}RolesSeedData.cs` (new file)
|
|
1351
|
-
5. `{AppPascalName}SeedDataProvider.cs` (**modify** — add using, add entries in Navigation/Permissions/RolePermissions methods, **including section/resource seeding for the new module**)
|
|
1352
|
-
6. DI registration (already exists — skip)
|
|
1353
|
-
|
|
1354
|
-
**Detection:** Check if `{AppPascalName}SeedDataProvider.cs` exists. If yes, READ it and ADD the new module's entries to the appropriate methods (Navigation, Permissions, RolePermissions). Do NOT modify SeedRolesAsync() or the Application creation in SeedNavigationAsync().
|
|
1355
|
-
|
|
1356
|
-
### Section/Resource Conditionality
|
|
1357
|
-
|
|
1358
|
-
Sections and resources are **optional per module**. When processing a module's feature.json:
|
|
1359
|
-
|
|
1360
|
-
| Condition | Action |
|
|
1361
|
-
|-----------|--------|
|
|
1362
|
-
| `seedDataCore.navigationSections` absent or empty | Skip `GetSectionEntries()` / `GetSectionTranslationEntries()` / section seeding in provider |
|
|
1363
|
-
| `seedDataCore.navigationResources` absent or empty | Skip `GetResourceEntries()` / resource seeding in provider |
|
|
1364
|
-
| Both present | Generate all section + resource methods and provider code |
|
|
1365
|
-
|
|
1366
|
-
---
|
|
1367
|
-
|
|
1368
|
-
## 8. Verification Checklist
|
|
1369
|
-
|
|
1370
|
-
Before marking the task as completed, verify ALL:
|
|
1371
|
-
|
|
1372
|
-
**Application-Level (FIRST — before modules):**
|
|
1373
|
-
- [ ] `NavigationApplicationSeedData.cs` created (once per application, at `Infrastructure/Persistence/Seeding/Data/`)
|
|
1374
|
-
- [ ] Application GUID is random (`Guid.NewGuid()`) — FK resolution is by Code lookup, not fixed ID
|
|
1375
|
-
- [ ] GetApplicationEntry() takes no parameters, includes `IsOpen = false` and `IsPersonal = false` (set `IsPersonal = true` only for myspace-scoped apps; set `IsOpen = true` only for public/system apps that should bypass permission checks). v3.46+ : `ApplicationZone` enum is removed — do NOT add `Zone = ...`
|
|
1376
|
-
- [ ] Application translations created (4 languages: fr, en, it, de, EntityType = Application), using `app.Id` (actual DB ID) for EntityId
|
|
1377
|
-
- [ ] `IClientSeedDataProvider.SeedNavigationAsync()` uses `NavigationApplicationSeedData` (NO hardcoded `{appLabel_en}` / `{appIcon}` placeholders)
|
|
1378
|
-
- [ ] `ApplicationRolesSeedData.ApplicationId` references `NavigationApplicationSeedData.ApplicationId` (DTO only — provider code resolves from DB by Code)
|
|
1379
|
-
|
|
1380
|
-
**Module-Level:**
|
|
1381
|
-
- [ ] Random GUIDs via `Guid.NewGuid()` (no deterministic/sequential/fixed values)
|
|
1382
|
-
- [ ] 4 languages for each navigation entity (fr, en, it, de)
|
|
1383
|
-
- [ ] `ApplicationRolesSeedData.cs` created (once per application)
|
|
1384
|
-
- [ ] 4 application roles defined: Admin, Manager, Contributor, Viewer
|
|
1385
|
-
- [ ] Each role has a valid `Code` value ("admin", "manager", "contributor", "viewer")
|
|
1386
|
-
- [ ] `Permissions.cs` constants match seed data paths
|
|
1387
|
-
- [ ] MCP `generate_permissions` called (or fallback used)
|
|
1388
|
-
- [ ] Role-permission mappings assigned (Admin, Manager, Contributor, Viewer)
|
|
1389
|
-
- [ ] RolePermission mappings use Code-based lookup (no `DeterministicGuid("role:admin")` or `GenerateRoleGuid()`)
|
|
1390
|
-
- [ ] SeedRolesAsync checks existence by Code (SmartStack core may pre-seed system roles)
|
|
1391
|
-
- [ ] `IClientSeedDataProvider` generated with 4 methods (Navigation, Roles, Permissions, RolePermissions)
|
|
1392
|
-
- [ ] Execution order: Navigation (application → modules → sections → resources) → Roles → Permissions → RolePermissions
|
|
1393
|
-
- [ ] Each Seed method is idempotent (checks existence before inserting)
|
|
1394
|
-
- [ ] Factory methods used throughout (no `new Entity()`)
|
|
1395
|
-
- [ ] `SaveChangesAsync` called per group (Navigation → Roles → Permissions → RolePermissions)
|
|
1396
|
-
- [ ] DI registration added: `services.AddScoped<IClientSeedDataProvider, ...>()`
|
|
1397
|
-
- [ ] NavigationSections seeded (if `seedDataCore.navigationSections` present in feature.json)
|
|
1398
|
-
- [ ] NavigationResources seeded (if `seedDataCore.navigationResources` present in feature.json)
|
|
1399
|
-
- [ ] Section/Resource translations created (4 languages each, EntityType = Section/Resource)
|
|
1400
|
-
- [ ] `dotnet build` passes after generation
|
|
1401
|
-
- [ ] NO `Enum.Parse<PermissionAction>` usage anywhere in seeding code (use typed enum directly)
|
|
1402
|
-
- [ ] ALL PermissionAction values are from the valid enum: Access, Read, Create, Update, Delete, Export, Import, Approve, Reject, Assign, Execute
|
|
1403
|
-
|
|
1404
|
-
**Seed Data Integrity (run AFTER `dotnet build`):**
|
|
1405
|
-
- [ ] Application startup test: `dotnet run --urls http://localhost:0 --environment Development` exits without seed data exceptions
|
|
1406
|
-
- [ ] Verify `nav_Applications` has entry for `{appCode}` (query or startup log)
|
|
1407
|
-
- [ ] Verify `nav_Modules` has entries for each module (count matches feature.json modules)
|
|
1408
|
-
- [ ] Verify `auth_Roles` has 4 application-scoped roles (admin, manager, contributor, viewer)
|
|
1409
|
-
- [ ] Verify `auth_Permissions` has entries for each module (wildcard + CRUD)
|
|
1410
|
-
|
|
1411
|
-
**If ANY check fails, the task status = 'failed'.**
|
|
1412
|
-
|
|
1413
|
-
---
|
|
1414
|
-
|
|
1415
|
-
## 9. Business Seed Data (DevDataSeeder) — TenantId Rules
|
|
1416
|
-
|
|
1417
|
-
> **Applies to:** Seed data for business entities (reference types, categories, statuses).
|
|
1418
|
-
> **NOT the same as** core seed data above (navigation, permissions, roles).
|
|
1419
|
-
|
|
1420
|
-
### Rules
|
|
1421
|
-
|
|
1422
|
-
| Rule | Description |
|
|
1423
|
-
|------|-------------|
|
|
1424
|
-
| TenantId required | All business seed entities must set `TenantId` |
|
|
1425
|
-
| Deterministic TenantId | Use `SeedConstants.DefaultTenantId` (do not inline GUID) |
|
|
1426
|
-
| DevDataSeeder pattern | Implement `IDevDataSeeder` with `SeedAsync()` method |
|
|
1427
|
-
| Idempotency | Each seeder MUST check `AnyAsync()` before inserting |
|
|
1428
|
-
| Order | DevDataSeeder `Order >= 200` (after core seed data at Order 100) |
|
|
1429
|
-
|
|
1430
|
-
### Template (Reference Types)
|
|
1431
|
-
|
|
1432
|
-
```csharp
|
|
1433
|
-
public class {Module}DevDataSeeder : IDevDataSeeder
|
|
1434
|
-
{
|
|
1435
|
-
public int Order => 200; // After core seed data (Order 100)
|
|
1436
|
-
|
|
1437
|
-
public async Task SeedAsync(ExtensionsDbContext context, CancellationToken ct)
|
|
1438
|
-
{
|
|
1439
|
-
if (await context.Set<{EntityType}>().AnyAsync(ct)) return;
|
|
1440
|
-
|
|
1441
|
-
var items = new[]
|
|
1442
|
-
{
|
|
1443
|
-
new {EntityType}
|
|
1444
|
-
{
|
|
1445
|
-
Id = Guid.NewGuid(),
|
|
1446
|
-
Code = "{code}",
|
|
1447
|
-
Name = "{name}",
|
|
1448
|
-
TenantId = SeedConstants.DefaultTenantId, // Required for multi-tenant isolation
|
|
1449
|
-
IsActive = true
|
|
1450
|
-
}
|
|
1451
|
-
};
|
|
1452
|
-
|
|
1453
|
-
context.Set<{EntityType}>().AddRange(items);
|
|
1454
|
-
await context.SaveChangesAsync(ct);
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
// No deterministic GUID generation — all IDs are random via Guid.NewGuid()
|
|
1458
|
-
}
|
|
1459
|
-
```
|
|
1460
|
-
|
|
1461
|
-
### Anti-patterns
|
|
1462
|
-
|
|
1463
|
-
- Seeding business entities without `TenantId`
|
|
1464
|
-
- Using `Guid.NewGuid()` for TenantId
|
|
1465
|
-
- Omitting idempotency check (`AnyAsync`)
|
|
1466
|
-
- Hardcoding TenantId inline (use `SeedConstants.DefaultTenantId`)
|
|
1467
|
-
|
|
1468
|
-
### CROSS-SCHEMA FK WARNING
|
|
1469
|
-
|
|
1470
|
-
> `SeedConstants.DefaultTenantId` MUST reference a tenant that EXISTS in `core.tenant_Tenants`.
|
|
1471
|
-
> The SmartStack platform seeds a default tenant during `InitializeSmartStackAsync()`.
|
|
1472
|
-
> If you use a custom GUID, ensure it is created BEFORE `DevDataSeeder` runs (Order >= 200).
|
|
1473
|
-
>
|
|
1474
|
-
> **Pipeline validation:**
|
|
1475
|
-
> - business-analyse-develop POST-CHECK warns if GUID not found in project config
|
|
1476
|
-
> - validate-feature step-05 verifies FK exists in real database via SQL query
|
|
1477
|
-
|
|
1478
|
-
---
|
|
1479
|
-
|
|
1480
|
-
## DataExportEndpoint Seed Data Pattern
|
|
1481
|
-
|
|
1482
|
-
When adding a new export endpoint, add seed data in `DataExportEndpointConfiguration.cs`:
|
|
1483
|
-
|
|
1484
|
-
```csharp
|
|
1485
|
-
builder.HasData(new {
|
|
1486
|
-
Id = new Guid("{random-guid}"),
|
|
1487
|
-
NavigationApplicationId = NavigationApplicationSeedData.{App}AppId,
|
|
1488
|
-
NavigationModuleId = NavigationModuleSeedData.{Module}ModuleId,
|
|
1489
|
-
Code = "{entity-code}",
|
|
1490
|
-
Name = "{Entity} Export",
|
|
1491
|
-
Description = "Export {entity} data with metadata",
|
|
1492
|
-
RouteTemplate = "/api/v1/export/{entity-code}",
|
|
1493
|
-
RequiredPermission = "{app}.{module}.export",
|
|
1494
|
-
EntityType = "{Entity}",
|
|
1495
|
-
IsActive = true,
|
|
1496
|
-
DefaultRateLimitPerMinute = 60,
|
|
1497
|
-
DefaultMaxPageSize = 1000,
|
|
1498
|
-
CreatedAt = seedDate
|
|
1499
|
-
});
|
|
1500
|
-
```
|
|
1501
|
-
|
|
1502
|
-
Requires matching controller in `Controllers/DataExport/v1/Export{Entity}Controller.cs`.
|