@polymorphism-tech/morph-spec 8.37.1 → 8.40.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 (317) hide show
  1. package/CLAUDE.md +37 -13
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +75 -49
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +6 -5
  8. package/framework/MORPH.md +25 -22
  9. package/framework/agents.json +96 -36
  10. package/framework/docs/CLI.md +54 -17
  11. package/framework/evals/rubrics/code-quality.md +5 -0
  12. package/framework/evals/rubrics/condensed.md +6 -2
  13. package/framework/evals/rubrics/contracts.md +20 -0
  14. package/framework/evals/rubrics/test-coverage.md +17 -6
  15. package/framework/hooks/README.md +9 -3
  16. package/framework/hooks/claude-code/core/graph-refresh-kick.js +52 -0
  17. package/framework/hooks/claude-code/core/telemetry-log.js +172 -87
  18. package/framework/hooks/claude-code/core/validate-completion.js +16 -90
  19. package/framework/hooks/claude-code/core/worktree-context.js +10 -0
  20. package/framework/hooks/shared/command-tokens.js +96 -0
  21. package/framework/hooks/shared/git-exclude.js +44 -0
  22. package/framework/hooks/shared/git-paths.js +52 -0
  23. package/framework/hooks/shared/graph-freshness.js +380 -0
  24. package/framework/hooks/shared/graph-refresh.js +416 -0
  25. package/framework/hooks/shared/morph-cli.js +17 -5
  26. package/framework/hooks/shared/redact-secrets.js +55 -0
  27. package/framework/hooks/shared/telemetry-logger.js +25 -2
  28. package/framework/hooks/shared/transcript-usage.js +80 -0
  29. package/framework/mcp/registry.json +33 -2
  30. package/framework/rubrics/backend.json +2 -2
  31. package/framework/rubrics/default.json +2 -2
  32. package/framework/rubrics/frontend.json +2 -2
  33. package/framework/rules/csharp-standards.md +1 -0
  34. package/framework/rules/infrastructure-standards.md +0 -1
  35. package/framework/rules/morph-workflow.md +10 -4
  36. package/framework/rules/nextjs-standards.md +1 -0
  37. package/framework/schemas/config.schema.json +41 -1
  38. package/framework/schemas/feature.schema.json +5 -1
  39. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  40. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  41. package/framework/skills/core/morph-apply/SKILL.md +40 -11
  42. package/framework/skills/core/morph-brainstorming/SKILL.md +16 -7
  43. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  44. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  45. package/framework/skills/core/morph-implement/SKILL.md +44 -10
  46. package/framework/skills/core/morph-media/SKILL.md +1 -1
  47. package/framework/skills/core/morph-plan/SKILL.md +73 -15
  48. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  49. package/framework/skills/core/morph-review/SKILL.md +51 -13
  50. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  51. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  52. package/framework/skills/core/morph-uiux/SKILL.md +39 -13
  53. package/framework/standards/STANDARDS.json +189 -14
  54. package/framework/standards/ai-agents/context-providers.md +16 -26
  55. package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
  56. package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
  57. package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
  58. package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
  59. package/framework/standards/ai-agents/modalities-vision.md +1 -18
  60. package/framework/standards/ai-agents/prompt-sources.md +0 -4
  61. package/framework/standards/ai-agents/testing-ai.md +2 -1
  62. package/framework/standards/architecture/code-comments.md +100 -0
  63. package/framework/standards/backend/dotnet/testing.md +22 -0
  64. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
  65. package/framework/standards/frontend/admin-app/data-table.md +562 -0
  66. package/framework/standards/frontend/admin-app/feedback.md +236 -0
  67. package/framework/standards/frontend/admin-app/forms.md +232 -0
  68. package/framework/standards/frontend/admin-app/page-structure.md +203 -0
  69. package/framework/standards/frontend/design-system/ai-image-generation.md +5 -5
  70. package/framework/standards/frontend/nextjs/components.md +37 -58
  71. package/framework/standards/frontend/nextjs/data-fetching.md +1 -0
  72. package/framework/standards/frontend/nextjs/forms.md +31 -30
  73. package/framework/standards/frontend/nextjs/state-management.md +2 -1
  74. package/framework/standards/frontend/nextjs/testing.md +18 -0
  75. package/framework/standards/integration/mcp/mcp-tools.md +48 -117
  76. package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
  77. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
  78. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
  79. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
  80. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
  81. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
  82. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
  83. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
  84. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
  85. package/framework/templates/code/dotnet/database/migration.cs +49 -83
  86. package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
  87. package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
  88. package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
  89. package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
  90. package/framework/templates/code/dotnet/jobs/job.cs +2 -97
  91. package/framework/templates/code/dotnet/test.cs +2 -87
  92. package/framework/templates/code/typescript/contracts.ts +140 -167
  93. package/framework/templates/context/design-system.md +3 -3
  94. package/framework/templates/docs/proposal.md +11 -0
  95. package/framework/templates/docs/spec.md +15 -0
  96. package/framework/templates/docs/ui-mockups.md +115 -98
  97. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
  98. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
  99. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
  100. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
  101. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
  102. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
  103. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
  104. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
  105. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
  106. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
  107. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
  108. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
  109. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
  110. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
  111. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
  112. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
  113. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
  114. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
  115. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
  116. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
  117. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
  118. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
  119. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
  120. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
  121. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
  122. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
  123. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
  124. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
  125. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
  126. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
  127. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
  128. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
  129. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
  130. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
  131. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
  132. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
  133. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
  134. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
  135. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
  136. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
  137. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
  138. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
  139. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
  140. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
  141. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
  142. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
  143. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
  144. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
  145. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
  146. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
  147. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
  148. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
  149. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
  150. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
  151. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
  152. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
  153. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
  154. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
  155. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
  156. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
  157. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
  158. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
  159. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
  160. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
  161. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
  162. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
  163. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
  164. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
  165. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
  166. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
  167. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
  168. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
  169. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
  170. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
  171. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
  172. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
  173. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
  174. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
  175. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
  176. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
  177. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
  178. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
  179. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
  180. package/framework/templates/feature/decisions.md +124 -122
  181. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
  182. package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
  183. package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
  184. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
  185. package/framework/templates/integrations/asaas-client.cs +332 -387
  186. package/framework/templates/integrations/asaas-webhook.cs +290 -351
  187. package/framework/templates/integrations/neon-auth-config.cs +9 -105
  188. package/framework/templates/project/validate.js +97 -120
  189. package/package.json +2 -2
  190. package/src/commands/dashboard/dashboard.js +80 -53
  191. package/src/commands/graph/affected.js +4 -3
  192. package/src/commands/graph/build.js +109 -18
  193. package/src/commands/graph/explain.js +8 -5
  194. package/src/commands/graph/status.js +14 -8
  195. package/src/commands/mcp/mcp-setup.js +37 -9
  196. package/src/commands/observability/cost.js +148 -18
  197. package/src/commands/project/doctor.js +85 -15
  198. package/src/commands/project/init.js +6 -3
  199. package/src/commands/project/install-plugin-cmd.js +1 -1
  200. package/src/commands/project/update.js +30 -0
  201. package/src/commands/project/worktree.js +73 -90
  202. package/src/commands/state/advance.js +18 -0
  203. package/src/commands/state/approve.js +15 -0
  204. package/src/commands/state/archive.js +62 -9
  205. package/src/commands/state/finish.js +62 -14
  206. package/src/commands/state/gate-check.js +8 -1
  207. package/src/commands/state/gate-decision.js +8 -4
  208. package/src/commands/state/report-check.js +90 -9
  209. package/src/commands/state/usecase.js +66 -0
  210. package/src/commands/tasks/dag.js +17 -2
  211. package/src/commands/validation/validate-feature.js +6 -1
  212. package/src/commands/validation/verify.js +20 -1
  213. package/src/dashboard/app/App.jsx +80 -16
  214. package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
  215. package/src/dashboard/app/components/CommandPalette.jsx +155 -0
  216. package/src/dashboard/app/components/DetailPanel.jsx +47 -11
  217. package/src/dashboard/app/components/EntityLink.jsx +55 -0
  218. package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
  219. package/src/dashboard/app/components/FlowGraph.jsx +19 -17
  220. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
  221. package/src/dashboard/app/components/Markdown.jsx +47 -0
  222. package/src/dashboard/app/components/PhaseRail.jsx +111 -0
  223. package/src/dashboard/app/components/SearchFilter.jsx +40 -22
  224. package/src/dashboard/app/components/Sidebar.jsx +146 -37
  225. package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
  226. package/src/dashboard/app/hooks/usePref.js +38 -0
  227. package/src/dashboard/app/lib/format.js +69 -0
  228. package/src/dashboard/app/lib/phases.js +56 -0
  229. package/src/dashboard/app/lib/project.js +50 -0
  230. package/src/dashboard/app/pages/Activity.jsx +24 -0
  231. package/src/dashboard/app/pages/AgentMap.jsx +371 -370
  232. package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
  233. package/src/dashboard/app/pages/Features.jsx +400 -0
  234. package/src/dashboard/app/pages/Guide.jsx +146 -0
  235. package/src/dashboard/app/pages/HookInspector.jsx +357 -322
  236. package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
  237. package/src/dashboard/app/pages/Portfolio.jsx +156 -0
  238. package/src/dashboard/app/pages/Rubrics.jsx +101 -0
  239. package/src/dashboard/app/pages/RulesMap.jsx +300 -273
  240. package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
  241. package/src/dashboard/app/pages/Standards.jsx +407 -332
  242. package/src/dashboard/app/styles/index.css +187 -47
  243. package/src/dashboard/index.html +14 -12
  244. package/src/dashboard/package.json +32 -24
  245. package/src/dashboard/scanner/activity-scanner.js +351 -0
  246. package/src/dashboard/scanner/agents-scanner.js +63 -1
  247. package/src/dashboard/scanner/docs-scanner.js +59 -0
  248. package/src/dashboard/scanner/feature-status.js +10 -0
  249. package/src/dashboard/scanner/features-scanner.js +360 -0
  250. package/src/dashboard/scanner/hooks-scanner.js +8 -1
  251. package/src/dashboard/scanner/index.js +14 -7
  252. package/src/dashboard/scanner/phases-scanner.js +14 -15
  253. package/src/dashboard/scanner/portfolio.js +153 -0
  254. package/src/dashboard/scanner/project-api.js +195 -0
  255. package/src/dashboard/scanner/rules-scanner.js +42 -37
  256. package/src/dashboard/scanner/skills-scanner.js +105 -43
  257. package/src/dashboard/scanner/standards-scanner.js +4 -1
  258. package/src/dashboard/vite-plugin-morph-data.js +134 -17
  259. package/src/lib/ai/comment-stripper.js +101 -4
  260. package/src/lib/detectors/claude-config-detector.js +2 -7
  261. package/src/lib/detectors/index.js +5 -1
  262. package/src/lib/evaluator-report.js +47 -0
  263. package/src/lib/generators/handoff-generator.js +4 -18
  264. package/src/lib/generators/settings-generator.js +208 -209
  265. package/src/lib/git/default-branch.js +52 -0
  266. package/src/lib/git/tree-fingerprint.js +58 -0
  267. package/src/lib/git/tree-state.js +167 -0
  268. package/src/lib/graph/god-nodes.js +12 -3
  269. package/src/lib/graph/graph-health.js +48 -2
  270. package/src/lib/graph/graph-loader.js +99 -25
  271. package/src/lib/graph/graphifyignore.js +145 -28
  272. package/src/lib/graph/sanitize.js +117 -11
  273. package/src/lib/installers/mcp-installer.js +724 -719
  274. package/src/lib/installers/memory-installer.js +1 -2
  275. package/src/lib/projects/registry.js +154 -0
  276. package/src/lib/risk-detector.js +90 -0
  277. package/src/lib/specs/acervo-format.js +70 -0
  278. package/src/lib/specs/acervo-lifecycle.js +264 -0
  279. package/src/lib/specs/adr-index.js +169 -0
  280. package/src/lib/specs/revocations.js +156 -0
  281. package/src/lib/specs/screen-checklist.js +357 -0
  282. package/src/lib/specs/usecase-check.js +20 -16
  283. package/src/lib/specs/usecase-promoter.js +103 -38
  284. package/src/lib/specs/usecase-registry.js +7 -7
  285. package/src/lib/tasks/tasks-json-parser.js +2 -3
  286. package/src/lib/telemetry/metrics.js +386 -0
  287. package/src/lib/telemetry/telemetry-reader.js +161 -51
  288. package/src/lib/telemetry/verify-event.js +79 -0
  289. package/src/lib/validators/code-budget/code-budget-validator.js +200 -0
  290. package/src/lib/validators/code-budget/comment-scanner.js +75 -0
  291. package/src/lib/validators/code-budget/index.js +9 -0
  292. package/src/lib/validators/reuse/reuse-validator.js +4 -2
  293. package/src/lib/validators/reuse/symbol-scanner.js +27 -22
  294. package/src/lib/validators/validation-runner.js +21 -5
  295. package/src/lib/validators/verify-runner.js +11 -0
  296. package/src/lib/worktree/finish-backup.js +739 -0
  297. package/src/lib/worktree/ignored-triage.js +15 -8
  298. package/src/lib/worktree/worktree-audit.js +5 -0
  299. package/src/scripts/install-plugin.js +1 -1
  300. package/src/scripts/setup-infra.js +31 -22
  301. package/src/utils/agents-installer.js +338 -24
  302. package/src/utils/banner.js +1 -1
  303. package/src/utils/hooks-installer.js +75 -15
  304. package/src/commands/index.js +0 -13
  305. package/src/commands/project/checkpoint.js +0 -209
  306. package/src/core/state/phase-state-machine.js +0 -197
  307. package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
  308. package/src/dashboard/app/pages/LiveState.jsx +0 -206
  309. package/src/dashboard/scanner/squads-scanner.js +0 -13
  310. package/src/dashboard/scanner/state-scanner.js +0 -85
  311. package/src/lib/generators/index.js +0 -10
  312. package/src/lib/hooks/hook-executor.js +0 -167
  313. package/src/lib/validators/checkpoint-persistence.js +0 -39
  314. package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
  315. package/src/lib/validators/shared/index.js +0 -12
  316. package/src/lib/validators/shared/issue-counter.js +0 -14
  317. package/src/lib/validators/shared/result-formatter.js +0 -124
