@polymorphism-tech/morph-spec 4.12.0 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/README.md +21 -29
  2. package/bin/morph-spec.js +41 -24
  3. package/bin/task-manager.js +962 -1341
  4. package/bin/validate.js +1 -1
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +10 -11
  7. package/docs/QUICKSTART.md +15 -15
  8. package/framework/CLAUDE.md +5 -2
  9. package/framework/agents/README.md +3 -4
  10. package/framework/agents/ai-agents/ai-system-architect.md +6 -10
  11. package/framework/agents/architecture/seo-growth-hacker.md +166 -326
  12. package/framework/agents/architecture/standards-architect.md +21 -31
  13. package/framework/agents/backend/dotnet-senior.md +160 -86
  14. package/framework/agents/backend/ef-modeler.md +2 -6
  15. package/framework/agents/backend/hangfire-orchestrator.md +8 -9
  16. package/framework/agents/backend/ms-agent-expert.md +1 -1
  17. package/framework/agents/frontend/nextjs-expert.md +198 -133
  18. package/framework/agents/frontend/ui-ux-designer.md +226 -267
  19. package/framework/agents/infrastructure/infra-architect.md +191 -27
  20. package/framework/agents/integrations/clerk-auth.md +19 -26
  21. package/framework/agents/integrations/hangfire-integration.md +1 -4
  22. package/framework/agents.json +215 -1453
  23. package/framework/commands/morph-apply.md +4 -4
  24. package/framework/commands/morph-preflight.md +4 -26
  25. package/framework/commands/morph-proposal.md +19 -19
  26. package/framework/commands/morph-status.md +2 -2
  27. package/framework/commands/morph-troubleshoot.md +6 -13
  28. package/framework/hooks/README.md +1 -6
  29. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +4 -6
  30. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
  31. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
  32. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
  33. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
  34. package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
  35. package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
  36. package/framework/hooks/claude-code/statusline.py +4 -5
  37. package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
  38. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
  39. package/framework/hooks/shared/compact-restore.js +28 -5
  40. package/framework/hooks/shared/phase-utils.js +4 -8
  41. package/framework/hooks/shared/state-reader.js +34 -3
  42. package/framework/phases.json +7 -45
  43. package/framework/rules/ai-agents-standards.md +15 -0
  44. package/framework/rules/asaas-standards.md +13 -0
  45. package/framework/rules/clerk-standards.md +13 -0
  46. package/framework/rules/csharp-standards.md +8 -4
  47. package/framework/rules/data-standards.md +18 -0
  48. package/framework/rules/dotnet-templates.md +87 -0
  49. package/framework/rules/frontend-standards.md +13 -13
  50. package/framework/rules/hangfire-standards.md +13 -0
  51. package/framework/rules/infrastructure-standards.md +27 -16
  52. package/framework/rules/morph-workflow.md +73 -13
  53. package/framework/rules/nextjs-standards.md +1 -0
  54. package/framework/rules/nextjs-templates.md +40 -0
  55. package/framework/rules/resend-standards.md +12 -0
  56. package/framework/rules/supabase-standards.md +29 -0
  57. package/framework/skills/README.md +6 -8
  58. package/framework/skills/level-0-meta/mcp-registry.json +21 -99
  59. package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
  60. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
  61. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  62. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
  63. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
  64. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
  65. package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
  66. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
  67. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
  68. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
  69. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
  70. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
  71. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
  72. package/framework/skills/level-1-workflows/README.md +1 -1
  73. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
  74. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +58 -124
  75. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
  76. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
  77. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
  78. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
  79. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
  80. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
  81. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
  82. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
  83. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -2
  84. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
  85. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +57 -77
  86. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  87. package/framework/squad-templates/backend-only.json +6 -6
  88. package/framework/squad-templates/frontend-only.json +17 -8
  89. package/framework/squad-templates/full-stack.json +29 -24
  90. package/framework/standards/STANDARDS.json +1021 -2369
  91. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
  92. package/framework/standards/backend/dotnet/result-pattern.md +213 -0
  93. package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
  94. package/framework/standards/backend/dotnet/scrutor.md +158 -0
  95. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
  96. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
  97. package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
  98. package/framework/standards/integration/mcp/mcp-tools.md +91 -77
  99. package/framework/templates/IDE-SNIPPETS.md +2 -6
  100. package/framework/templates/README.md +709 -814
  101. package/framework/templates/REGISTRY.json +223 -762
  102. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
  103. package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
  104. package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
  105. package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
  106. package/framework/templates/code/dotnet/backend/repository.cs +148 -141
  107. package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
  108. package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
  109. package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
  110. package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
  111. package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
  112. package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
  113. package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
  114. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
  115. package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
  116. package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
  117. package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
  118. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
  119. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
  120. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
  121. package/framework/templates/code/dotnet/jobs/job.cs +21 -17
  122. package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
  123. package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
  124. package/framework/templates/code/dotnet/test.cs +192 -106
  125. package/framework/templates/context/ARCHITECTURE.md +89 -0
  126. package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
  127. package/framework/templates/context/CONTEXT.md +180 -181
  128. package/framework/templates/context/design-system.md +1 -5
  129. package/framework/templates/docs/onboarding.md +2 -3
  130. package/framework/templates/docs/proposal.md +171 -182
  131. package/framework/templates/docs/spec.md +1 -3
  132. package/framework/templates/docs/ui-components.md +0 -72
  133. package/framework/templates/examples/design-system-examples.md +4 -4
  134. package/framework/templates/feature/decisions.md +0 -66
  135. package/framework/templates/feature/recap.md +1 -2
  136. package/framework/templates/infrastructure/github/README.md +56 -593
  137. package/framework/templates/integrations/clerk-config.cs +0 -41
  138. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  139. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
  140. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
  141. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
  142. package/framework/templates/project/validate.js +2 -4
  143. package/framework/templates/ui/design-system.css +1 -1
  144. package/framework/workflows/README.md +8 -8
  145. package/framework/workflows/configs/fast-track.json +51 -0
  146. package/framework/workflows/configs/full.json +68 -0
  147. package/framework/workflows/configs/standard.json +7 -3
  148. package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
  149. package/framework/workflows/docs/enforcement-pipeline.md +18 -19
  150. package/framework/workflows/docs/full-morph.md +69 -76
  151. package/framework/workflows/docs/standard.md +49 -44
  152. package/framework/workflows/docs/ui-refresh.md +1 -1
  153. package/package.json +3 -3
  154. package/src/commands/agents/dispatch-agents.js +55 -116
  155. package/src/commands/context/context-refresh.js +79 -0
  156. package/src/commands/phase/phase-reset.js +1 -1
  157. package/src/commands/project/doctor.js +10 -32
  158. package/src/commands/project/init.js +12 -0
  159. package/src/commands/project/status.js +6 -12
  160. package/src/commands/scaffold/scaffold.js +131 -0
  161. package/src/commands/scope/escalate.js +1 -1
  162. package/src/commands/state/advance-phase.js +15 -29
  163. package/src/commands/state/state.js +20 -5
  164. package/src/commands/tasks/task.js +0 -30
  165. package/src/commands/validation/validate-feature.js +3 -10
  166. package/src/core/paths/output-schema.js +12 -13
  167. package/src/core/state/phase-state-machine.js +211 -217
  168. package/src/core/state/state-manager.js +9 -9
  169. package/src/lib/agents/agents-manager.js +2 -2
  170. package/src/lib/agents/output-collector.js +1 -2
  171. package/src/lib/detectors/design-system-detector.js +4 -4
  172. package/src/lib/detectors/index.js +1 -11
  173. package/src/lib/generators/architecture-scanner.js +640 -0
  174. package/src/lib/generators/context-generator.js +3 -3
  175. package/src/lib/generators/design-system-generator.js +508 -587
  176. package/src/lib/generators/index.js +12 -10
  177. package/src/lib/generators/metadata-extractor.js +386 -387
  178. package/src/lib/generators/recap-generator.js +4 -4
  179. package/src/lib/generators/scaffold-generator.js +317 -0
  180. package/src/lib/generators/settings-generator.js +0 -1
  181. package/src/lib/phase-chain/phase-validator.js +64 -42
  182. package/src/lib/stack/stack-profile.js +2 -2
  183. package/src/lib/standards/digest-builder.js +72 -285
  184. package/src/lib/tasks/task-parser.js +11 -5
  185. package/src/lib/validators/architecture/architecture-validator.js +259 -387
  186. package/src/lib/validators/content/content-validator.js +287 -287
  187. package/src/lib/validators/css/css-validator.js +340 -352
  188. package/src/lib/validators/packages/package-validator.js +347 -360
  189. package/src/lib/validators/shared/issue-counter.js +14 -18
  190. package/src/lib/validators/validation-runner.js +3 -19
  191. package/src/scripts/setup-infra.js +1 -1
  192. package/src/utils/agents-installer.js +24 -3
  193. package/src/utils/file-copier.js +1 -0
  194. package/src/utils/hooks-installer.js +11 -19
  195. package/src/utils/skills-installer.js +178 -178
  196. package/framework/agents/architecture/prompt-engineer.md +0 -195
  197. package/framework/agents/backend/api-designer.md +0 -106
  198. package/framework/agents/frontend/blazor-builder.md +0 -229
  199. package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
  200. package/framework/agents/infrastructure/azure-architect.md +0 -150
  201. package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
  202. package/framework/agents/infrastructure/bicep-architect.md +0 -132
  203. package/framework/agents/infrastructure/container-specialist.md +0 -137
  204. package/framework/agents/infrastructure/devops-engineer.md +0 -126
  205. package/framework/agents/integrations/azure-identity.md +0 -148
  206. package/framework/agents/quality/code-analyzer.md +0 -239
  207. package/framework/agents/quality/testing-specialist.md +0 -130
  208. package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
  209. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
  210. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
  211. package/framework/index/troubleshooting-index.json +0 -184
  212. package/framework/rules/testing-standards.md +0 -14
  213. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
  214. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
  215. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
  216. package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
  217. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
  218. package/framework/standards/ai-agents/blazor-ui.md +0 -364
  219. package/framework/standards/architecture/ddd/aggregates.md +0 -120
  220. package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  221. package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  222. package/framework/standards/architecture/ddd/entities.md +0 -99
  223. package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  224. package/framework/standards/architecture/ddd/value-objects.md +0 -124
  225. package/framework/standards/backend/api/minimal-api.md +0 -494
  226. package/framework/standards/backend/api/rest.md +0 -492
  227. package/framework/standards/backend/authentication/passkeys.md +0 -428
  228. package/framework/standards/backend/database/ef-core.md +0 -199
  229. package/framework/standards/backend/database/migrations.md +0 -393
  230. package/framework/standards/backend/database/repository-patterns.md +0 -528
  231. package/framework/standards/backend/dotnet/async.md +0 -366
  232. package/framework/standards/backend/dotnet/core.md +0 -117
  233. package/framework/standards/backend/dotnet/di.md +0 -439
  234. package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  235. package/framework/standards/context/analytics.md +0 -96
  236. package/framework/standards/context/bundles.md +0 -110
  237. package/framework/standards/context/priming.md +0 -78
  238. package/framework/standards/core/architecture.md +0 -185
  239. package/framework/standards/core/coding.md +0 -214
  240. package/framework/standards/core/git-branching-strategy.md +0 -403
  241. package/framework/standards/core/git.md +0 -185
  242. package/framework/standards/core/testing.md +0 -295
  243. package/framework/standards/data/nosql/blob-storage.md +0 -102
  244. package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  245. package/framework/standards/frontend/blazor/design-checklist.md +0 -222
  246. package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  247. package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  248. package/framework/standards/frontend/blazor/html-conversion.md +0 -184
  249. package/framework/standards/frontend/blazor/lifecycle.md +0 -195
  250. package/framework/standards/frontend/blazor/pitfalls.md +0 -198
  251. package/framework/standards/frontend/blazor/state.md +0 -191
  252. package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -266
  253. package/framework/standards/frontend/design-system/design-trends.md +0 -171
  254. package/framework/standards/infrastructure/azure/azure.md +0 -624
  255. package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  256. package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  257. package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  258. package/framework/standards/infrastructure/azure/services/functions.md +0 -486
  259. package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  260. package/framework/standards/infrastructure/azure/services/storage.md +0 -407
  261. package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
  262. package/framework/standards/integration/api/graphql.md +0 -91
  263. package/framework/standards/integration/api/grpc.md +0 -114
  264. package/framework/standards/integration/api/rest-design.md +0 -95
  265. package/framework/standards/integration/event-driven/cqrs.md +0 -101
  266. package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  267. package/framework/standards/integration/event-driven/service-bus.md +0 -95
  268. package/framework/standards/observability/logging.md +0 -131
  269. package/framework/standards/observability/metrics.md +0 -121
  270. package/framework/standards/observability/monitoring.md +0 -114
  271. package/framework/standards/observability/tracing.md +0 -132
  272. package/framework/standards/workflows/parallel-execution.md +0 -112
  273. package/framework/standards/workflows/thread-management.md +0 -113
  274. package/framework/templates/code/dotnet/backend/service.cs +0 -139
  275. package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  276. package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  277. package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  278. package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  279. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  280. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  281. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  282. package/framework/templates/code/dotnet/frontend/component.razor +0 -239
  283. package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  284. package/framework/templates/infrastructure/azure/README.md +0 -286
  285. package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  286. package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  287. package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  288. package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  289. package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  290. package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  291. package/framework/templates/infrastructure/azure/deploy.sh +0 -208
  292. package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  293. package/framework/templates/infrastructure/azure/main.bicep +0 -189
  294. package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  295. package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  296. package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  297. package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  298. package/framework/templates/infrastructure/azure/storage.bicep +0 -106
  299. package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  300. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  301. package/framework/templates/integrations/azure-identity-config.cs +0 -288
  302. package/framework/templates/project-structure/dotnet-ddd.md +0 -70
  303. package/framework/templates/saas/subscription.cs +0 -347
  304. package/framework/templates/saas/tenant.cs +0 -338
  305. package/framework/templates/ui/FluentDesignTheme.cs +0 -149
  306. package/framework/templates/ui/MudTheme.cs +0 -281
  307. package/framework/workflows/configs/nodejs-cli.json +0 -40
  308. package/src/commands/standards/context-budget.js +0 -89
  309. package/src/lib/standards/index.js +0 -7
  310. package/src/lib/standards/standards-context-injector.js +0 -302
  311. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
  312. package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
  313. package/src/lib/validators/blazor/blazor-validator.js +0 -369
  314. package/src/lib/validators/blazor/index.js +0 -9
