@polymorphism-tech/morph-spec 3.0.0 → 3.1.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 (240) hide show
  1. package/CLAUDE.md +68 -400
  2. package/README.md +198 -76
  3. package/bin/detect-agents.js +227 -225
  4. package/bin/morph-spec.js +10 -0
  5. package/bin/render-template.js +303 -302
  6. package/bin/semantic-detect-agents.js +247 -246
  7. package/bin/{task-manager.js → task-manager.cjs} +12 -1
  8. package/bin/validate-agents-skills.js +257 -251
  9. package/bin/validate-agents.js +70 -69
  10. package/bin/validate-phase.js +263 -263
  11. package/docs/getting-started.md +3 -3
  12. package/package.json +3 -4
  13. package/scripts/reorganize-skills.cjs +175 -0
  14. package/scripts/validate-agents-structure.cjs +52 -0
  15. package/scripts/validate-skills.cjs +180 -0
  16. package/src/commands/create-story.js +354 -351
  17. package/src/commands/detect-agents.js +13 -2
  18. package/src/commands/detect.js +104 -104
  19. package/src/commands/state.js +334 -333
  20. package/src/commands/sync.js +167 -167
  21. package/src/commands/task.js +1 -1
  22. package/src/commands/update.js +13 -1
  23. package/src/lib/context-generator.js +7 -4
  24. package/{detectors → src/lib/detectors}/config-detector.js +223 -223
  25. package/{detectors → src/lib/detectors}/conversation-analyzer.js +163 -163
  26. package/{detectors → src/lib/detectors}/index.js +84 -84
  27. package/{detectors → src/lib/detectors}/standards-generator.js +275 -275
  28. package/src/lib/hook-executor.js +2 -1
  29. package/src/lib/stack-resolver.js +148 -0
  30. package/src/lib/standards-context-injector.js +4 -3
  31. package/src/lib/state-manager.js +21 -4
  32. package/src/lib/team-orchestrator.js +2 -1
  33. package/src/lib/troubleshoot-grep.js +13 -3
  34. package/src/lib/validation-runner.js +2 -1
  35. package/src/utils/file-copier.js +3 -1
  36. package/{content → stacks/blazor-azure}/.azure/README.md +293 -293
  37. package/{content → stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +454 -454
  38. package/{content → stacks/blazor-azure}/.azure/docs/branch-strategy.md +398 -398
  39. package/{content → stacks/blazor-azure}/.azure/docs/local-development.md +515 -515
  40. package/{content → stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +34 -34
  41. package/{content → stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +319 -319
  42. package/{content → stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +234 -234
  43. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +75 -75
  44. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +94 -94
  45. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +120 -120
  46. package/{content → stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +90 -90
  47. package/{content → stacks/blazor-azure}/.claude/commands/morph-archive.md +79 -79
  48. package/{content → stacks/blazor-azure}/.claude/commands/morph-deploy.md +529 -529
  49. package/{content → stacks/blazor-azure}/.claude/commands/morph-infra.md +209 -209
  50. package/{content → stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +1 -1
  51. package/{content → stacks/blazor-azure}/.claude/settings.local.json +15 -15
  52. package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
  53. package/{content/.claude/skills/specialists → stacks/blazor-azure/.claude/skills/level-2-domains/architecture}/prompt-engineer.md +189 -189
  54. package/{content/.claude/skills/specialists → stacks/blazor-azure/.claude/skills/level-2-domains/architecture}/seo-growth-hacker.md +320 -320
  55. package/{content/.claude/skills/infra → stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure}/azure-deploy-specialist.md +699 -699
  56. package/{content → stacks/blazor-azure}/.morph/.morphversion +5 -5
  57. package/{content → stacks/blazor-azure}/.morph/archive/.gitkeep +25 -25
  58. package/{content → stacks/blazor-azure}/.morph/config/agents.json +7 -5
  59. package/{content → stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
  60. package/{content → stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
  61. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +241 -241
  62. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +307 -307
  63. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +399 -399
  64. package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +168 -168
  65. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/README.md +125 -125
  66. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +358 -358
  67. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +246 -246
  68. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +236 -236
  69. package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +150 -150
  70. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/README.md +309 -309
  71. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +433 -433
  72. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +479 -479
  73. package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +185 -185
  74. package/{content → stacks/blazor-azure}/.morph/examples/state-v3.json +188 -188
  75. package/{content → stacks/blazor-azure}/.morph/features/.gitkeep +25 -25
  76. package/{content → stacks/blazor-azure}/.morph/hooks/README.md +12 -12
  77. package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +48 -48
  78. package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +49 -49
  79. package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +60 -60
  80. package/{content → stacks/blazor-azure}/.morph/project.md +160 -160
  81. package/{content → stacks/blazor-azure}/.morph/schemas/agent.schema.json +296 -296
  82. package/{content → stacks/blazor-azure}/.morph/specs/.gitkeep +20 -20
  83. package/{content → stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
  84. package/{content → stacks/blazor-azure}/.morph/standards/coding.md +377 -377
  85. package/{content → stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +590 -590
  86. package/{content → stacks/blazor-azure}/.morph/standards/migration-guide.md +514 -514
  87. package/{content → stacks/blazor-azure}/.morph/standards/passkeys-auth.md +423 -423
  88. package/{content → stacks/blazor-azure}/.morph/standards/vector-search-rag.md +536 -536
  89. package/{content → stacks/blazor-azure}/.morph/state.json +17 -17
  90. package/{content → stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +149 -149
  91. package/{content → stacks/blazor-azure}/.morph/templates/MudTheme.cs +281 -281
  92. package/{content → stacks/blazor-azure}/.morph/templates/component.razor +239 -239
  93. package/{content → stacks/blazor-azure}/.morph/templates/contracts.cs +217 -217
  94. package/{content → stacks/blazor-azure}/.morph/templates/design-system.css +226 -226
  95. package/{content → stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +89 -89
  96. package/{content → stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +82 -82
  97. package/{content → stacks/blazor-azure}/.morph/templates/infra/README.md +286 -286
  98. package/{content → stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +63 -63
  99. package/{content → stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +164 -164
  100. package/{content → stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +480 -480
  101. package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +49 -49
  102. package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +156 -156
  103. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +229 -229
  104. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.sh +208 -208
  105. package/{content → stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +91 -91
  106. package/{content → stacks/blazor-azure}/.morph/templates/infra/main.bicep +189 -189
  107. package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +29 -29
  108. package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +29 -29
  109. package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +29 -29
  110. package/{content → stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +103 -103
  111. package/{content → stacks/blazor-azure}/.morph/templates/infra/storage.bicep +106 -106
  112. package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +387 -387
  113. package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +351 -351
  114. package/{content → stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +288 -288
  115. package/{content → stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +258 -258
  116. package/{content → stacks/blazor-azure}/.morph/templates/job.cs +171 -171
  117. package/{content → stacks/blazor-azure}/.morph/templates/migration.cs +83 -83
  118. package/{content → stacks/blazor-azure}/.morph/templates/repository.cs +141 -141
  119. package/{content → stacks/blazor-azure}/.morph/templates/saas/subscription.cs +347 -347
  120. package/{content → stacks/blazor-azure}/.morph/templates/saas/tenant.cs +338 -338
  121. package/{content → stacks/blazor-azure}/.morph/templates/service.cs +139 -139
  122. package/{content → stacks/blazor-azure}/.morph/templates/sprint-status.yaml +68 -68
  123. package/{content → stacks/blazor-azure}/.morph/templates/story.md +143 -143
  124. package/{content → stacks/blazor-azure}/.morph/templates/test.cs +239 -239
  125. package/{content → stacks/blazor-azure}/.morph/templates/ui-design-system.md +286 -286
  126. package/{content → stacks/blazor-azure}/.morph/templates/ui-flows.md +336 -336
  127. package/{content → stacks/blazor-azure}/.morph/templates/ui-mockups.md +133 -133
  128. package/{content → stacks/blazor-azure}/.morph/test-infra/example.bicep +59 -59
  129. package/{content → stacks/blazor-azure}/README.md +79 -79
  130. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
  131. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
  132. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
  133. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
  134. package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
  135. package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
  136. package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
  137. package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
  138. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
  139. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
  140. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
  141. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
  142. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
  143. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
  144. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
  145. package/stacks/nextjs-supabase/.morph/project.md +168 -0
  146. package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
  147. package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
  148. package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
  149. package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
  150. package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
  151. package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
  152. package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
  153. package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
  154. package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
  155. package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
  156. package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
  157. package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
  158. package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
  159. package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
  160. package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
  161. package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
  162. package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
  163. package/stacks/nextjs-supabase/CLAUDE.md +149 -0
  164. package/stacks/nextjs-supabase/README.md +112 -0
  165. /package/{detectors → src/lib/detectors}/structure-detector.js +0 -0
  166. /package/{content → stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
  167. /package/{content → stacks/blazor-azure}/.claude/commands/morph-preflight.md +0 -0
  168. /package/{content → stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
  169. /package/{content → stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
  170. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
  171. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
  172. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
  173. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
  174. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
  175. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
  176. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
  177. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
  178. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
  179. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
  180. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
  181. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
  182. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
  183. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
  184. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
  185. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
  186. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
  187. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
  188. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
  189. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
  190. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
  191. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
  192. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
  193. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
  194. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
  195. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
  196. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
  197. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
  198. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
  199. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
  200. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
  201. /package/{content → stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
  202. /package/{content → stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
  203. /package/{content → stacks/blazor-azure}/.morph/config/config.template.json +0 -0
  204. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
  205. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
  206. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
  207. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
  208. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
  209. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
  210. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
  211. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
  212. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
  213. /package/{content → stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
  214. /package/{content → stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
  215. /package/{content → stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
  216. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
  217. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
  218. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
  219. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
  220. /package/{content → stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
  221. /package/{content → stacks/blazor-azure}/.morph/standards/azure.md +0 -0
  222. /package/{content → stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
  223. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
  224. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
  225. /package/{content → stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
  226. /package/{content → stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
  227. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
  228. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
  229. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
  230. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
  231. /package/{content → stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
  232. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +0 -0
  233. /package/{content → stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
  234. /package/{content → stacks/blazor-azure}/.morph/templates/recap.md +0 -0
  235. /package/{content → stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
  236. /package/{content → stacks/blazor-azure}/.morph/templates/spec.md +0 -0
  237. /package/{content → stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
  238. /package/{content → stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
  239. /package/{content → stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
  240. /package/{content → stacks/blazor-azure}/CLAUDE.md +0 -0
@@ -1,377 +1,377 @@
1
- # Padrões de Código - MORPH Framework
2
-
3
- ## 📝 Nomenclatura
4
-
5
- ### Classes e Interfaces
6
- ```csharp
7
- // Interfaces: sempre com prefixo I
8
- public interface IReportService { }
9
- public interface IReportRepository { }
10
-
11
- // Classes: PascalCase, sufixo indica tipo
12
- public class ReportService : IReportService { }
13
- public class ReportRepository : IReportRepository { }
14
- public class ReportController : ControllerBase { }
15
- public class ReportGeneratorJob { } // Hangfire job
16
- public class ReportAnalyzerAgent { } // AI Agent
17
- ```
18
-
19
- ### Métodos
20
- ```csharp
21
- // Async sempre com sufixo Async
22
- public async Task<Report> GetByIdAsync(int id) { }
23
- public async Task CreateAsync(Report report) { }
24
-
25
- // Métodos síncronos sem sufixo
26
- public Report GetById(int id) { }
27
- public void Validate(Report report) { }
28
- ```
29
-
30
- ### Variáveis e Parâmetros
31
- ```csharp
32
- // camelCase para variáveis locais e parâmetros
33
- public async Task ProcessAsync(string reportId, CancellationToken cancellationToken)
34
- {
35
- var report = await _repository.GetByIdAsync(reportId);
36
- var analysisResult = await _analyzer.AnalyzeAsync(report);
37
- }
38
-
39
- // _camelCase para campos privados
40
- private readonly IReportRepository _repository;
41
- private readonly ILogger<ReportService> _logger;
42
- ```
43
-
44
- ---
45
-
46
- ## 📁 Estrutura de Projeto
47
-
48
- ```
49
- src/
50
- ├── MyProject.Web/ # Blazor Server
51
- │ ├── Components/
52
- │ │ ├── Pages/ # Páginas (rotas)
53
- │ │ ├── Shared/ # Componentes compartilhados
54
- │ │ └── Layout/ # Layouts
55
- │ └── Program.cs
56
-
57
- ├── MyProject.Application/ # Casos de uso
58
- │ ├── Features/
59
- │ │ └── Reports/
60
- │ │ ├── Commands/
61
- │ │ ├── Queries/
62
- │ │ └── Services/
63
- │ └── Common/
64
-
65
- ├── MyProject.Domain/ # Entidades e regras
66
- │ ├── Entities/
67
- │ ├── ValueObjects/
68
- │ └── Enums/
69
-
70
- ├── MyProject.Infrastructure/ # Implementações
71
- │ ├── Data/
72
- │ │ ├── Configurations/
73
- │ │ ├── Migrations/
74
- │ │ └── AppDbContext.cs
75
- │ └── Services/
76
-
77
- └── MyProject.Agents/ # MS Agent Framework
78
- └── ReportAnalyzer/
79
- ```
80
-
81
- ---
82
-
83
- ## 💉 Dependency Injection
84
-
85
- ```csharp
86
- // Usar primary constructor (C# 12+)
87
- public class ReportService(
88
- IReportRepository repository,
89
- ILogger<ReportService> logger) : IReportService
90
- {
91
- public async Task<Report> GetByIdAsync(int id)
92
- {
93
- logger.LogInformation("Getting report {ReportId}", id);
94
- return await repository.GetByIdAsync(id);
95
- }
96
- }
97
- ```
98
-
99
- ---
100
-
101
- ## 🗄️ Entity Framework Core
102
-
103
- ### Entidades
104
- ```csharp
105
- public class ReportSchedule
106
- {
107
- public int Id { get; private set; }
108
- public string Name { get; private set; } = string.Empty;
109
- public ReportType ReportType { get; private set; }
110
- public string CronExpression { get; private set; } = string.Empty;
111
- public List<string> Recipients { get; private set; } = [];
112
- public bool IsActive { get; private set; }
113
- public DateTime CreatedAt { get; private set; }
114
-
115
- // Factory method para criação
116
- public static ReportSchedule Create(string name, ReportType reportType,
117
- string cronExpression, List<string> recipients)
118
- {
119
- return new ReportSchedule
120
- {
121
- Name = name,
122
- ReportType = reportType,
123
- CronExpression = cronExpression,
124
- Recipients = recipients,
125
- IsActive = true,
126
- CreatedAt = DateTime.UtcNow
127
- };
128
- }
129
-
130
- // Métodos de domínio
131
- public void Activate() => IsActive = true;
132
- public void Deactivate() => IsActive = false;
133
- }
134
- ```
135
-
136
- ### Configuração Fluent API
137
- ```csharp
138
- public class ReportScheduleConfiguration : IEntityTypeConfiguration<ReportSchedule>
139
- {
140
- public void Configure(EntityTypeBuilder<ReportSchedule> builder)
141
- {
142
- builder.ToTable("ReportSchedules");
143
- builder.HasKey(x => x.Id);
144
-
145
- builder.Property(x => x.Name)
146
- .IsRequired()
147
- .HasMaxLength(200);
148
-
149
- // JSON column para lista
150
- builder.Property(x => x.Recipients)
151
- .HasConversion(
152
- v => JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
153
- v => JsonSerializer.Deserialize<List<string>>(v, (JsonSerializerOptions?)null) ?? [])
154
- .HasColumnType("nvarchar(max)");
155
- }
156
- }
157
- ```
158
-
159
- ---
160
-
161
- ## 🔥 Componentes Blazor
162
-
163
- ```razor
164
- @page "/reports/schedules"
165
- @attribute [Authorize(Policy = "CanManageReports")]
166
- @inject IReportScheduleService ReportService
167
- @inject ILogger<ReportScheduleList> Logger
168
-
169
- <PageTitle>Report Schedules</PageTitle>
170
-
171
- @if (_isLoading)
172
- {
173
- <LoadingSpinner />
174
- }
175
- else if (_schedules is null || !_schedules.Any())
176
- {
177
- <EmptyState Message="No schedules configured" />
178
- }
179
- else
180
- {
181
- <div class="schedule-list">
182
- @foreach (var schedule in _schedules)
183
- {
184
- <ScheduleCard Schedule="schedule" OnToggle="HandleToggleAsync" />
185
- }
186
- </div>
187
- }
188
-
189
- @code {
190
- private List<ReportScheduleDto>? _schedules;
191
- private bool _isLoading = true;
192
-
193
- protected override async Task OnInitializedAsync()
194
- {
195
- try
196
- {
197
- _schedules = await ReportService.GetAllAsync();
198
- }
199
- catch (Exception ex)
200
- {
201
- Logger.LogError(ex, "Failed to load schedules");
202
- }
203
- finally
204
- {
205
- _isLoading = false;
206
- }
207
- }
208
- }
209
- ```
210
-
211
- ### Padrões Obrigatórios
212
- - ✅ Loading state em toda página
213
- - ✅ Empty state quando lista vazia
214
- - ✅ Error handling com try/catch
215
- - ✅ `@inject` para DI (não construtor)
216
- - ✅ `@attribute [Authorize]` quando necessário
217
-
218
- ---
219
-
220
- ## 🤖 AI Agents - Padrão Obrigatório (.NET 10)
221
-
222
- > **CRÍTICO:** Use **exclusivamente** Microsoft Agent Framework.
223
- > Semantic Kernel foi descontinuado no MORPH-SPEC.
224
-
225
- ### Pattern Obrigatório
226
-
227
- ```csharp
228
- using Microsoft.Agents.AI;
229
- using Microsoft.Extensions.AI;
230
-
231
- public class ReportAnalyzerAgent(
232
- IChatClient chatClient,
233
- ILogger<ReportAnalyzerAgent> logger) : IReportAnalyzerAgent
234
- {
235
- public async Task<AnalysisResult> AnalyzeAsync(
236
- ReportData reportData,
237
- CancellationToken cancellationToken = default)
238
- {
239
- var agent = chatClient.CreateAgent(
240
- instructions: """
241
- Você é um especialista em análise de relatórios.
242
- Analise os dados fornecidos e retorne em JSON:
243
- {
244
- "summary": "resumo",
245
- "insights": ["top 3 insights"],
246
- "recommendations": ["recomendações"]
247
- }
248
- """,
249
- name: "ReportAnalyzer"
250
- );
251
-
252
- var prompt = $"Analise este relatório:\n{reportData.ToJson()}";
253
-
254
- try
255
- {
256
- var response = await agent.RunAsync(prompt, cancellationToken: cancellationToken);
257
- return ParseResponse(response.Content);
258
- }
259
- catch (Exception ex)
260
- {
261
- logger.LogError(ex, "Analysis failed for report {ReportId}", reportData.Id);
262
- throw new ReportAnalysisException("Failed to analyze", ex);
263
- }
264
- }
265
- }
266
- ```
267
-
268
- ### Configuração (Program.cs)
269
-
270
- ```csharp
271
- // Registrar ChatClient
272
- builder.Services.AddSingleton<IChatClient>(sp =>
273
- {
274
- var config = sp.GetRequiredService<IConfiguration>();
275
- return new ChatClient(
276
- model: "gpt-4o-mini",
277
- credential: new ApiKeyCredential(config["AzureOpenAI:ApiKey"]!),
278
- endpoint: new Uri(config["AzureOpenAI:Endpoint"]!)
279
- );
280
- });
281
-
282
- // Registrar agent
283
- builder.Services.AddScoped<IReportAnalyzerAgent, ReportAnalyzerAgent>();
284
- ```
285
-
286
- **Referência:** [Agent Framework Setup](./agent-framework-setup.md)
287
-
288
- ---
289
-
290
- ## ⏰ Hangfire Jobs
291
-
292
- ```csharp
293
- public class ReportGeneratorJob(
294
- IReportScheduleService scheduleService,
295
- IReportAnalyzerAgent analyzer,
296
- ILogger<ReportGeneratorJob> logger) : IReportGeneratorJob
297
- {
298
- [AutomaticRetry(Attempts = 3, DelaysInSeconds = new[] { 60, 300, 900 })]
299
- [Queue("reports")]
300
- public async Task ExecuteAsync(int scheduleId, CancellationToken cancellationToken)
301
- {
302
- logger.LogInformation("Starting report generation for {ScheduleId}", scheduleId);
303
-
304
- var schedule = await scheduleService.GetByIdAsync(scheduleId);
305
- if (schedule is null || !schedule.IsActive)
306
- {
307
- logger.LogWarning("Schedule {ScheduleId} not found or inactive", scheduleId);
308
- return;
309
- }
310
-
311
- // ... implementação
312
- }
313
- }
314
- ```
315
-
316
- ---
317
-
318
- ## 🧪 Testes
319
-
320
- ### Nomenclatura
321
- ```csharp
322
- // Classe: {ClasseTestada}Tests
323
- public class ReportServiceTests
324
- {
325
- // Método: {Método}_{Cenário}_{ResultadoEsperado}
326
- [Fact]
327
- public async Task GetByIdAsync_WithValidId_ReturnsReport() { }
328
-
329
- [Fact]
330
- public async Task GetByIdAsync_WithInvalidId_ThrowsNotFoundException() { }
331
- }
332
- ```
333
-
334
- ### Estrutura AAA
335
- ```csharp
336
- [Fact]
337
- public async Task CreateAsync_WithValidData_CreatesSchedule()
338
- {
339
- // Arrange
340
- var request = new CreateReportScheduleRequest("Daily Sales", ReportType.Sales);
341
-
342
- // Act
343
- var result = await _service.CreateAsync(request);
344
-
345
- // Assert
346
- Assert.NotNull(result);
347
- Assert.Equal(request.Name, result.Name);
348
- }
349
- ```
350
-
351
- ---
352
-
353
- ## 🚫 Anti-Patterns a Evitar
354
-
355
- ```csharp
356
- // ❌ Service Locator
357
- var service = serviceProvider.GetService<IReportService>();
358
-
359
- // ✅ Constructor Injection
360
- public class MyClass(IReportService reportService) { }
361
-
362
- // ❌ Async void
363
- public async void ProcessReport() { }
364
-
365
- // ✅ Async Task
366
- public async Task ProcessReportAsync() { }
367
-
368
- // ❌ Catching generic Exception sem log
369
- catch (Exception) { }
370
-
371
- // ✅ Log and handle
372
- catch (Exception ex)
373
- {
374
- _logger.LogError(ex, "Operation failed");
375
- throw;
376
- }
377
- ```
1
+ # Padrões de Código - MORPH Framework
2
+
3
+ ## 📝 Nomenclatura
4
+
5
+ ### Classes e Interfaces
6
+ ```csharp
7
+ // Interfaces: sempre com prefixo I
8
+ public interface IReportService { }
9
+ public interface IReportRepository { }
10
+
11
+ // Classes: PascalCase, sufixo indica tipo
12
+ public class ReportService : IReportService { }
13
+ public class ReportRepository : IReportRepository { }
14
+ public class ReportController : ControllerBase { }
15
+ public class ReportGeneratorJob { } // Hangfire job
16
+ public class ReportAnalyzerAgent { } // AI Agent
17
+ ```
18
+
19
+ ### Métodos
20
+ ```csharp
21
+ // Async sempre com sufixo Async
22
+ public async Task<Report> GetByIdAsync(int id) { }
23
+ public async Task CreateAsync(Report report) { }
24
+
25
+ // Métodos síncronos sem sufixo
26
+ public Report GetById(int id) { }
27
+ public void Validate(Report report) { }
28
+ ```
29
+
30
+ ### Variáveis e Parâmetros
31
+ ```csharp
32
+ // camelCase para variáveis locais e parâmetros
33
+ public async Task ProcessAsync(string reportId, CancellationToken cancellationToken)
34
+ {
35
+ var report = await _repository.GetByIdAsync(reportId);
36
+ var analysisResult = await _analyzer.AnalyzeAsync(report);
37
+ }
38
+
39
+ // _camelCase para campos privados
40
+ private readonly IReportRepository _repository;
41
+ private readonly ILogger<ReportService> _logger;
42
+ ```
43
+
44
+ ---
45
+
46
+ ## 📁 Estrutura de Projeto
47
+
48
+ ```
49
+ src/
50
+ ├── MyProject.Web/ # Blazor Server
51
+ │ ├── Components/
52
+ │ │ ├── Pages/ # Páginas (rotas)
53
+ │ │ ├── Shared/ # Componentes compartilhados
54
+ │ │ └── Layout/ # Layouts
55
+ │ └── Program.cs
56
+
57
+ ├── MyProject.Application/ # Casos de uso
58
+ │ ├── Features/
59
+ │ │ └── Reports/
60
+ │ │ ├── Commands/
61
+ │ │ ├── Queries/
62
+ │ │ └── Services/
63
+ │ └── Common/
64
+
65
+ ├── MyProject.Domain/ # Entidades e regras
66
+ │ ├── Entities/
67
+ │ ├── ValueObjects/
68
+ │ └── Enums/
69
+
70
+ ├── MyProject.Infrastructure/ # Implementações
71
+ │ ├── Data/
72
+ │ │ ├── Configurations/
73
+ │ │ ├── Migrations/
74
+ │ │ └── AppDbContext.cs
75
+ │ └── Services/
76
+
77
+ └── MyProject.Agents/ # MS Agent Framework
78
+ └── ReportAnalyzer/
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 💉 Dependency Injection
84
+
85
+ ```csharp
86
+ // Usar primary constructor (C# 12+)
87
+ public class ReportService(
88
+ IReportRepository repository,
89
+ ILogger<ReportService> logger) : IReportService
90
+ {
91
+ public async Task<Report> GetByIdAsync(int id)
92
+ {
93
+ logger.LogInformation("Getting report {ReportId}", id);
94
+ return await repository.GetByIdAsync(id);
95
+ }
96
+ }
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 🗄️ Entity Framework Core
102
+
103
+ ### Entidades
104
+ ```csharp
105
+ public class ReportSchedule
106
+ {
107
+ public int Id { get; private set; }
108
+ public string Name { get; private set; } = string.Empty;
109
+ public ReportType ReportType { get; private set; }
110
+ public string CronExpression { get; private set; } = string.Empty;
111
+ public List<string> Recipients { get; private set; } = [];
112
+ public bool IsActive { get; private set; }
113
+ public DateTime CreatedAt { get; private set; }
114
+
115
+ // Factory method para criação
116
+ public static ReportSchedule Create(string name, ReportType reportType,
117
+ string cronExpression, List<string> recipients)
118
+ {
119
+ return new ReportSchedule
120
+ {
121
+ Name = name,
122
+ ReportType = reportType,
123
+ CronExpression = cronExpression,
124
+ Recipients = recipients,
125
+ IsActive = true,
126
+ CreatedAt = DateTime.UtcNow
127
+ };
128
+ }
129
+
130
+ // Métodos de domínio
131
+ public void Activate() => IsActive = true;
132
+ public void Deactivate() => IsActive = false;
133
+ }
134
+ ```
135
+
136
+ ### Configuração Fluent API
137
+ ```csharp
138
+ public class ReportScheduleConfiguration : IEntityTypeConfiguration<ReportSchedule>
139
+ {
140
+ public void Configure(EntityTypeBuilder<ReportSchedule> builder)
141
+ {
142
+ builder.ToTable("ReportSchedules");
143
+ builder.HasKey(x => x.Id);
144
+
145
+ builder.Property(x => x.Name)
146
+ .IsRequired()
147
+ .HasMaxLength(200);
148
+
149
+ // JSON column para lista
150
+ builder.Property(x => x.Recipients)
151
+ .HasConversion(
152
+ v => JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
153
+ v => JsonSerializer.Deserialize<List<string>>(v, (JsonSerializerOptions?)null) ?? [])
154
+ .HasColumnType("nvarchar(max)");
155
+ }
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## 🔥 Componentes Blazor
162
+
163
+ ```razor
164
+ @page "/reports/schedules"
165
+ @attribute [Authorize(Policy = "CanManageReports")]
166
+ @inject IReportScheduleService ReportService
167
+ @inject ILogger<ReportScheduleList> Logger
168
+
169
+ <PageTitle>Report Schedules</PageTitle>
170
+
171
+ @if (_isLoading)
172
+ {
173
+ <LoadingSpinner />
174
+ }
175
+ else if (_schedules is null || !_schedules.Any())
176
+ {
177
+ <EmptyState Message="No schedules configured" />
178
+ }
179
+ else
180
+ {
181
+ <div class="schedule-list">
182
+ @foreach (var schedule in _schedules)
183
+ {
184
+ <ScheduleCard Schedule="schedule" OnToggle="HandleToggleAsync" />
185
+ }
186
+ </div>
187
+ }
188
+
189
+ @code {
190
+ private List<ReportScheduleDto>? _schedules;
191
+ private bool _isLoading = true;
192
+
193
+ protected override async Task OnInitializedAsync()
194
+ {
195
+ try
196
+ {
197
+ _schedules = await ReportService.GetAllAsync();
198
+ }
199
+ catch (Exception ex)
200
+ {
201
+ Logger.LogError(ex, "Failed to load schedules");
202
+ }
203
+ finally
204
+ {
205
+ _isLoading = false;
206
+ }
207
+ }
208
+ }
209
+ ```
210
+
211
+ ### Padrões Obrigatórios
212
+ - ✅ Loading state em toda página
213
+ - ✅ Empty state quando lista vazia
214
+ - ✅ Error handling com try/catch
215
+ - ✅ `@inject` para DI (não construtor)
216
+ - ✅ `@attribute [Authorize]` quando necessário
217
+
218
+ ---
219
+
220
+ ## 🤖 AI Agents - Padrão Obrigatório (.NET 10)
221
+
222
+ > **CRÍTICO:** Use **exclusivamente** Microsoft Agent Framework.
223
+ > Semantic Kernel foi descontinuado no MORPH-SPEC.
224
+
225
+ ### Pattern Obrigatório
226
+
227
+ ```csharp
228
+ using Microsoft.Agents.AI;
229
+ using Microsoft.Extensions.AI;
230
+
231
+ public class ReportAnalyzerAgent(
232
+ IChatClient chatClient,
233
+ ILogger<ReportAnalyzerAgent> logger) : IReportAnalyzerAgent
234
+ {
235
+ public async Task<AnalysisResult> AnalyzeAsync(
236
+ ReportData reportData,
237
+ CancellationToken cancellationToken = default)
238
+ {
239
+ var agent = chatClient.CreateAgent(
240
+ instructions: """
241
+ Você é um especialista em análise de relatórios.
242
+ Analise os dados fornecidos e retorne em JSON:
243
+ {
244
+ "summary": "resumo",
245
+ "insights": ["top 3 insights"],
246
+ "recommendations": ["recomendações"]
247
+ }
248
+ """,
249
+ name: "ReportAnalyzer"
250
+ );
251
+
252
+ var prompt = $"Analise este relatório:\n{reportData.ToJson()}";
253
+
254
+ try
255
+ {
256
+ var response = await agent.RunAsync(prompt, cancellationToken: cancellationToken);
257
+ return ParseResponse(response.Content);
258
+ }
259
+ catch (Exception ex)
260
+ {
261
+ logger.LogError(ex, "Analysis failed for report {ReportId}", reportData.Id);
262
+ throw new ReportAnalysisException("Failed to analyze", ex);
263
+ }
264
+ }
265
+ }
266
+ ```
267
+
268
+ ### Configuração (Program.cs)
269
+
270
+ ```csharp
271
+ // Registrar ChatClient
272
+ builder.Services.AddSingleton<IChatClient>(sp =>
273
+ {
274
+ var config = sp.GetRequiredService<IConfiguration>();
275
+ return new ChatClient(
276
+ model: "gpt-4o-mini",
277
+ credential: new ApiKeyCredential(config["AzureOpenAI:ApiKey"]!),
278
+ endpoint: new Uri(config["AzureOpenAI:Endpoint"]!)
279
+ );
280
+ });
281
+
282
+ // Registrar agent
283
+ builder.Services.AddScoped<IReportAnalyzerAgent, ReportAnalyzerAgent>();
284
+ ```
285
+
286
+ **Referência:** [Agent Framework Setup](./agent-framework-setup.md)
287
+
288
+ ---
289
+
290
+ ## ⏰ Hangfire Jobs
291
+
292
+ ```csharp
293
+ public class ReportGeneratorJob(
294
+ IReportScheduleService scheduleService,
295
+ IReportAnalyzerAgent analyzer,
296
+ ILogger<ReportGeneratorJob> logger) : IReportGeneratorJob
297
+ {
298
+ [AutomaticRetry(Attempts = 3, DelaysInSeconds = new[] { 60, 300, 900 })]
299
+ [Queue("reports")]
300
+ public async Task ExecuteAsync(int scheduleId, CancellationToken cancellationToken)
301
+ {
302
+ logger.LogInformation("Starting report generation for {ScheduleId}", scheduleId);
303
+
304
+ var schedule = await scheduleService.GetByIdAsync(scheduleId);
305
+ if (schedule is null || !schedule.IsActive)
306
+ {
307
+ logger.LogWarning("Schedule {ScheduleId} not found or inactive", scheduleId);
308
+ return;
309
+ }
310
+
311
+ // ... implementação
312
+ }
313
+ }
314
+ ```
315
+
316
+ ---
317
+
318
+ ## 🧪 Testes
319
+
320
+ ### Nomenclatura
321
+ ```csharp
322
+ // Classe: {ClasseTestada}Tests
323
+ public class ReportServiceTests
324
+ {
325
+ // Método: {Método}_{Cenário}_{ResultadoEsperado}
326
+ [Fact]
327
+ public async Task GetByIdAsync_WithValidId_ReturnsReport() { }
328
+
329
+ [Fact]
330
+ public async Task GetByIdAsync_WithInvalidId_ThrowsNotFoundException() { }
331
+ }
332
+ ```
333
+
334
+ ### Estrutura AAA
335
+ ```csharp
336
+ [Fact]
337
+ public async Task CreateAsync_WithValidData_CreatesSchedule()
338
+ {
339
+ // Arrange
340
+ var request = new CreateReportScheduleRequest("Daily Sales", ReportType.Sales);
341
+
342
+ // Act
343
+ var result = await _service.CreateAsync(request);
344
+
345
+ // Assert
346
+ Assert.NotNull(result);
347
+ Assert.Equal(request.Name, result.Name);
348
+ }
349
+ ```
350
+
351
+ ---
352
+
353
+ ## 🚫 Anti-Patterns a Evitar
354
+
355
+ ```csharp
356
+ // ❌ Service Locator
357
+ var service = serviceProvider.GetService<IReportService>();
358
+
359
+ // ✅ Constructor Injection
360
+ public class MyClass(IReportService reportService) { }
361
+
362
+ // ❌ Async void
363
+ public async void ProcessReport() { }
364
+
365
+ // ✅ Async Task
366
+ public async Task ProcessReportAsync() { }
367
+
368
+ // ❌ Catching generic Exception sem log
369
+ catch (Exception) { }
370
+
371
+ // ✅ Log and handle
372
+ catch (Exception ex)
373
+ {
374
+ _logger.LogError(ex, "Operation failed");
375
+ throw;
376
+ }
377
+ ```