@@ -1,83 +1,49 @@
1
- // ============================================================
2
- // EF CORE MIGRATION TEMPLATE
3
- // Generated by MORPH Framework
4
- // ============================================================
5
-
6
- using Microsoft.EntityFrameworkCore.Migrations;
7
-
8
- #nullable disable
9
-
10
- namespace {{NAMESPACE}}.Infrastructure.Data.Migrations;
11
-
12
- /// <inheritdoc />
13
- public partial class Add{{pascalCase FEATURE_NAME}} : Migration
14
- {
15
- /// <inheritdoc />
16
- protected override void Up(MigrationBuilder migrationBuilder)
17
- {
18
- migrationBuilder.CreateTable(
19
- name: "{{pascalCase FEATURE_NAME}}s",
20
- columns: table => new
21
- {
22
- Id = table.Column<int>(type: "int", nullable: false)
23
- .Annotation("SqlServer:Identity", "1, 1"),
24
- Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
25
- Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
26
- CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false,
27
- defaultValueSql: "GETUTCDATE()"),
28
- UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
29
- },
30
- constraints: table =>
31
- {
32
- table.PrimaryKey("PK_{{pascalCase FEATURE_NAME}}s", x => x.Id);
33
- });
34
-
35
- // Indexes
36
- migrationBuilder.CreateIndex(
37
- name: "IX_{{pascalCase FEATURE_NAME}}s_Name",
38
- table: "{{pascalCase FEATURE_NAME}}s",
39
- column: "Name");
40
-
41
- migrationBuilder.CreateIndex(
42
- name: "IX_{{pascalCase FEATURE_NAME}}s_Status",
43
- table: "{{pascalCase FEATURE_NAME}}s",
44
- column: "Status");
45
-
46
- migrationBuilder.CreateIndex(
47
- name: "IX_{{pascalCase FEATURE_NAME}}s_CreatedAt",
48
- table: "{{pascalCase FEATURE_NAME}}s",
49
- column: "CreatedAt");
50
- }
51
-
52
- /// <inheritdoc />
53
- protected override void Down(MigrationBuilder migrationBuilder)
54
- {
55
- migrationBuilder.DropTable(
56
- name: "{{pascalCase FEATURE_NAME}}s");
57
- }
58
- }
59
-
60
- // ============================================================
61
- // HOW TO CREATE A MIGRATION
62
- // ============================================================
63
- //
64
- // 1. Add your entity to AppDbContext:
65
- //
66
- // public DbSet<{{pascalCase FEATURE_NAME}}> {{pascalCase FEATURE_NAME}}s => Set<{{pascalCase FEATURE_NAME}}>();
67
- //
68
- // 2. Add your configuration:
69
- //
70
- // protected override void OnModelCreating(ModelBuilder modelBuilder)
71
- // {
72
- // modelBuilder.ApplyConfiguration(new {{pascalCase FEATURE_NAME}}Configuration());
73
- // }
74
- //
75
- // 3. Run migration command:
76
- //
77
- // dotnet ef migrations add Add{{pascalCase FEATURE_NAME}} -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
78
- //
79
- // 4. Apply migration:
80
- //
81
- // dotnet ef database update -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
82
- //
83
- // ============================================================
1
+ using Microsoft.EntityFrameworkCore.Migrations;
2
+
3
+ #nullable disable
4
+
5
+ namespace {{NAMESPACE}}.Infrastructure.Data.Migrations;
6
+
7
+ public partial class Add{{pascalCase FEATURE_NAME}} : Migration
8
+ {
9
+ protected override void Up(MigrationBuilder migrationBuilder)
10
+ {
11
+ migrationBuilder.CreateTable(
12
+ name: "{{pascalCase FEATURE_NAME}}s",
13
+ columns: table => new
14
+ {
15
+ Id = table.Column<int>(type: "int", nullable: false)
16
+ .Annotation("SqlServer:Identity", "1, 1"),
17
+ Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
18
+ Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
19
+ CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false,
20
+ defaultValueSql: "GETUTCDATE()"),
21
+ UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
22
+ },
23
+ constraints: table =>
24
+ {
25
+ table.PrimaryKey("PK_{{pascalCase FEATURE_NAME}}s", x => x.Id);
26
+ });
27
+
28
+ migrationBuilder.CreateIndex(
29
+ name: "IX_{{pascalCase FEATURE_NAME}}s_Name",
30
+ table: "{{pascalCase FEATURE_NAME}}s",
31
+ column: "Name");
32
+
33
+ migrationBuilder.CreateIndex(
34
+ name: "IX_{{pascalCase FEATURE_NAME}}s_Status",
35
+ table: "{{pascalCase FEATURE_NAME}}s",
36
+ column: "Status");
37
+
38
+ migrationBuilder.CreateIndex(
39
+ name: "IX_{{pascalCase FEATURE_NAME}}s_CreatedAt",
40
+ table: "{{pascalCase FEATURE_NAME}}s",
41
+ column: "CreatedAt");
42
+ }
43
+
44
+ protected override void Down(MigrationBuilder migrationBuilder)
45
+ {
46
+ migrationBuilder.DropTable(
47
+ name: "{{pascalCase FEATURE_NAME}}s");
48
+ }
49
+ }
@@ -1,8 +1,3 @@
1
- // ============================================================
2
- // PGVECTOR ENTITY + CONFIGURATION TEMPLATE
3
- // Generated by MORPH Framework
4
- // ============================================================
5
-
6
1
  using System.ComponentModel.DataAnnotations.Schema;