@@ -1,407 +0,0 @@
1
- # Azure Storage Services Standard
2
-
3
- > **Scope:** blazor-azure
4
- > **Layer:** 2 (on keyword)
5
- > **Keywords:** azure storage, blob, queue, table, file storage
6
- > **Load When:** azure storage keywords detected
7
-
8
- Azure Storage services patterns for Blob, Queue, Table, and File storage.
9
-
10
- ---
11
-
12
- ## Overview
13
-
14
- Azure Storage provides:
15
- - **Blob Storage**: Object storage for unstructured data (files, images, videos)
16
- - **Queue Storage**: Message queuing for async processing
17
- - **Table Storage**: NoSQL key-value store
18
- - **File Storage**: SMB file shares
19
-
20
- **Stack:** .NET 10 + Blazor Server
21
-
22
- ---
23
-
24
- ## Core Principles
25
-
26
- 1. **Managed Identity**: Use Managed Identity over connection strings
27
- 2. **SAS Tokens**: Use SAS for temporary access delegation
28
- 3. **Retry Policies**: Configure exponential backoff for transient failures
29
- 4. **Lifecycle Management**: Auto-delete old blobs with lifecycle policies
30
- 5. **Cost Optimization**: Use appropriate storage tiers (Hot/Cool/Archive)
31
-
32
- ---
33
-
34
- ## Installation
35
-
36
- ```bash
37
- dotnet add package Azure.Storage.Blobs
38
- dotnet add package Azure.Storage.Queues
39
- dotnet add package Azure.Identity
40
- ```
41
-
42
- ---
43
-
44
- ## Blob Storage
45
-
46
- ### DI Configuration
47
-
48
- ```csharp
49
- // Program.cs
50
- using Azure.Identity;
51
- using Azure.Storage.Blobs;
52
-
53
- builder.Services.AddSingleton(sp =>
54
- {
55
- var blobServiceUri = new Uri(builder.Configuration["AzureStorage:BlobServiceUri"]!);
56
- return new BlobServiceClient(blobServiceUri, new DefaultAzureCredential());
57
- });
58
- ```
59
-
60
- ### Upload Blob
61
-
62
- ```csharp
63
- public class FileUploadService
64
- {
65
- private readonly BlobServiceClient _blobServiceClient;
66
-
67
- public FileUploadService(BlobServiceClient blobServiceClient)
68
- {
69
- _blobServiceClient = blobServiceClient;
70
- }
71
-
72
- public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string containerName)
73
- {
74
- var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
75
- await containerClient.CreateIfNotExistsAsync();
76
-
77
- var blobClient = containerClient.GetBlobClient(fileName);
78
-
79
- await blobClient.UploadAsync(fileStream, overwrite: true);
80
-
81
- return blobClient.Uri.ToString();
82
- }
83
- }
84
- ```
85
-
86
- ### Download Blob
87
-
88
- ```csharp
89
- public async Task<Stream> DownloadFileAsync(string fileName, string containerName)
90
- {
91
- var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
92
- var blobClient = containerClient.GetBlobClient(fileName);
93
-
94
- var response = await blobClient.DownloadAsync();
95
- return response.Value.Content;
96
- }
97
- ```
98
-
99
- ### Generate SAS Token
100
-
101
- ```csharp
102
- using Azure.Storage.Sas;
103
-
104
- public string GenerateSasUri(string containerName, string blobName, TimeSpan validity)
105
- {
106
- var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
107
- var blobClient = containerClient.GetBlobClient(blobName);
108
-
109
- var sasBuilder = new BlobSasBuilder
110
- {
111
- BlobContainerName = containerName,
112
- BlobName = blobName,
113
- Resource = "b", // Blob
114
- StartsOn = DateTimeOffset.UtcNow,
115
- ExpiresOn = DateTimeOffset.UtcNow.Add(validity)
116
- };
117
-
118
- sasBuilder.SetPermissions(BlobSasPermissions.Read);
119
-
120
- var sasUri = blobClient.GenerateSasUri(sasBuilder);
121
- return sasUri.ToString();
122
- }
123
- ```
124
-
125
- ---
126
-
127
- ## Queue Storage
128
-
129
- ### DI Configuration
130
-
131
- ```csharp
132
- // Program.cs
133
- builder.Services.AddSingleton(sp =>
134
- {
135
- var queueServiceUri = new Uri(builder.Configuration["AzureStorage:QueueServiceUri"]!);
136
- return new QueueServiceClient(queueServiceUri, new DefaultAzureCredential());
137
- });
138
- ```
139
-
140
- ### Send Message
141
-
142
- ```csharp
143
- public class QueueService
144
- {
145
- private readonly QueueServiceClient _queueServiceClient;
146
-
147
- public QueueService(QueueServiceClient queueServiceClient)
148
- {
149
- _queueServiceClient = queueServiceClient;
150
- }
151
-
152
- public async Task SendMessageAsync(string queueName, string message)
153
- {
154
- var queueClient = _queueServiceClient.GetQueueClient(queueName);
155
- await queueClient.CreateIfNotExistsAsync();
156
-
157
- await queueClient.SendMessageAsync(message);
158
- }
159
-
160
- public async Task SendMessageWithDelayAsync(string queueName, string message, TimeSpan delay)
161
- {
162
- var queueClient = _queueServiceClient.GetQueueClient(queueName);
163
- await queueClient.CreateIfNotExistsAsync();
164
-
165
- await queueClient.SendMessageAsync(message, visibilityTimeout: delay);
166
- }
167
- }
168
- ```
169
-
170
- ### Process Messages
171
-
172
- ```csharp
173
- using Azure.Storage.Queues.Models;
174
-
175
- public async Task ProcessMessagesAsync(string queueName, CancellationToken cancellationToken)
176
- {
177
- var queueClient = _queueServiceClient.GetQueueClient(queueName);
178
-
179
- while (!cancellationToken.IsCancellationRequested)
180
- {
181
- QueueMessage[] messages = await queueClient.ReceiveMessagesAsync(maxMessages: 32);
182
-
183
- foreach (var message in messages)
184
- {
185
- try
186
- {
187
- // Process message
188
- await ProcessMessageAsync(message.MessageText);
189
-
190
- // Delete message after successful processing
191
- await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
192
- }
193
- catch (Exception ex)
194
- {
195
- // Log error, message will become visible again after timeout
196
- _logger.LogError(ex, "Failed to process message {MessageId}", message.MessageId);
197
- }
198
- }
199
-
200
- if (messages.Length == 0)
201
- {
202
- await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
203
- }
204
- }
205
- }
206
- ```
207
-
208
- ---
209
-
210
- ## Table Storage
211
-
212
- ### DI Configuration
213
-
214
- ```csharp
215
- dotnet add package Azure.Data.Tables
216
-
217
- // Program.cs
218
- builder.Services.AddSingleton(sp =>
219
- {
220
- var tableServiceUri = new Uri(builder.Configuration["AzureStorage:TableServiceUri"]!);
221
- return new TableServiceClient(tableServiceUri, new DefaultAzureCredential());
222
- });
223
- ```
224
-
225
- ### Entity Model
226
-
227
- ```csharp
228
- using Azure;
229
- using Azure.Data.Tables;
230
-
231
- public class ProductEntity : ITableEntity
232
- {
233
- public string PartitionKey { get; set; } = default!; // Category
234
- public string RowKey { get; set; } = default!; // ProductId
235
- public DateTimeOffset? Timestamp { get; set; }
236
- public ETag ETag { get; set; }
237
-
238
- public string Name { get; set; } = string.Empty;
239
- public decimal Price { get; set; }
240
- public int Stock { get; set; }
241
- }
242
- ```
243
-
244
- ### CRUD Operations
245
-
246
- ```csharp
247
- public class ProductTableService
248
- {
249
- private readonly TableClient _tableClient;
250
-
251
- public ProductTableService(TableServiceClient tableServiceClient)
252
- {
253
- _tableClient = tableServiceClient.GetTableClient("products");
254
- _tableClient.CreateIfNotExists();
255
- }
256
-
257
- public async Task AddProductAsync(ProductEntity product)
258
- {
259
- await _tableClient.AddEntityAsync(product);
260
- }
261
-
262
- public async Task<ProductEntity?> GetProductAsync(string category, string productId)
263
- {
264
- try
265
- {
266
- return await _tableClient.GetEntityAsync<ProductEntity>(category, productId);
267
- }
268
- catch (RequestFailedException ex) when (ex.Status == 404)
269
- {
270
- return null;
271
- }
272
- }
273
-
274
- public async Task<List<ProductEntity>> QueryProductsAsync(string category)
275
- {
276
- var query = _tableClient.QueryAsync<ProductEntity>(p => p.PartitionKey == category);
277
-
278
- var results = new List<ProductEntity>();
279
- await foreach (var product in query)
280
- {
281
- results.Add(product);
282
- }
283
-
284
- return results;
285
- }
286
-
287
- public async Task UpdateProductAsync(ProductEntity product)
288
- {
289
- await _tableClient.UpdateEntityAsync(product, ETag.All, TableUpdateMode.Replace);
290
- }
291
-
292
- public async Task DeleteProductAsync(string category, string productId)
293
- {
294
- await _tableClient.DeleteEntityAsync(category, productId);
295
- }
296
- }
297
- ```
298
-
299
- ---
300
-
301
- ## Best Practices
302
-
303
- ### Retry Policy
304
-
305
- ```csharp
306
- using Azure.Core;
307
-
308
- var options = new BlobClientOptions
309
- {
310
- Retry =
311
- {
312
- Mode = RetryMode.Exponential,
313
- MaxRetries = 3,
314
- Delay = TimeSpan.FromSeconds(2),
315
- MaxDelay = TimeSpan.FromSeconds(10)
316
- }
317
- };
318
-
319
- var blobServiceClient = new BlobServiceClient(blobServiceUri, credential, options);
320
- ```
321
-
322
- ### Blob Metadata
323
-
324
- ```csharp
325
- var metadata = new Dictionary<string, string>
326
- {
327
- { "uploadedBy", userId },
328
- { "fileType", "invoice" },
329
- { "department", "finance" }
330
- };
331
-
332
- await blobClient.UploadAsync(stream, metadata: metadata);
333
-
334
- // Retrieve metadata
335
- var properties = await blobClient.GetPropertiesAsync();
336
- var uploadedBy = properties.Value.Metadata["uploadedBy"];
337
- ```
338
-
339
- ### Lifecycle Management
340
-
341
- ```json
342
- // Configure in Azure Portal or via Bicep
343
- {
344
- "rules": [
345
- {
346
- "name": "deleteOldBackups",
347
- "enabled": true,
348
- "type": "Lifecycle",
349
- "definition": {
350
- "filters": {
351
- "blobTypes": ["blockBlob"],
352
- "prefixMatch": ["backups/"]
353
- },
354
- "actions": {
355
- "baseBlob": {
356
- "delete": {
357
- "daysAfterModificationGreaterThan": 30
358
- }
359
- }
360
- }
361
- }
362
- }
363
- ]
364
- }
365
- ```
366
-
367
- ---
368
-
369
- ## Bicep Configuration
370
-
371
- ```bicep
372
- resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
373
- name: storageAccountName
374
- location: location
375
- sku: {
376
- name: 'Standard_LRS'
377
- }
378
- kind: 'StorageV2'
379
- properties: {
380
- allowBlobPublicAccess: false
381
- minimumTlsVersion: 'TLS1_2'
382
- supportsHttpsTrafficOnly: true
383
- }
384
- }
385
-
386
- // Grant Container App Blob access
387
- resource blobRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
388
- scope: storageAccount
389
- name: guid(storageAccount.id, principalId, 'Storage Blob Data Contributor')
390
- properties: {
391
- roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')
392
- principalId: principalId
393
- }
394
- }
395
- ```
396
-
397
- ---
398
-
399
- ## References
400
-
401
- - [Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/)
402
- - [Azure Queue Storage](https://learn.microsoft.com/azure/storage/queues/)
403
- - [Azure Table Storage](https://learn.microsoft.com/azure/storage/tables/)
404
-
405
- ---
406
-
407
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,106 +0,0 @@
1
- # Vercel Deployment — Database Standard
2
-
3
- > **Scope:** nextjs-vercel
4
- > **Layer:** 1 (always-on for Vercel-deployed Next.js)
5
- > **Keywords:** vercel, neon, planetscale, serverless database, serverless postgres, deploy nextjs
6
- > **Load When:** deployment target is Vercel with Next.js stack
7
-
8
- ---
9
-
10
- ## Rule: Vercel Requires a Serverless Database
11
-
12
- **NEVER** use a traditional long-lived database connection pool (PostgreSQL TCP, MySQL TCP) with Vercel.
13
- Vercel functions are ephemeral and stateless — each invocation may spawn a fresh process.
14
- A persistent connection pool (e.g., EF Core + plain Npgsql TCP) will exhaust database connection limits within minutes under moderate load.
15
-
16
- **ALWAYS** use a **serverless-compatible** database when deploying to Vercel.
17
-
18
- ---
19
-
20
- ## Approved Serverless Databases
21
-
22
- | Provider | Type | Connection mode | Notes |
23
- |----------|------|-----------------|-------|
24
- | **Neon** | PostgreSQL (serverless) | HTTP (`@neondatabase/serverless`) or pooled TCP via PgBouncer | First choice for SQL |
25
- | **PlanetScale** | MySQL-compatible (serverless) | HTTP driver (`@planetscale/database`) | Good for MySQL ecosystems |
26
- | **Supabase** | PostgreSQL + PgBouncer | Pooled TCP (transaction mode) or REST | Full BaaS option |
27
- | **Turso** | SQLite (distributed) | HTTP (`@libsql/client`) | Lightweight, edge-friendly |
28
-
29
- ---
30
-
31
- ## Implementation: Neon (Recommended)
32
-
33
- ```ts
34
- // lib/db.ts
35
- import { neon } from '@neondatabase/serverless';
36
-
37
- const sql = neon(process.env.DATABASE_URL!);
38
- export default sql;
39
- ```
40
-
41
- ```ts
42
- // Example: API Route (app/api/items/route.ts)
43
- import sql from '@/lib/db';
44
-
45
- export async function GET() {
46
- const items = await sql`SELECT * FROM items LIMIT 50`;
47
- return Response.json(items);
48
- }
49
- ```
50
-
51
- ### Environment variable
52
- ```
53
- DATABASE_URL=postgresql://user:pass@ep-xxx.neon.tech/dbname?sslmode=require
54
- ```
55
-
56
- ---
57
-
58
- ## Implementation: Supabase + PgBouncer (Transaction Mode)
59
-
60
- Use the **port 6543** connection string (PgBouncer, transaction pooling):
61
-
62
- ```
63
- DATABASE_URL=postgresql://user:pass@db.xxx.supabase.co:6543/postgres?pgbouncer=true&connection_limit=1
64
- ```
65
-
66
- If using an ORM (Prisma/Drizzle), set `connection_limit=1` to avoid pool saturation.
67
-
68
- ---
69
-
70
- ## Anti-patterns — NEVER use with Vercel
71
-
72
- ```ts
73
- // WRONG: plain Npgsql/pg pool without serverless adapter
74
- import { Pool } from 'pg';
75
- const pool = new Pool({ connectionString: process.env.DATABASE_URL });
76
- // → Leaks connections on every cold start
77
-
78
- // WRONG: EF Core (dotnet) TCP pool behind a Vercel-deployed Next.js API route
79
- // → Not applicable (EF Core is .NET), but calling a .NET API that pools
80
- // connections is fine as long as the .NET side runs on a persistent server
81
- ```
82
-
83
- ---
84
-
85
- ## Decision Tree: Choose Your DB Tier
86
-
87
- ```
88
- Deploying to Vercel?
89
- └── YES → Use serverless DB
90
- ├── Need SQL + PostGIS/pgvector? → Neon
91
- ├── Need full BaaS (auth, storage, RLS)? → Supabase
92
- ├── MySQL ecosystem? → PlanetScale
93
- └── Edge-only, lightweight? → Turso
94
- └── NO (EasyPanel, Railway, Render, Azure Container Apps)
95
- └── Any PostgreSQL with connection pool is fine
96
- ```
97
-
98
- ---
99
-
100
- ## Validator Check (design phase)
101
-
102
- During `phase-design`, the standards agent must verify:
103
-
104
- - `config.deployment.target === 'vercel'` → enforce serverless DB selection
105
- - If `database.provider` is missing or is `postgresql-tcp`, flag as **BLOCKING** issue
106
- - Add to `decisions.md`: "Database must be serverless-compatible (Vercel constraint)"
@@ -1,91 +0,0 @@
1
- # Integration Standard: GraphQL
2
-
3
- ## When to Use GraphQL
4
- ✅ Client needs fine-grained field selection (mobile apps, different clients)
5
- ✅ Complex nested resource relationships (avoid N+1 with DataLoader)
6
- ✅ Real-time subscriptions alongside queries
7
- ❌ Simple CRUD APIs (REST is simpler)
8
- ❌ File upload as primary use case (use REST for uploads)
9
- ❌ When caching is critical (GraphQL caching is harder)
10
-
11
- ## Setup (Hot Chocolate)
12
- ```xml
13
- <PackageReference Include="HotChocolate.AspNetCore" Version="14.*" />
14
- <PackageReference Include="HotChocolate.Data.EntityFramework" Version="14.*" />
15
- ```
16
-
17
- ```csharp
18
- builder.Services
19
- .AddGraphQLServer()
20
- .AddQueryType<QueryType>()
21
- .AddMutationType<MutationType>()
22
- .AddSubscriptionType<SubscriptionType>()
23
- .AddProjections()
24
- .AddFiltering()
25
- .AddSorting()
26
- .AddAuthorization();
27
-
28
- app.MapGraphQL("/graphql");
29
- ```
30
-
31
- ## Query Type
32
- ```csharp
33
- [QueryType]
34
- public class QueryType
35
- {
36
- [UseProjection]
37
- [UseFiltering]
38
- [UseSorting]
39
- [UsePaging]
40
- public IQueryable<Order> GetOrders([Service] AppDbContext ctx) => ctx.Orders;
41
-
42
- public async Task<Order?> GetOrder(Guid id, [Service] AppDbContext ctx)
43
- => await ctx.Orders.FindAsync(id);
44
- }
45
- ```
46
-
47
- ## Mutation Type
48
- ```csharp
49
- [MutationType]
50
- public class MutationType
51
- {
52
- public async Task<CreateOrderPayload> CreateOrder(
53
- CreateOrderInput input,
54
- [Service] ISender sender)
55
- {
56
- var result = await sender.Send(new CreateOrderCommand(input.UserId, input.Items));
57
- return new CreateOrderPayload(result.OrderId);
58
- }
59
- }
60
-
61
- public record CreateOrderInput(Guid UserId, List<OrderItemInput> Items);
62
- public record CreateOrderPayload(Guid OrderId);
63
- ```
64
-
65
- ## DataLoader (N+1 Prevention)
66
- ```csharp
67
- public class UserDataLoader : BatchDataLoader<Guid, User>
68
- {
69
- protected override async Task<IReadOnlyDictionary<Guid, User>> LoadBatchAsync(
70
- IReadOnlyList<Guid> keys, CancellationToken ct)
71
- {
72
- return await _context.Users
73
- .Where(u => keys.Contains(u.Id))
74
- .ToDictionaryAsync(u => u.Id, ct);
75
- }
76
- }
77
-
78
- // Use in resolver
79
- public async Task<User?> GetUser([Parent] Order order, UserDataLoader loader)
80
- => await loader.LoadAsync(order.UserId);
81
- ```
82
-
83
- ## Security
84
- - Apply `[Authorize]` on mutations and sensitive queries
85
- - Disable introspection in production
86
- - Depth limiting: max 5 levels
87
- - Complexity limiting: max 1000 nodes per query
88
- ```csharp
89
- .AddMaxExecutionDepthRule(5)
90
- .ModifyRequestOptions(opts => opts.MaxAllowedRequestSize = 1_000_000)
91
- ```
@@ -1,114 +0,0 @@
1
- # Integration Standard: gRPC
2
-
3
- ## When to Use gRPC
4
- ✅ Internal service-to-service communication (high performance)
5
- ✅ Streaming (server-streaming for real-time data, client-streaming for uploads)
6
- ✅ Multi-language microservices (proto contracts shared across .NET, Go, Python)
7
- ❌ Browser-to-server (use gRPC-Web or REST instead)
8
- ❌ Debugging priority (binary format is harder to inspect than JSON)
9
-
10
- ## Setup
11
- ```xml
12
- <PackageReference Include="Grpc.AspNetCore" Version="2.*" />
13
- ```
14
-
15
- ```csharp
16
- // Program.cs
17
- builder.Services.AddGrpc(opts =>
18
- {
19
- opts.EnableDetailedErrors = builder.Environment.IsDevelopment();
20
- opts.MaxReceiveMessageSize = 4 * 1024 * 1024; // 4 MB
21
- });
22
- app.MapGrpcService<OrdersService>();
23
- ```
24
-
25
- ## Proto Definition
26
- ```protobuf
27
- syntax = "proto3";
28
- option csharp_namespace = "MyApp.Grpc";
29
-
30
- service Orders {
31
- rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
32
- rpc GetOrder(GetOrderRequest) returns (OrderResponse);
33
- rpc StreamOrders(StreamOrdersRequest) returns (stream OrderResponse);
34
- }
35
-
36
- message CreateOrderRequest {
37
- string user_id = 1;
38
- repeated OrderItem items = 2;
39
- }
40
-
41
- message CreateOrderResponse {
42
- string order_id = 1;
43
- double total = 2;
44
- }
45
- ```
46
-
47
- ## Service Implementation
48
- ```csharp
49
- public class OrdersService : Orders.OrdersBase
50
- {
51
- public override async Task<CreateOrderResponse> CreateOrder(
52
- CreateOrderRequest request, ServerCallContext context)
53
- {
54
- var cmd = new CreateOrderCommand(
55
- Guid.Parse(request.UserId),
56
- request.Items.Select(i => new OrderItem(i.ProductId, i.Quantity)).ToList());
57
-
58
- var result = await _sender.Send(cmd, context.CancellationToken);
59
-
60
- return new CreateOrderResponse
61
- {
62
- OrderId = result.OrderId.ToString(),
63
- Total = (double)result.Total
64
- };
65
- }
66
-
67
- public override async Task StreamOrders(
68
- StreamOrdersRequest request,
69
- IServerStreamWriter<OrderResponse> responseStream,
70
- ServerCallContext context)
71
- {
72
- await foreach (var order in _service.GetOrderStreamAsync(context.CancellationToken))
73
- {
74
- await responseStream.WriteAsync(MapToResponse(order), context.CancellationToken);
75
- if (context.CancellationToken.IsCancellationRequested) break;
76
- }
77
- }
78
- }
79
- ```
80
-
81
- ## Client Setup
82
- ```csharp
83
- // Program.cs (client service)
84
- builder.Services.AddGrpcClient<Orders.OrdersClient>(opts =>
85
- {
86
- opts.Address = new Uri(config["Services:OrdersUrl"]);
87
- })
88
- .ConfigureChannel(opts =>
89
- {
90
- opts.HttpHandler = new SocketsHttpHandler
91
- {
92
- PooledConnectionIdleTimeout = Timeout.InfiniteTimeSpan,
93
- KeepAlivePingDelay = TimeSpan.FromSeconds(60),
94
- KeepAlivePingTimeout = TimeSpan.FromSeconds(30)
95
- };
96
- });
97
- ```
98
-
99
- ## Error Handling
100
- ```csharp
101
- // Map exceptions to gRPC status codes
102
- try
103
- {
104
- return await _service.ProcessAsync(request.Id);
105
- }
106
- catch (NotFoundException)
107
- {
108
- throw new RpcException(new Status(StatusCode.NotFound, "Order not found"));
109
- }
110
- catch (ValidationException ex)
111
- {
112
- throw new RpcException(new Status(StatusCode.InvalidArgument, ex.Message));
113
- }
114
- ```