@polymorphism-tech/morph-spec 4.12.0 → 4.14.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 (316) hide show
  1. package/CLAUDE.md +7 -7
  2. package/README.md +28 -34
  3. package/bin/morph-spec.js +41 -24
  4. package/bin/task-manager.js +962 -1341
  5. package/bin/validate.js +1 -1
  6. package/claude-plugin.json +1 -1
  7. package/docs/CHEATSHEET.md +14 -16
  8. package/docs/QUICKSTART.md +15 -15
  9. package/framework/CLAUDE.md +5 -2
  10. package/framework/agents/README.md +3 -4
  11. package/framework/agents/ai-agents/ai-system-architect.md +6 -10
  12. package/framework/agents/architecture/seo-growth-hacker.md +166 -326
  13. package/framework/agents/architecture/standards-architect.md +21 -31
  14. package/framework/agents/backend/dotnet-senior.md +160 -86
  15. package/framework/agents/backend/ef-modeler.md +2 -6
  16. package/framework/agents/backend/hangfire-orchestrator.md +8 -9
  17. package/framework/agents/backend/ms-agent-expert.md +1 -1
  18. package/framework/agents/frontend/nextjs-expert.md +198 -133
  19. package/framework/agents/frontend/ui-ux-designer.md +226 -267
  20. package/framework/agents/infrastructure/infra-architect.md +191 -27
  21. package/framework/agents/integrations/clerk-auth.md +19 -26
  22. package/framework/agents/integrations/hangfire-integration.md +1 -4
  23. package/framework/agents.json +1084 -2278
  24. package/framework/commands/morph-apply.md +4 -6
  25. package/framework/commands/morph-preflight.md +192 -269
  26. package/framework/commands/morph-proposal.md +210 -238
  27. package/framework/commands/morph-status.md +72 -92
  28. package/framework/commands/morph-troubleshoot.md +6 -13
  29. package/framework/hooks/README.md +1 -6
  30. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +4 -6
  31. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
  32. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
  33. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
  34. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
  35. package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
  36. package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
  37. package/framework/hooks/claude-code/statusline.py +4 -5
  38. package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
  39. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
  40. package/framework/hooks/shared/compact-restore.js +28 -5
  41. package/framework/hooks/shared/phase-utils.js +4 -8
  42. package/framework/hooks/shared/state-reader.js +34 -3
  43. package/framework/phases.json +162 -200
  44. package/framework/rules/ai-agents-standards.md +15 -0
  45. package/framework/rules/asaas-standards.md +13 -0
  46. package/framework/rules/clerk-standards.md +13 -0
  47. package/framework/rules/csharp-standards.md +8 -4
  48. package/framework/rules/data-standards.md +18 -0
  49. package/framework/rules/dotnet-templates.md +87 -0
  50. package/framework/rules/frontend-standards.md +13 -13
  51. package/framework/rules/hangfire-standards.md +13 -0
  52. package/framework/rules/infrastructure-standards.md +27 -16
  53. package/framework/rules/morph-workflow.md +73 -13
  54. package/framework/rules/nextjs-standards.md +1 -0
  55. package/framework/rules/nextjs-templates.md +40 -0
  56. package/framework/rules/resend-standards.md +12 -0
  57. package/framework/rules/supabase-standards.md +29 -0
  58. package/framework/skills/README.md +6 -8
  59. package/framework/skills/level-0-meta/mcp-registry.json +21 -99
  60. package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
  61. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
  62. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  63. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
  64. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
  65. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
  66. package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
  67. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
  68. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
  69. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
  70. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
  71. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
  72. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
  73. package/framework/skills/level-1-workflows/README.md +1 -1
  74. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
  75. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +57 -123
  76. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
  77. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
  78. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
  79. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +1 -1
  80. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
  81. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
  82. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
  83. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
  84. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
  85. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +143 -172
  86. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
  87. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +57 -77
  88. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  89. package/framework/squad-templates/backend-only.json +6 -6
  90. package/framework/squad-templates/frontend-only.json +17 -8
  91. package/framework/squad-templates/full-stack.json +29 -24
  92. package/framework/standards/STANDARDS.json +1021 -2369
  93. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
  94. package/framework/standards/backend/dotnet/result-pattern.md +213 -0
  95. package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
  96. package/framework/standards/backend/dotnet/scrutor.md +158 -0
  97. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
  98. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
  99. package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
  100. package/framework/standards/integration/mcp/mcp-tools.md +91 -77
  101. package/framework/templates/IDE-SNIPPETS.md +2 -6
  102. package/framework/templates/README.md +709 -814
  103. package/framework/templates/REGISTRY.json +223 -762
  104. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
  105. package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
  106. package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
  107. package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
  108. package/framework/templates/code/dotnet/backend/repository.cs +148 -141
  109. package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
  110. package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
  111. package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
  112. package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
  113. package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
  114. package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
  115. package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
  116. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
  117. package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
  118. package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
  119. package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
  120. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
  121. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
  122. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
  123. package/framework/templates/code/dotnet/jobs/job.cs +21 -17
  124. package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
  125. package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
  126. package/framework/templates/code/dotnet/test.cs +192 -106
  127. package/framework/templates/context/ARCHITECTURE.md +89 -0
  128. package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
  129. package/framework/templates/context/CONTEXT.md +180 -181
  130. package/framework/templates/context/design-system.md +1 -5
  131. package/framework/templates/docs/onboarding.md +2 -3
  132. package/framework/templates/docs/proposal.md +171 -182
  133. package/framework/templates/docs/spec.md +1 -3
  134. package/framework/templates/docs/ui-components.md +0 -72
  135. package/framework/templates/examples/design-system-examples.md +4 -4
  136. package/framework/templates/feature/decisions.md +0 -66
  137. package/framework/templates/feature/recap.md +1 -2
  138. package/framework/templates/infrastructure/github/README.md +56 -593
  139. package/framework/templates/integrations/clerk-config.cs +0 -41
  140. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  141. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
  142. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
  143. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
  144. package/framework/templates/project/validate.js +2 -4
  145. package/framework/templates/ui/design-system.css +1 -1
  146. package/framework/workflows/README.md +8 -8
  147. package/framework/workflows/configs/fast-track.json +51 -0
  148. package/framework/workflows/configs/full.json +68 -0
  149. package/framework/workflows/configs/standard.json +7 -3
  150. package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
  151. package/framework/workflows/docs/enforcement-pipeline.md +18 -19
  152. package/framework/workflows/docs/full-morph.md +69 -76
  153. package/framework/workflows/docs/standard.md +49 -44
  154. package/framework/workflows/docs/ui-refresh.md +1 -1
  155. package/package.json +3 -3
  156. package/src/commands/agents/dispatch-agents.js +55 -116
  157. package/src/commands/context/context-refresh.js +79 -0
  158. package/src/commands/phase/phase-reset.js +1 -1
  159. package/src/commands/project/doctor.js +10 -32
  160. package/src/commands/project/init.js +12 -0
  161. package/src/commands/project/status.js +6 -12
  162. package/src/commands/scaffold/scaffold.js +131 -0
  163. package/src/commands/scope/escalate.js +1 -1
  164. package/src/commands/state/advance-phase.js +15 -29
  165. package/src/commands/state/state.js +20 -5
  166. package/src/commands/tasks/task.js +0 -30
  167. package/src/commands/validation/validate-feature.js +3 -10
  168. package/src/core/paths/output-schema.js +12 -13
  169. package/src/core/state/phase-state-machine.js +211 -217
  170. package/src/core/state/state-manager.js +9 -9
  171. package/src/lib/agents/agents-manager.js +2 -2
  172. package/src/lib/agents/output-collector.js +1 -2
  173. package/src/lib/detectors/design-system-detector.js +4 -4
  174. package/src/lib/detectors/index.js +1 -11
  175. package/src/lib/generators/architecture-scanner.js +640 -0
  176. package/src/lib/generators/context-generator.js +3 -3
  177. package/src/lib/generators/design-system-generator.js +508 -587
  178. package/src/lib/generators/index.js +12 -10
  179. package/src/lib/generators/metadata-extractor.js +386 -387
  180. package/src/lib/generators/recap-generator.js +4 -4
  181. package/src/lib/generators/scaffold-generator.js +317 -0
  182. package/src/lib/generators/settings-generator.js +0 -1
  183. package/src/lib/phase-chain/phase-validator.js +64 -42
  184. package/src/lib/stack/stack-profile.js +2 -2
  185. package/src/lib/standards/digest-builder.js +72 -285
  186. package/src/lib/tasks/task-parser.js +11 -5
  187. package/src/lib/validators/architecture/architecture-validator.js +259 -387
  188. package/src/lib/validators/content/content-validator.js +287 -287
  189. package/src/lib/validators/css/css-validator.js +340 -352
  190. package/src/lib/validators/packages/package-validator.js +347 -360
  191. package/src/lib/validators/shared/issue-counter.js +14 -18
  192. package/src/lib/validators/validation-runner.js +3 -19
  193. package/src/scripts/setup-infra.js +1 -1
  194. package/src/utils/agents-installer.js +61 -10
  195. package/src/utils/file-copier.js +1 -0
  196. package/src/utils/hooks-installer.js +11 -19
  197. package/src/utils/skills-installer.js +178 -178
  198. package/framework/agents/architecture/prompt-engineer.md +0 -195
  199. package/framework/agents/backend/api-designer.md +0 -106
  200. package/framework/agents/frontend/blazor-builder.md +0 -229
  201. package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
  202. package/framework/agents/infrastructure/azure-architect.md +0 -150
  203. package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
  204. package/framework/agents/infrastructure/bicep-architect.md +0 -132
  205. package/framework/agents/infrastructure/container-specialist.md +0 -137
  206. package/framework/agents/infrastructure/devops-engineer.md +0 -126
  207. package/framework/agents/integrations/azure-identity.md +0 -148
  208. package/framework/agents/quality/code-analyzer.md +0 -239
  209. package/framework/agents/quality/testing-specialist.md +0 -130
  210. package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
  211. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
  212. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
  213. package/framework/index/troubleshooting-index.json +0 -184
  214. package/framework/rules/testing-standards.md +0 -14
  215. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
  216. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
  217. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
  218. package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
  219. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
  220. package/framework/standards/ai-agents/blazor-ui.md +0 -364
  221. package/framework/standards/architecture/ddd/aggregates.md +0 -120
  222. package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  223. package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  224. package/framework/standards/architecture/ddd/entities.md +0 -99
  225. package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  226. package/framework/standards/architecture/ddd/value-objects.md +0 -124
  227. package/framework/standards/backend/api/minimal-api.md +0 -494
  228. package/framework/standards/backend/api/rest.md +0 -492
  229. package/framework/standards/backend/authentication/passkeys.md +0 -428
  230. package/framework/standards/backend/database/ef-core.md +0 -199
  231. package/framework/standards/backend/database/migrations.md +0 -393
  232. package/framework/standards/backend/database/repository-patterns.md +0 -528
  233. package/framework/standards/backend/dotnet/async.md +0 -366
  234. package/framework/standards/backend/dotnet/core.md +0 -117
  235. package/framework/standards/backend/dotnet/di.md +0 -439
  236. package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  237. package/framework/standards/context/analytics.md +0 -96
  238. package/framework/standards/context/bundles.md +0 -110
  239. package/framework/standards/context/priming.md +0 -78
  240. package/framework/standards/core/architecture.md +0 -185
  241. package/framework/standards/core/coding.md +0 -214
  242. package/framework/standards/core/git-branching-strategy.md +0 -403
  243. package/framework/standards/core/git.md +0 -185
  244. package/framework/standards/core/testing.md +0 -295
  245. package/framework/standards/data/nosql/blob-storage.md +0 -102
  246. package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  247. package/framework/standards/frontend/blazor/design-checklist.md +0 -222
  248. package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  249. package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  250. package/framework/standards/frontend/blazor/html-conversion.md +0 -184
  251. package/framework/standards/frontend/blazor/lifecycle.md +0 -195
  252. package/framework/standards/frontend/blazor/pitfalls.md +0 -198
  253. package/framework/standards/frontend/blazor/state.md +0 -191
  254. package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -266
  255. package/framework/standards/frontend/design-system/design-trends.md +0 -171
  256. package/framework/standards/infrastructure/azure/azure.md +0 -624
  257. package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  258. package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  259. package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  260. package/framework/standards/infrastructure/azure/services/functions.md +0 -486
  261. package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  262. package/framework/standards/infrastructure/azure/services/storage.md +0 -407
  263. package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
  264. package/framework/standards/integration/api/graphql.md +0 -91
  265. package/framework/standards/integration/api/grpc.md +0 -114
  266. package/framework/standards/integration/api/rest-design.md +0 -95
  267. package/framework/standards/integration/event-driven/cqrs.md +0 -101
  268. package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  269. package/framework/standards/integration/event-driven/service-bus.md +0 -95
  270. package/framework/standards/observability/logging.md +0 -131
  271. package/framework/standards/observability/metrics.md +0 -121
  272. package/framework/standards/observability/monitoring.md +0 -114
  273. package/framework/standards/observability/tracing.md +0 -132
  274. package/framework/standards/workflows/parallel-execution.md +0 -112
  275. package/framework/standards/workflows/thread-management.md +0 -113
  276. package/framework/templates/code/dotnet/backend/service.cs +0 -139
  277. package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  278. package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  279. package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  280. package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  281. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  282. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  283. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  284. package/framework/templates/code/dotnet/frontend/component.razor +0 -239
  285. package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  286. package/framework/templates/infrastructure/azure/README.md +0 -286
  287. package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  288. package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  289. package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  290. package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  291. package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  292. package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  293. package/framework/templates/infrastructure/azure/deploy.sh +0 -208
  294. package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  295. package/framework/templates/infrastructure/azure/main.bicep +0 -189
  296. package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  297. package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  298. package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  299. package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  300. package/framework/templates/infrastructure/azure/storage.bicep +0 -106
  301. package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  302. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  303. package/framework/templates/integrations/azure-identity-config.cs +0 -288
  304. package/framework/templates/project-structure/dotnet-ddd.md +0 -70
  305. package/framework/templates/saas/subscription.cs +0 -347
  306. package/framework/templates/saas/tenant.cs +0 -338
  307. package/framework/templates/ui/FluentDesignTheme.cs +0 -149
  308. package/framework/templates/ui/MudTheme.cs +0 -281
  309. package/framework/workflows/configs/nodejs-cli.json +0 -40
  310. package/src/commands/standards/context-budget.js +0 -89
  311. package/src/lib/standards/index.js +0 -7
  312. package/src/lib/standards/standards-context-injector.js +0 -302
  313. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
  314. package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
  315. package/src/lib/validators/blazor/blazor-validator.js +0 -369
  316. 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
- ```