7
2
  using Microsoft.EntityFrameworkCore;
8
3
  using Microsoft.EntityFrameworkCore.Metadata.Builders;
@@ -12,10 +7,6 @@ using Pgvector;
12
7
 
13
8
  namespace {{NAMESPACE}}.Domain.Entities;
14
9
 
15
- /// <summary>
16
- /// Entity with vector embedding for similarity search via pgvector.
17
- /// Dimensions: 1536 (text-embedding-3-small). Adjust if using a different model.
18
- /// </summary>
19
10
  public class {{pascalCase FEATURE_NAME}}
20
11
  {
21
12
  public Guid Id { get; set; }
@@ -23,6 +14,7 @@ public class {{pascalCase FEATURE_NAME}}
23
14
  public string Content { get; set; } = string.Empty;
24
15
  public string? Metadata { get; set; }
25
16
 
17
+ // 1536 é a dimensão do text-embedding-3-small; troca junto com o modelo, aqui e na configuração
26
18
  [Column(TypeName = "vector(1536)")]
27
19
  public Vector? Embedding { get; set; }
28
20
 
@@ -30,12 +22,9 @@ public class {{pascalCase FEATURE_NAME}}
30
22
  public DateTimeOffset? UpdatedAt { get; set; }
31
23
  }
32
24
 
33
- // ============================================================
34
- // ENTITY TYPE CONFIGURATION
35
- // ============================================================
36
-
37
25
  namespace {{NAMESPACE}}.Infrastructure.Data.Configurations;
38
26
 
27
+ // Exige UseVector() no AddNpgsql e HasPostgresExtension("vector") no OnModelCreating
39
28
  public class {{pascalCase FEATURE_NAME}}Configuration : IEntityTypeConfiguration<{{pascalCase FEATURE_NAME}}>
40
29
  {
41
30
  public void Configure(EntityTypeBuilder<{{pascalCase FEATURE_NAME}}> builder)
@@ -49,7 +38,6 @@ public class {{pascalCase FEATURE_NAME}}Configuration : IEntityTypeConfiguration
49
38
  builder.Property(e => e.Embedding).HasColumnType("vector(1536)");
50
39
  builder.Property(e => e.CreatedAt).HasDefaultValueSql("now()");
51
40
 
52
- // HNSW index for cosine similarity search
53
41
  builder.HasIndex(e => e.Embedding)
54
42
  .HasMethod("hnsw")
55
43
  .HasOperators("vector_cosine_ops")
@@ -59,35 +47,3 @@ public class {{pascalCase FEATURE_NAME}}Configuration : IEntityTypeConfiguration
59
47
  builder.HasIndex(e => e.Title);
60
48
  }
61
49
  }
62
-
63
- // ============================================================
64
- // SETUP INSTRUCTIONS
65
- // ============================================================
66
- //
67
- // 1. Install NuGet packages:
68
- //
69
- // dotnet add package Pgvector.EntityFrameworkCore
70
- // dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
71
- //
72
- // 2. Configure NpgsqlDataSource with vector support in Program.cs:
73
- //
74
- // builder.Services.AddNpgsql<AppDbContext>(
75
- // connectionString,
76
- // npgsqlOptions => npgsqlOptions.UseVector());
77
- //
78
- // 3. Register in DbContext:
79
- //
80
- // public DbSet<{{pascalCase FEATURE_NAME}}> {{pascalCase FEATURE_NAME}}s => Set<{{pascalCase FEATURE_NAME}}>();
81
- //
82
- // protected override void OnModelCreating(ModelBuilder modelBuilder)
83
- // {
84
- // modelBuilder.HasPostgresExtension("vector");
85
- // modelBuilder.ApplyConfiguration(new {{pascalCase FEATURE_NAME}}Configuration());
86
- // }
87
- //
88
- // 4. Create and apply migration:
89
- //
90
- // dotnet ef migrations add Add{{pascalCase FEATURE_NAME}}WithVector -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
91
- // dotnet ef database update -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
92
- //
93
- // ============================================================
@@ -5,7 +5,6 @@ namespace {{pascalCase PROJECT_NAME}}.Extensions;
5
5
 
6
6
  public static class ResultExtensions
7
7
  {
8
- // For non-generic Result
9
8
  public static TOut Match<TOut>(
10
9
  this Result result,
11
10
  Func<TOut> onSuccess,
@@ -16,7 +15,6 @@ public static class ResultExtensions
16
15
  : onFailure(result.Error);
17
16
  }
18
17
 
19
- // 🔥 THIS is what your endpoint needs
20
18
  public static TOut Match<TIn, TOut>(
21
19
  this Result<TIn> result,
22
20
  Func<TIn, TOut> onSuccess,
@@ -1,15 +1,11 @@
1
- using FluentValidation;
2
-
3
- namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
4
-
5
- public class {{pascalCase SLICE_NAME}}Validator : AbstractValidator<{{pascalCase SLICE_NAME}}Request>
6
- {
7
- public {{pascalCase SLICE_NAME}}Validator()
8
- {
9
- // TODO: Add validation rules for {{pascalCase SLICE_NAME}}Request properties
10
- // Example:
11
- // RuleFor(c => c.Name)
12
- // .NotEmpty().WithMessage("Name is required")
13
- // .MaximumLength(200).WithMessage("Name must not exceed 200 characters");
14
- }
15
- }
1
+ using FluentValidation;
2
+
3
+ namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
4
+
5
+ public class {{pascalCase SLICE_NAME}}Validator : AbstractValidator<{{pascalCase SLICE_NAME}}Request>
6
+ {
7
+ public {{pascalCase SLICE_NAME}}Validator()
8
+ {
9
+ // TODO: Add validation rules for {{pascalCase SLICE_NAME}}Request properties
10
+ }
11
+ }
@@ -1,8 +1,3 @@
1
- // ============================================================
2
- // MICROSOFT AGENT FRAMEWORK TEMPLATE
3
- // Generated by MORPH Framework
4
- // ============================================================
5
-
6
1
  using System.ComponentModel;
7
2
  using System.Text.Json;
8
3
  using Microsoft.Extensions.AI;
@@ -10,15 +5,10 @@ using Microsoft.Extensions.Logging;
10
5
 
11
6
  namespace {{NAMESPACE}}.Agents.{{pascalCase FEATURE_NAME}};
12
7
 
13
- /// <summary>
14
- /// AI Agent for analyzing {{pascalCase FEATURE_NAME}} data.
15
- /// Uses Microsoft Agent Framework with IChatClient (gpt-4o-mini by default).
16
- /// </summary>
17
8
  public class {{pascalCase FEATURE_NAME}}AnalyzerAgent(
18
9
  IChatClient chatClient,
19
10
  ILogger<{{pascalCase FEATURE_NAME}}AnalyzerAgent> logger) : I{{pascalCase FEATURE_NAME}}AnalyzerAgent
20
11
  {
21
- /// <inheritdoc />
22
12
  public async Task<{{pascalCase FEATURE_NAME}}AnalysisResult> AnalyzeAsync(
23
13
  {{pascalCase FEATURE_NAME}}Data data,
24
14
  CancellationToken cancellationToken = default)
@@ -65,14 +55,12 @@ public class {{pascalCase FEATURE_NAME}}AnalyzerAgent(
65
55
  return result;
66
56
  }
67
57
 
68
- #region Tools
69
-
70
58
  [Description("Gets additional context for the analysis")]
71
59
  private async Task<string> GetContextAsync(
72
60
  [Description("What context is needed")] string query,
73
61
  CancellationToken ct = default)
74
62
  {
75
- // TODO: Implement context retrieval (e.g., from database or search)
63
+ // TODO: buscar o contexto (banco ou busca)
76
64
  await Task.CompletedTask;
77
65
  return $"Context for: {query}";
78
66
  }
@@ -82,19 +70,16 @@ public class {{pascalCase FEATURE_NAME}}AnalyzerAgent(
82
70
  [Description("Metric type to retrieve")] string metricType,
83
71
  CancellationToken ct = default)
84
72
  {
85
- // TODO: Implement metrics retrieval
73
+ // TODO: buscar as métricas
86
74
  await Task.CompletedTask;
87
75
  return $"Metrics for: {metricType}";
88
76
  }
89
77
 
90
- #endregion
91
-
92
- #region Response Parsing
93
-
94
78
  private {{pascalCase FEATURE_NAME}}AnalysisResult ParseResponse(string response)
95
79
  {
96
80
  try
97
81
  {
82
+ // o modelo às vezes cerca o JSON com ```json mesmo instruído a não fazer
98
83
  var json = response
99
84
  .Replace("```json", "")
100
85
  .Replace("```", "")
@@ -126,37 +111,4 @@ public class {{pascalCase FEATURE_NAME}}AnalyzerAgent(
126
111
  public List<string>? Recommendations { get; set; }
127
112
  public double ConfidenceScore { get; set; }
128
113
  }
129
-
130
- #endregion
131
114
  }
132
-
133
- // ============================================================
134
- // DEPENDENCY INJECTION SETUP
135
- // ============================================================
136
- //
137
- // In Program.cs:
138
- //
139
- // // Register IChatClient (Azure OpenAI with Managed Identity)
140
- // builder.Services.AddSingleton<IChatClient>(sp =>
141
- // {
142
- // var cfg = sp.GetRequiredService<IConfiguration>();
143
- // return new AzureOpenAIClient(
144
- // new Uri(cfg["AzureOpenAI:Endpoint"]!),
145
- // new DefaultAzureCredential())
146
- // .GetChatClient(cfg["AzureOpenAI:DeploymentName"] ?? "gpt-4o-mini")
147
- // .AsIChatClient();
148
- // });
149
- //
150
- // // Option A: Register as scoped service
151
- // builder.Services.AddScoped<I{{pascalCase FEATURE_NAME}}AnalyzerAgent, {{pascalCase FEATURE_NAME}}AnalyzerAgent>();
152
- //
153
- // // Option B: Register as keyed agent (recommended for multiple agents)
154
- // builder.AddAIAgent("{{pascalCase FEATURE_NAME}}Analyzer", (sp, key) =>
155
- // {
156
- // var chatClient = sp.GetRequiredService<IChatClient>();
157
- // return new ChatClientAgent(chatClient,
158
- // name: key,
159
- // instructions: "You are an expert {{pascalCase FEATURE_NAME}} analyst.");
160
- // });
161
- //
162
- // ============================================================
@@ -1,8 +1,3 @@
1
- // ============================================================
2
- // HANGFIRE JOB TEMPLATE (VSA Pattern — ApplicationDbContext direto)
3
- // Generated by MORPH Framework
4
- // ============================================================
5
-
6
1
  using Hangfire;
7
2
  using Microsoft.EntityFrameworkCore;
8
3
  using Microsoft.Extensions.Logging;
@@ -10,21 +5,11 @@ using {{pascalCase PROJECT_NAME}}.Database;
10
5
 
11
6
  namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}.Jobs;
12
7
 
13
- /// <summary>
14
- /// Background job for processing {{pascalCase FEATURE_NAME}}.
15
- /// Uses Hangfire for scheduling and retry handling.
16
- /// Injects ApplicationDbContext directly (no service layer, no generic repository).
17
- /// </summary>
18
8
  public class {{pascalCase FEATURE_NAME}}ProcessorJob(
19
9
  ApplicationDbContext db,
20
10
  I{{pascalCase FEATURE_NAME}}AnalyzerAgent analyzer,
21
11
  ILogger<{{pascalCase FEATURE_NAME}}ProcessorJob> logger) : I{{pascalCase FEATURE_NAME}}ProcessorJob
22
12
  {
23
- /// <summary>
24
- /// Executes the {{pascalCase FEATURE_NAME}} processing job.
25
- /// </summary>
26
- /// <param name="id">The {{pascalCase FEATURE_NAME}} ID to process</param>
27
- /// <param name="cancellationToken">Cancellation token</param>
28
13
  [AutomaticRetry(Attempts = 3, DelaysInSeconds = new[] { 60, 300, 900 })]
29
14
  [Queue("default")]
30
15
  [JobDisplayName("{{pascalCase FEATURE_NAME}} Processing - ID: {0}")]
@@ -34,7 +19,6 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
34
19
 
35
20
  try
36
21
  {
37
- // Get the entity directly from the DbSet
38
22
  var entity = await db.Set<{{pascalCase FEATURE_NAME}}>().FindAsync(new object[] { id }, cancellationToken);
39
23
  if (entity is null)
40
24
  {
@@ -42,14 +26,12 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
42
26
  return;
43
27
  }
44
28
 
45
- // Check if already processed
46
29
  if (entity.Status == {{pascalCase FEATURE_NAME}}Status.Completed)
47
30
  {
48
31
  logger.LogInformation("{{pascalCase FEATURE_NAME}} {Id} already completed, skipping", id);
49
32
  return;
50
33
  }
51
34
 
52
- // Perform MAF agent analysis (if applicable)
53
35
  var analysisData = new {{pascalCase FEATURE_NAME}}Data(entity.Name);
54
36
  var analysis = await analyzer.AnalyzeAsync(analysisData, cancellationToken);
55
37
 
@@ -57,7 +39,6 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
57
39
  "{{pascalCase FEATURE_NAME}} {Id} analyzed. Confidence: {Confidence:P0}",
58
40
  id, analysis.ConfidenceScore);
59
41
 
60
- // Update the tracked entity and persist
61
42
  entity.MarkAsCompleted(analysis);
62
43
  await db.SaveChangesAsync(cancellationToken);
63
44
 
@@ -66,54 +47,17 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
66
47
  catch (Exception ex)
67
48
  {
68
49
  logger.LogError(ex, "Failed to process {{pascalCase FEATURE_NAME}} {Id}", id);
69
- throw; // Re-throw to trigger Hangfire retry
50
+ throw; // sem a exceção o Hangfire não aplica o AutomaticRetry
70
51
  }
71
52
  }
72
53
  }
73
54
 
74
- // ============================================================
75
- // RECURRING JOB CONFIGURATION
76
- // ============================================================
77
- //
78
- // For scheduled/recurring jobs, configure in Program.cs:
79
- //
80
- // // Run every hour
81
- // RecurringJob.AddOrUpdate<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
82
- // "{{kebabCase FEATURE_NAME}}-processor",
83
- // job => job.ExecuteAsync(0, CancellationToken.None),
84
- // Cron.Hourly);
85
- //
86
- // // Run daily at midnight
87
- // RecurringJob.AddOrUpdate<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
88
- // "{{kebabCase FEATURE_NAME}}-daily-processor",
89
- // job => job.ExecuteAsync(0, CancellationToken.None),
90
- // Cron.Daily);
91
- //
92
- // // Custom cron expression (every 15 minutes)
93
- // RecurringJob.AddOrUpdate<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
94
- // "{{kebabCase FEATURE_NAME}}-frequent-processor",
95
- // job => job.ExecuteAsync(0, CancellationToken.None),
96
- // "*/15 * * * *");
97
- //
98
- // ============================================================
99
-
100
- // ============================================================
101
- // BATCH JOB TEMPLATE
102
- // ============================================================
103
-
104
- /// <summary>
105
- /// Batch job for processing multiple {{pascalCase FEATURE_NAME}}s.
106
- /// Queries pending items via LINQ on the DbSet and enqueues individual jobs.
107
- /// </summary>
108
55
  public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
109
56
  ApplicationDbContext db,
110
57
  ILogger<{{pascalCase FEATURE_NAME}}BatchProcessorJob> logger)
111
58
  {
112
- /// <summary>
113
- /// Processes all pending {{pascalCase FEATURE_NAME}}s.
114
- /// </summary>
115
59
  [AutomaticRetry(Attempts = 1)]
116
- [Queue("batch")]
60
+ [Queue("batch")] // a fila precisa constar em AddHangfireServer(o => o.Queues), senão ninguém a consome
117
61
  [JobDisplayName("{{pascalCase FEATURE_NAME}} Batch Processing")]
118
62
  public async Task ProcessAllPendingAsync(CancellationToken cancellationToken)
119
63
  {
@@ -127,7 +71,6 @@ public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
127
71
 
128
72
  foreach (var item in pending)
129
73
  {
130
- // Enqueue individual processing jobs
131
74
  BackgroundJob.Enqueue<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
132
75
  job => job.ExecuteAsync(item.Id, CancellationToken.None));
133
76
  }
@@ -135,41 +78,3 @@ public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
135
78
  logger.LogInformation("Enqueued {Count} processing jobs", pending.Count);
136
79
  }
137
80
  }
138
-
139
- // ============================================================
140
- // HANGFIRE CONFIGURATION
141
- // ============================================================
142
- //
143
- // In Program.cs:
144
- //
145
- // // Add Hangfire services
146
- // builder.Services.AddHangfire(config => config
147
- // .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
148
- // .UseSimpleAssemblyNameTypeSerializer()
149
- // .UseRecommendedSerializerSettings()
150
- // .UseSqlServerStorage(connectionString, new SqlServerStorageOptions
151
- // {
152
- // CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
153
- // SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
154
- // QueuePollInterval = TimeSpan.Zero,
155
- // UseRecommendedIsolationLevel = true,
156
- // DisableGlobalLocks = true
157
- // }));
158
- //
159
- // builder.Services.AddHangfireServer(options =>
160
- // {
161
- // options.Queues = new[] { "default", "batch" };
162
- // options.WorkerCount = Environment.ProcessorCount * 2;
163
- // });
164
- //
165
- // // Register jobs (ApplicationDbContext already registered via AddDbContext)
166
- // builder.Services.AddScoped<I{{pascalCase FEATURE_NAME}}ProcessorJob, {{pascalCase FEATURE_NAME}}ProcessorJob>();
167
- // builder.Services.AddScoped<{{pascalCase FEATURE_NAME}}BatchProcessorJob>();
168
- //
169
- // // In app pipeline
170
- // app.UseHangfireDashboard("/hangfire", new DashboardOptions
171
- // {
172
- // Authorization = new[] { new HangfireAuthorizationFilter() }
173
- // });
174
- //
175
- // ============================================================