@polymorphism-tech/morph-spec 2.3.0 → 2.4.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 (251) hide show
  1. package/CLAUDE.md +314 -1730
  2. package/LICENSE +72 -72
  3. package/README.md +515 -516
  4. package/bin/detect-agents.js +225 -225
  5. package/bin/morph-spec.js +358 -294
  6. package/bin/render-template.js +302 -302
  7. package/bin/semantic-detect-agents.js +246 -246
  8. package/bin/task-manager.js +429 -368
  9. package/bin/validate-agents-skills.js +251 -251
  10. package/bin/validate-agents.js +69 -69
  11. package/bin/validate-phase.js +263 -263
  12. package/bin/validate.js +369 -268
  13. package/content/.azure/README.md +293 -293
  14. package/content/.azure/docs/azure-devops-setup.md +454 -454
  15. package/content/.azure/docs/branch-strategy.md +398 -398
  16. package/content/.azure/docs/local-development.md +515 -515
  17. package/content/.azure/pipelines/pipeline-variables.yml +34 -34
  18. package/content/.azure/pipelines/prod-pipeline.yml +319 -319
  19. package/content/.azure/pipelines/staging-pipeline.yml +234 -234
  20. package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
  21. package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
  22. package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
  23. package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
  24. package/content/.claude/commands/morph-apply.md +221 -158
  25. package/content/.claude/commands/morph-archive.md +79 -79
  26. package/content/.claude/commands/morph-infra.md +209 -209
  27. package/content/.claude/commands/morph-preflight.md +227 -0
  28. package/content/.claude/commands/morph-proposal.md +122 -101
  29. package/content/.claude/commands/morph-status.md +86 -86
  30. package/content/.claude/commands/morph-troubleshoot.md +122 -0
  31. package/content/.claude/settings.local.json +15 -15
  32. package/content/.claude/skills/checklists/code-review.md +226 -0
  33. package/content/.claude/skills/checklists/morph-checklist.md +117 -0
  34. package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
  35. package/content/.claude/skills/infra/bicep-architect.md +126 -419
  36. package/content/.claude/skills/infra/container-specialist.md +131 -437
  37. package/content/.claude/skills/infra/devops-engineer.md +119 -405
  38. package/content/.claude/skills/integrations/asaas-financial.md +130 -333
  39. package/content/.claude/skills/integrations/azure-identity.md +142 -309
  40. package/content/.claude/skills/integrations/clerk-auth.md +108 -290
  41. package/content/.claude/skills/integrations/resend-email.md +119 -0
  42. package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
  43. package/content/.claude/skills/specialists/azure-architect.md +142 -142
  44. package/content/.claude/skills/specialists/code-analyzer.md +235 -0
  45. package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
  46. package/content/.claude/skills/specialists/ef-modeler.md +113 -211
  47. package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -255
  48. package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
  49. package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
  50. package/content/.claude/skills/specialists/standards-architect.md +156 -78
  51. package/content/.claude/skills/specialists/testing-specialist.md +126 -0
  52. package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1100
  53. package/content/.claude/skills/stacks/dotnet-blazor.md +210 -606
  54. package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
  55. package/content/.claude/skills/workflows/morph-replicate.md +213 -0
  56. package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
  57. package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
  58. package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
  59. package/content/.claude/skills/workflows/phase-tasks.md +164 -0
  60. package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
  61. package/content/.morph/.morphversion +5 -5
  62. package/content/.morph/archive/.gitkeep +25 -25
  63. package/content/.morph/config/agents.json +378 -242
  64. package/content/.morph/config/config.template.json +89 -108
  65. package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
  66. package/content/.morph/docs/workflows/design-impl.md +37 -0
  67. package/content/.morph/docs/workflows/fast-track.md +29 -0
  68. package/content/.morph/docs/workflows/full-morph.md +76 -0
  69. package/content/.morph/docs/workflows/standard.md +44 -0
  70. package/content/.morph/docs/workflows/ui-refresh.md +39 -0
  71. package/content/.morph/examples/api-nextjs/README.md +241 -241
  72. package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
  73. package/content/.morph/examples/api-nextjs/spec.md +399 -399
  74. package/content/.morph/examples/api-nextjs/tasks.md +168 -168
  75. package/content/.morph/examples/micro-saas/README.md +125 -125
  76. package/content/.morph/examples/micro-saas/contracts.cs +358 -358
  77. package/content/.morph/examples/micro-saas/decisions.md +246 -246
  78. package/content/.morph/examples/micro-saas/spec.md +236 -236
  79. package/content/.morph/examples/micro-saas/tasks.md +150 -150
  80. package/content/.morph/examples/multi-agent/README.md +309 -309
  81. package/content/.morph/examples/multi-agent/contracts.cs +433 -433
  82. package/content/.morph/examples/multi-agent/spec.md +479 -479
  83. package/content/.morph/examples/multi-agent/tasks.md +185 -185
  84. package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
  85. package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
  86. package/content/.morph/examples/scheduled-reports/spec.md +267 -0
  87. package/content/.morph/examples/state-v3.json +188 -188
  88. package/content/.morph/features/.gitkeep +25 -25
  89. package/content/.morph/hooks/README.md +190 -239
  90. package/content/.morph/hooks/pre-commit-agents.sh +24 -24
  91. package/content/.morph/hooks/pre-commit-all.sh +48 -48
  92. package/content/.morph/hooks/pre-commit-specs.sh +49 -49
  93. package/content/.morph/hooks/pre-commit-tests.sh +60 -60
  94. package/content/.morph/project.md +160 -160
  95. package/content/.morph/schemas/agent.schema.json +296 -296
  96. package/content/.morph/schemas/tasks.schema.json +220 -0
  97. package/content/.morph/specs/.gitkeep +20 -20
  98. package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
  99. package/content/.morph/standards/agent-framework-production.md +410 -0
  100. package/content/.morph/standards/agent-framework-setup.md +413 -453
  101. package/content/.morph/standards/agent-framework-workflows.md +349 -0
  102. package/content/.morph/standards/architecture.md +325 -325
  103. package/content/.morph/standards/azure.md +605 -379
  104. package/content/.morph/standards/coding.md +377 -377
  105. package/content/.morph/standards/dotnet10-migration.md +520 -494
  106. package/content/.morph/standards/fluent-ui-setup.md +590 -590
  107. package/content/.morph/standards/migration-guide.md +514 -514
  108. package/content/.morph/standards/passkeys-auth.md +423 -423
  109. package/content/.morph/standards/vector-search-rag.md +536 -536
  110. package/content/.morph/state.json +17 -17
  111. package/content/.morph/templates/FluentDesignTheme.cs +149 -149
  112. package/content/.morph/templates/MudTheme.cs +281 -281
  113. package/content/.morph/templates/agent.cs +163 -172
  114. package/content/.morph/templates/clarify-questions.md +159 -0
  115. package/content/.morph/templates/component.razor +239 -239
  116. package/content/.morph/templates/contracts/Commands.cs +74 -0
  117. package/content/.morph/templates/contracts/Entities.cs +25 -0
  118. package/content/.morph/templates/contracts/Queries.cs +74 -0
  119. package/content/.morph/templates/contracts/README.md +74 -0
  120. package/content/.morph/templates/contracts.cs +217 -217
  121. package/content/.morph/templates/decisions.md +123 -106
  122. package/content/.morph/templates/design-system.css +226 -226
  123. package/content/.morph/templates/infra/.dockerignore.example +89 -89
  124. package/content/.morph/templates/infra/Dockerfile.example +82 -82
  125. package/content/.morph/templates/infra/README.md +286 -286
  126. package/content/.morph/templates/infra/app-insights.bicep +63 -63
  127. package/content/.morph/templates/infra/app-service.bicep +164 -164
  128. package/content/.morph/templates/infra/container-app-env.bicep +49 -49
  129. package/content/.morph/templates/infra/container-app.bicep +156 -156
  130. package/content/.morph/templates/infra/deploy-checklist.md +426 -0
  131. package/content/.morph/templates/infra/deploy.ps1 +229 -229
  132. package/content/.morph/templates/infra/deploy.sh +208 -208
  133. package/content/.morph/templates/infra/key-vault.bicep +91 -91
  134. package/content/.morph/templates/infra/main.bicep +189 -189
  135. package/content/.morph/templates/infra/parameters.dev.json +29 -29
  136. package/content/.morph/templates/infra/parameters.prod.json +29 -29
  137. package/content/.morph/templates/infra/parameters.staging.json +29 -29
  138. package/content/.morph/templates/infra/sql-database.bicep +103 -103
  139. package/content/.morph/templates/infra/storage.bicep +106 -106
  140. package/content/.morph/templates/integrations/asaas-client.cs +387 -387
  141. package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
  142. package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
  143. package/content/.morph/templates/integrations/clerk-config.cs +258 -258
  144. package/content/.morph/templates/job.cs +171 -171
  145. package/content/.morph/templates/migration.cs +83 -83
  146. package/content/.morph/templates/proposal.md +141 -155
  147. package/content/.morph/templates/recap.md +94 -105
  148. package/content/.morph/templates/repository.cs +141 -141
  149. package/content/.morph/templates/saas/subscription.cs +347 -347
  150. package/content/.morph/templates/saas/tenant.cs +338 -338
  151. package/content/.morph/templates/service.cs +139 -139
  152. package/content/.morph/templates/simulation.md +353 -0
  153. package/content/.morph/templates/spec.md +149 -148
  154. package/content/.morph/templates/sprint-status.yaml +68 -68
  155. package/content/.morph/templates/state.template.json +222 -222
  156. package/content/.morph/templates/story.md +143 -143
  157. package/content/.morph/templates/tasks.md +257 -235
  158. package/content/.morph/templates/test.cs +239 -239
  159. package/content/.morph/templates/ui-components.md +362 -276
  160. package/content/.morph/templates/ui-design-system.md +286 -286
  161. package/content/.morph/templates/ui-flows.md +336 -336
  162. package/content/.morph/templates/ui-mockups.md +133 -133
  163. package/content/.morph/test-infra/example.bicep +59 -59
  164. package/content/CLAUDE.md +150 -442
  165. package/content/README.md +79 -79
  166. package/detectors/config-detector.js +223 -223
  167. package/detectors/conversation-analyzer.js +163 -163
  168. package/detectors/index.js +84 -84
  169. package/detectors/standards-generator.js +275 -275
  170. package/detectors/structure-detector.js +245 -250
  171. package/docs/README.md +144 -149
  172. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
  173. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
  174. package/docs/api/scripts/collapse.js +38 -38
  175. package/docs/api/scripts/commonNav.js +28 -28
  176. package/docs/api/scripts/linenumber.js +25 -25
  177. package/docs/api/scripts/nav.js +12 -12
  178. package/docs/api/scripts/polyfill.js +3 -3
  179. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
  180. package/docs/api/scripts/prettify/lang-css.js +2 -2
  181. package/docs/api/scripts/prettify/prettify.js +28 -28
  182. package/docs/api/scripts/search.js +98 -98
  183. package/docs/api/styles/jsdoc.css +776 -776
  184. package/docs/api/styles/prettify.css +80 -80
  185. package/docs/examples.md +328 -328
  186. package/docs/getting-started.md +301 -302
  187. package/docs/installation.md +361 -361
  188. package/docs/templates.md +418 -418
  189. package/docs/validation-checklist.md +265 -266
  190. package/package.json +80 -80
  191. package/scripts/postinstall.js +132 -132
  192. package/src/commands/advance-phase.js +183 -0
  193. package/src/commands/analyze-blazor-concurrency.js +193 -0
  194. package/src/commands/create-story.js +351 -351
  195. package/src/commands/detect-agents.js +139 -0
  196. package/src/commands/detect.js +104 -104
  197. package/src/commands/doctor.js +356 -280
  198. package/src/commands/generate.js +149 -149
  199. package/src/commands/init.js +258 -245
  200. package/src/commands/lint-fluent.js +352 -0
  201. package/src/commands/rollback-phase.js +185 -0
  202. package/src/commands/session-summary.js +291 -0
  203. package/src/commands/shard-spec.js +224 -224
  204. package/src/commands/sprint-status.js +250 -250
  205. package/src/commands/state.js +333 -333
  206. package/src/commands/sync.js +167 -167
  207. package/src/commands/task.js +78 -75
  208. package/src/commands/troubleshoot.js +222 -0
  209. package/src/commands/update.js +192 -159
  210. package/src/commands/validate-blazor-state.js +210 -0
  211. package/src/commands/validate-blazor.js +156 -0
  212. package/src/commands/validate-css.js +84 -0
  213. package/src/commands/validate-phase.js +221 -0
  214. package/src/lib/blazor-concurrency-analyzer.js +288 -0
  215. package/src/lib/blazor-state-validator.js +291 -0
  216. package/src/lib/blazor-validator.js +374 -0
  217. package/src/lib/complexity-analyzer.js +441 -292
  218. package/src/lib/continuous-validator.js +421 -440
  219. package/src/lib/css-validator.js +352 -0
  220. package/src/lib/decision-constraint-loader.js +109 -0
  221. package/src/lib/design-system-generator.js +298 -298
  222. package/src/lib/learning-system.js +520 -520
  223. package/src/lib/mockup-generator.js +366 -366
  224. package/src/lib/recap-generator.js +205 -0
  225. package/src/lib/state-manager.js +397 -340
  226. package/src/lib/troubleshoot-grep.js +194 -0
  227. package/src/lib/troubleshoot-index.js +144 -0
  228. package/src/lib/ui-detector.js +350 -350
  229. package/src/lib/validation-runner.js +231 -0
  230. package/src/lib/validators/architecture-validator.js +387 -387
  231. package/src/lib/validators/contract-compliance-validator.js +273 -0
  232. package/src/lib/validators/package-validator.js +360 -360
  233. package/src/lib/validators/ui-contrast-validator.js +422 -422
  234. package/src/utils/file-copier.js +179 -139
  235. package/src/utils/logger.js +32 -32
  236. package/src/utils/version-checker.js +175 -175
  237. package/content/.claude/commands/morph-costs.md +0 -206
  238. package/content/.claude/commands/morph-tasks.md +0 -319
  239. package/content/.claude/skills/specialists/cost-guardian.md +0 -110
  240. package/content/.claude/skills/stacks/shopify.md +0 -445
  241. package/content/.morph/config/azure-pricing.json +0 -70
  242. package/content/.morph/config/azure-pricing.schema.json +0 -50
  243. package/content/.morph/hooks/pre-commit-costs.sh +0 -91
  244. package/docs/api/cost-calculator.js.html +0 -513
  245. package/docs/api/design-system-generator.js.html +0 -382
  246. package/docs/api/global.html +0 -5263
  247. package/docs/api/index.html +0 -96
  248. package/docs/api/state-manager.js.html +0 -423
  249. package/src/commands/cost.js +0 -181
  250. package/src/commands/update-pricing.js +0 -206
  251. package/src/lib/cost-calculator.js +0 -429
@@ -1,606 +1,210 @@
1
- # .NET + Blazor Stack
2
-
3
- Stack principal para desenvolvimento de aplicações web com .NET e Blazor Server.
4
-
5
- ## Visão Geral
6
-
7
- | Aspecto | Tecnologia |
8
- |---------|------------|
9
- | **Backend** | .NET 10 / C# 14 |
10
- | **Frontend** | Blazor Server |
11
- | **Database** | Entity Framework Core 10 + Azure SQL |
12
- | **Hosting** | Azure Container Apps |
13
- | **Background** | Hangfire |
14
- | **AI** | Microsoft Agent Framework (exclusivo) |
15
-
16
- ## Triggers
17
-
18
- Keywords: `blazor`, `razor`, `server-side`, `.net`, `csharp`, `dotnet`
19
-
20
- ---
21
-
22
- ## ⚠️ CRITICAL PITFALLS (Read FIRST!)
23
-
24
- **ALWAYS consult framework standards before implementing:**
25
- - `framework/standards/blazor-pitfalls.md` - Common issues & solutions
26
- - `framework/standards/blazor-lifecycle.md` - Lifecycle patterns
27
- - `framework/standards/program-cs-checklist.md` - Required Program.cs setup
28
- - `framework/standards/dotnet10-compatibility.md` - Package compatibility
29
-
30
- **Quick Checklist:**
31
- - [ ] DI Pattern: Use HttpClient, NOT direct Application layer injection
32
- - [ ] Lifecycle: JSRuntime ONLY in OnAfterRenderAsync(firstRender)
33
- - [ ] Program.cs: app.UseStaticFiles() BEFORE app.UseAntiforgery()
34
- - [ ] File Upload: Specify maxAllowedSize in OpenReadStream()
35
- - [ ] RenderMode: NO @rendermode on MainLayout
36
- - [ ] Package Versions: MudBlazor 8.15.0 for .NET 10
37
-
38
- ## Estrutura de Projeto
39
-
40
- ```
41
- src/
42
- ├── {App}.Domain/ # Entidades, Value Objects, Enums
43
- │ ├── Entities/
44
- │ ├── ValueObjects/
45
- │ ├── Enums/
46
- │ └── Exceptions/
47
-
48
- ├── {App}.Application/ # Serviços, DTOs, Interfaces
49
- │ ├── Services/
50
- │ ├── DTOs/
51
- │ ├── Interfaces/
52
- │ └── Validators/
53
-
54
- ├── {App}.Infrastructure/ # EF Core, External Services
55
- │ ├── Data/
56
- │ │ ├── AppDbContext.cs
57
- │ │ ├── Configurations/
58
- │ │ └── Migrations/
59
- │ ├── Services/
60
- │ └── Extensions/
61
-
62
- ├── {App}.Web/ # Blazor Server
63
- │ ├── Program.cs
64
- │ ├── Components/
65
- │ │ ├── Layout/
66
- │ │ ├── Pages/
67
- │ │ └── Shared/
68
- │ ├── wwwroot/
69
- │ └── appsettings.json
70
-
71
- └── tests/
72
- ├── {App}.UnitTests/
73
- └── {App}.IntegrationTests/
74
- ```
75
-
76
- ## Configuração do Projeto
77
-
78
- ### csproj principal
79
-
80
- ```xml
81
- <!-- {App}.Web.csproj -->
82
- <Project Sdk="Microsoft.NET.Sdk.Web">
83
- <PropertyGroup>
84
- <TargetFramework>net10.0</TargetFramework>
85
- <Nullable>enable</Nullable>
86
- <ImplicitUsings>enable</ImplicitUsings>
87
- </PropertyGroup>
88
-
89
- <ItemGroup>
90
- <ProjectReference Include="..\{App}.Application\{App}.Application.csproj" />
91
- <ProjectReference Include="..\{App}.Infrastructure\{App}.Infrastructure.csproj" />
92
- </ItemGroup>
93
- </Project>
94
- ```
95
-
96
- ### Program.cs
97
-
98
- ```csharp
99
- var builder = WebApplication.CreateBuilder(args);
100
-
101
- // Services
102
- builder.Services.AddRazorComponents()
103
- .AddInteractiveServerComponents();
104
-
105
- // Database
106
- builder.Services.AddDbContext<AppDbContext>(options =>
107
- options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
108
-
109
- // Application Services
110
- builder.Services.AddScoped<IOrderService, OrderService>();
111
- builder.Services.AddScoped<ICustomerService, CustomerService>();
112
-
113
- // Hangfire
114
- builder.Services.AddHangfire(config => config
115
- .UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection")));
116
- builder.Services.AddHangfireServer();
117
-
118
- var app = builder.Build();
119
-
120
- // Pipeline
121
- if (!app.Environment.IsDevelopment())
122
- {
123
- app.UseExceptionHandler("/Error");
124
- app.UseHsts();
125
- }
126
-
127
- app.UseHttpsRedirection();
128
- app.UseStaticFiles();
129
- app.UseAntiforgery();
130
-
131
- app.MapRazorComponents<App>()
132
- .AddInteractiveServerRenderMode();
133
-
134
- app.MapHangfireDashboard("/hangfire");
135
-
136
- app.Run();
137
- ```
138
-
139
- ## Componentes Blazor
140
-
141
- ### Padrões de Componente
142
-
143
- ```razor
144
- @* Components/Pages/Orders/OrderList.razor *@
145
- @page "/orders"
146
- @inject IOrderService OrderService
147
- @inject NavigationManager Navigation
148
-
149
- <PageTitle>Pedidos</PageTitle>
150
-
151
- <div class="container mx-auto p-4">
152
- <div class="flex justify-between items-center mb-6">
153
- <h1 class="text-2xl font-bold">Pedidos</h1>
154
- <button @onclick="CreateNew" class="btn btn-primary">
155
- Novo Pedido
156
- </button>
157
- </div>
158
-
159
- @if (_orders is null)
160
- {
161
- <Loading />
162
- }
163
- else if (!_orders.Any())
164
- {
165
- <EmptyState Message="Nenhum pedido encontrado" />
166
- }
167
- else
168
- {
169
- <DataTable Items="_orders">
170
- <HeaderTemplate>
171
- <th>Número</th>
172
- <th>Cliente</th>
173
- <th>Total</th>
174
- <th>Status</th>
175
- <th>Ações</th>
176
- </HeaderTemplate>
177
- <RowTemplate Context="order">
178
- <td>@order.OrderNumber</td>
179
- <td>@order.CustomerName</td>
180
- <td>@order.Total.ToString("C")</td>
181
- <td><StatusBadge Status="@order.Status" /></td>
182
- <td>
183
- <button @onclick="() => ViewOrder(order.Id)" class="btn btn-sm">
184
- Ver
185
- </button>
186
- </td>
187
- </RowTemplate>
188
- </DataTable>
189
- }
190
- </div>
191
-
192
- @code {
193
- private List<OrderDto>? _orders;
194
-
195
- protected override async Task OnInitializedAsync()
196
- {
197
- _orders = await OrderService.GetAllAsync();
198
- }
199
-
200
- private void CreateNew() => Navigation.NavigateTo("/orders/new");
201
-
202
- private void ViewOrder(int id) => Navigation.NavigateTo($"/orders/{id}");
203
- }
204
- ```
205
-
206
- ### Formulários
207
-
208
- ```razor
209
- @* Components/Pages/Orders/OrderForm.razor *@
210
- @page "/orders/new"
211
- @page "/orders/{Id:int}/edit"
212
- @inject IOrderService OrderService
213
- @inject NavigationManager Navigation
214
-
215
- <PageTitle>@(_isEdit ? "Editar" : "Novo") Pedido</PageTitle>
216
-
217
- <EditForm Model="_model" OnValidSubmit="HandleSubmit">
218
- <DataAnnotationsValidator />
219
-
220
- <div class="space-y-4">
221
- <div>
222
- <label for="customerId">Cliente</label>
223
- <InputSelect @bind-Value="_model.CustomerId" id="customerId" class="input">
224
- <option value="">Selecione...</option>
225
- @foreach (var customer in _customers)
226
- {
227
- <option value="@customer.Id">@customer.Name</option>
228
- }
229
- </InputSelect>
230
- <ValidationMessage For="() => _model.CustomerId" />
231
- </div>
232
-
233
- <div>
234
- <label for="notes">Observações</label>
235
- <InputTextArea @bind-Value="_model.Notes" id="notes" class="input" />
236
- </div>
237
-
238
- <div class="flex gap-2">
239
- <button type="submit" class="btn btn-primary" disabled="@_isSubmitting">
240
- @if (_isSubmitting)
241
- {
242
- <span class="loading"></span>
243
- }
244
- Salvar
245
- </button>
246
- <button type="button" @onclick="Cancel" class="btn">Cancelar</button>
247
- </div>
248
- </div>
249
- </EditForm>
250
-
251
- @code {
252
- [Parameter] public int? Id { get; set; }
253
-
254
- private OrderFormModel _model = new();
255
- private List<CustomerDto> _customers = new();
256
- private bool _isEdit => Id.HasValue;
257
- private bool _isSubmitting;
258
-
259
- protected override async Task OnInitializedAsync()
260
- {
261
- _customers = await CustomerService.GetAllAsync();
262
-
263
- if (_isEdit)
264
- {
265
- var order = await OrderService.GetByIdAsync(Id!.Value);
266
- _model = new OrderFormModel
267
- {
268
- CustomerId = order.CustomerId,
269
- Notes = order.Notes
270
- };
271
- }
272
- }
273
-
274
- private async Task HandleSubmit()
275
- {
276
- _isSubmitting = true;
277
-
278
- try
279
- {
280
- if (_isEdit)
281
- await OrderService.UpdateAsync(Id!.Value, _model);
282
- else
283
- await OrderService.CreateAsync(_model);
284
-
285
- Navigation.NavigateTo("/orders");
286
- }
287
- finally
288
- {
289
- _isSubmitting = false;
290
- }
291
- }
292
-
293
- private void Cancel() => Navigation.NavigateTo("/orders");
294
- }
295
- ```
296
-
297
- ## Services
298
-
299
- ```csharp
300
- // Application/Services/OrderService.cs
301
- public interface IOrderService
302
- {
303
- Task<List<OrderDto>> GetAllAsync(CancellationToken ct = default);
304
- Task<OrderDto> GetByIdAsync(int id, CancellationToken ct = default);
305
- Task<OrderDto> CreateAsync(CreateOrderRequest request, CancellationToken ct = default);
306
- Task UpdateAsync(int id, UpdateOrderRequest request, CancellationToken ct = default);
307
- }
308
-
309
- public class OrderService : IOrderService
310
- {
311
- private readonly AppDbContext _context;
312
- private readonly ILogger<OrderService> _logger;
313
-
314
- public OrderService(AppDbContext context, ILogger<OrderService> logger)
315
- {
316
- _context = context;
317
- _logger = logger;
318
- }
319
-
320
- public async Task<List<OrderDto>> GetAllAsync(CancellationToken ct = default)
321
- {
322
- return await _context.Orders
323
- .Include(o => o.Customer)
324
- .OrderByDescending(o => o.CreatedAt)
325
- .Select(o => new OrderDto
326
- {
327
- Id = o.Id,
328
- OrderNumber = o.OrderNumber,
329
- CustomerName = o.Customer.Name,
330
- Total = o.Total,
331
- Status = o.Status.ToString()
332
- })
333
- .ToListAsync(ct);
334
- }
335
-
336
- public async Task<OrderDto> CreateAsync(CreateOrderRequest request, CancellationToken ct = default)
337
- {
338
- var order = Order.Create(request.CustomerId, request.Items);
339
-
340
- _context.Orders.Add(order);
341
- await _context.SaveChangesAsync(ct);
342
-
343
- _logger.LogInformation("Order {OrderNumber} created", order.OrderNumber);
344
-
345
- return new OrderDto { /* map */ };
346
- }
347
- }
348
- ```
349
-
350
- ---
351
-
352
- ## 🎨 UI Component Libraries
353
-
354
- ### Recomendação para Projetos AI-First
355
-
356
- | Biblioteca | Quando Usar | Vantagens | Desvantagens |
357
- |------------|-------------|-----------|--------------|
358
- | **Fluent UI** ⭐ | Projetos AI-first, Micro-SaaS | Componentes AI nativos, Microsoft integration, Performance (~200KB) | Menos componentes prontos |
359
- | **MudBlazor** | SaaS tradicional, Analytics pesados | 140+ componentes, Charts nativos, Templates prontos | Mais pesado (~500KB), Sem componentes AI |
360
- | **Híbrido** | SaaS complexo com AI | Melhor dos dois mundos | Maior bundle size (~350KB) |
361
-
362
- ### Fluent UI Blazor (Recomendado)
363
-
364
- **Para:**
365
- - Projetos com AI agents/chat
366
- - Integração com Microsoft Agent Framework
367
- - Produtos com UX Copilot-like
368
- - Micro-SaaS que priorizam performance
369
-
370
- **Setup rápido:**
371
- ```bash
372
- dotnet add package Microsoft.FluentUI.AspNetCore.Components
373
- ```
374
-
375
- ```csharp
376
- // Program.cs
377
- builder.Services.AddFluentUIComponents();
378
- ```
379
-
380
- **Exemplo de Chat AI:**
381
- ```razor
382
- <FluentMessageBar Intent="MessageIntent.Success">
383
- <FluentLabel Weight="FontWeight.Bold">AI Assistant</FluentLabel>
384
- <FluentLabel>@_aiResponse</FluentLabel>
385
- </FluentMessageBar>
386
- ```
387
-
388
- **Guia completo:** [Fluent UI Setup](../../.morph/standards/fluent-ui-setup.md)
389
-
390
- ### MudBlazor (Complemento)
391
-
392
- **Para:**
393
- - Grids complexos com filtros avançados
394
- - Charts e dashboards analytics
395
- - Componentes que Fluent UI não tem
396
-
397
- **Setup:**
398
- ```bash
399
- dotnet add package MudBlazor
400
- ```
401
-
402
- **Exemplo de Grid Avançado:**
403
- ```razor
404
- <MudDataGrid T="Order" Items="@_orders"
405
- Filterable="true"
406
- Groupable="true"
407
- Dense="true">
408
- <Columns>
409
- <PropertyColumn Property="x => x.OrderNumber" />
410
- <PropertyColumn Property="x => x.Total" Format="C2" />
411
- </Columns>
412
- </MudDataGrid>
413
- ```
414
-
415
- ### Abordagem Híbrida
416
-
417
- **Quando usar:**
418
- - SaaS com AI + analytics complexos
419
- - Dashboards com charts + chat AI
420
- - Aplicações enterprise completas
421
-
422
- **Pattern:**
423
- - **Base:** Fluent UI (layout, navegação, AI)
424
- - **Complemento:** MudBlazor (grids, charts)
425
-
426
- ```razor
427
- <FluentLayout>
428
- <FluentHeader>...</FluentHeader>
429
- <FluentMain>
430
- @* Grid complexo *@
431
- <MudDataGrid ... />
432
-
433
- @* Chat AI *@
434
- <FluentMessageBar>AI response</FluentMessageBar>
435
- </FluentMain>
436
- </FluentLayout>
437
- ```
438
-
439
- ---
440
-
441
- ## 🎯 Novas Features .NET 10
442
-
443
- ### State Persistence
444
-
445
- **Novo:** Propriedades com `[PersistentState]` são persist idas automaticamente.
446
-
447
- ```razor
448
- @page "/counter"
449
-
450
- <button @onclick="Increment">Count: @Count</button>
451
-
452
- @code {
453
- // Persiste automaticamente em pre-rendering e circuit disconnections
454
- [PersistentState]
455
- private int Count { get; set; } = 0;
456
-
457
- private void Increment() => Count++;
458
- }
459
- ```
460
-
461
- **Quando usar:**
462
- - Componentes com estado que precisam sobreviver a pre-rendering
463
- - Aplicações com circuit disconnections frequentes
464
- - Formulários multi-step
465
-
466
- **Não usar para:**
467
- - Dados sensíveis (passwords, tokens)
468
- - Estado que deve ser recalculado (derived state)
469
-
470
- ### Circuit Pause/Resume
471
-
472
- **Novo:** APIs JavaScript para pausar/resumir circuits.
473
-
474
- ```razor
475
- @inject IJSRuntime JS
476
-
477
- @code {
478
- protected override async Task OnAfterRenderAsync(bool firstRender)
479
- {
480
- if (firstRender)
481
- {
482
- await JS.InvokeVoidAsync("setupCircuitManagement");
483
- }
484
- }
485
- }
486
- ```
487
-
488
- ```javascript
489
- // wwwroot/app.js
490
- function setupCircuitManagement() {
491
- // Pausar quando usuário minimiza/troca de aba
492
- document.addEventListener('visibilitychange', () => {
493
- if (document.hidden) {
494
- Blazor.pauseCircuit(); // Libera recursos do servidor
495
- } else {
496
- Blazor.resumeCircuit(); // Restaura estado
497
- }
498
- });
499
- }
500
- ```
501
-
502
- **Benefícios:**
503
- - Reduz uso de memória do servidor
504
- - Melhora escalabilidade
505
- - Estado mantido durante pausa
506
-
507
- ### Blazor Metrics & Observability
508
-
509
- **Novo:** Métricas específicas de Blazor Server.
510
-
511
- ```csharp
512
- // Program.cs
513
- builder.Services.AddOpenTelemetry()
514
- .WithTracing(tracing =>
515
- {
516
- tracing.AddSource("Microsoft.AspNetCore.Components.Server");
517
- tracing.AddAspireTracing();
518
- })
519
- .WithMetrics(metrics =>
520
- {
521
- metrics.AddMeter("Microsoft.AspNetCore.Components.Server");
522
- metrics.AddAspireMetrics();
523
- });
524
- ```
525
-
526
- **Métricas disponíveis:**
527
- - Page navigations (por rota/componente)
528
- - UI events (eventos e duração)
529
- - Component lifecycle (render diff sizes)
530
- - Active circuits (usuários simultâneos)
531
- - Circuit state (connected/disconnected)
532
-
533
- **Visualização:** Aspire Dashboard integrado.
534
-
535
- ### Hot Reload Aprimorado
536
-
537
- **Automático:** 10x mais rápido no Visual Studio 2026.
538
-
539
- **Nada a fazer:** Apenas use VS 2026 Preview ou `dotnet watch`.
540
-
541
- ### Formulários com Validação Aninhada
542
-
543
- **Novo:** Validação automática de modelos aninhados.
544
-
545
- ```csharp
546
- public class Order
547
- {
548
- [Required]
549
- public string OrderNumber { get; set; } = null!;
550
-
551
- // Modelo aninhado - validado automaticamente
552
- public Customer Customer { get; set; } = new();
553
- public List<OrderItem> Items { get; set; } = new();
554
- }
555
-
556
- public class Customer
557
- {
558
- [Required]
559
- public string Name { get; set; } = null!;
560
-
561
- [EmailAddress]
562
- public string Email { get; set; } = null!;
563
-
564
- // Aninhamento profundo - também validado
565
- public Address ShippingAddress { get; set; } = new();
566
- }
567
- ```
568
-
569
- ```razor
570
- <EditForm Model="@_order" OnValidSubmit="HandleSubmit">
571
- <DataAnnotationsValidator />
572
- <ValidationSummary />
573
- <!-- Campos... -->
574
- </EditForm>
575
- ```
576
-
577
- **Configuração (Program.cs):**
578
- ```csharp
579
- builder.Services.AddValidation(); // Habilita validação aninhada
580
- ```
581
-
582
- ---
583
-
584
- ## 📚 Documentação de Referência
585
-
586
- - [Blazor Documentation](https://learn.microsoft.com/aspnet/core/blazor/)
587
- - [Entity Framework Core 10](https://learn.microsoft.com/ef/core/)
588
- - [ASP.NET Core 10](https://learn.microsoft.com/aspnet/core/)
589
- - [Hangfire](https://docs.hangfire.io/)
590
- - **[Passkeys/WebAuthn](../../.morph/standards/passkeys-auth.md)**
591
- - **[Agent Framework](../../.morph/standards/agent-framework-setup.md)**
592
-
593
- ## Checklist de Projeto
594
-
595
- - [ ] Estrutura de camadas (Domain, Application, Infrastructure, Web)
596
- - [ ] EF Core configurado com migrations
597
- - [ ] Blazor Server com componentes reutilizáveis
598
- - [ ] Services com injeção de dependência
599
- - [ ] Logging estruturado
600
- - [ ] Validação com FluentValidation ou DataAnnotations
601
- - [ ] Hangfire para background jobs
602
- - [ ] Dockerfile para containerização
603
-
604
- ---
605
-
606
- *MORPH-SPEC by Polymorphism Tech*
1
+ # .NET + Blazor Stack
2
+
3
+ Stack principal para aplicações web com .NET e Blazor Server.
4
+
5
+ | Aspecto | Tecnologia |
6
+ |---------|------------|
7
+ | **Backend** | .NET 10 / C# 14 |
8
+ | **Frontend** | Blazor Server |
9
+ | **Database** | EF Core 10 + Azure SQL |
10
+ | **Hosting** | Azure Container Apps |
11
+ | **Background** | Hangfire |
12
+ | **AI** | Microsoft Agent Framework |
13
+
14
+ **Triggers:** `blazor`, `razor`, `server-side`, `.net`, `csharp`, `dotnet`
15
+
16
+ ---
17
+
18
+ ## Critical Standards (Read FIRST)
19
+
20
+ | Standard | What |
21
+ |----------|------|
22
+ | `framework/standards/coding.md` | **C# naming conventions, code style, .editorconfig template** |
23
+ | `framework/standards/architecture.md` | **Clean Architecture layers, SOLID, service patterns** |
24
+ | `framework/standards/blazor-efcore.md` | DbContext concurrency, Repository Factory, background ops, migrations |
25
+ | `framework/standards/blazor-pitfalls.md` | Common Blazor issues & solutions |
26
+ | `framework/standards/fluent-ui-blazor.md` | Fluent UI APIs, icon sizes, dialog patterns |
27
+ | `framework/standards/blazor-lifecycle.md` | Component lifecycle patterns |
28
+ | `framework/standards/program-cs-checklist.md` | Required Program.cs setup |
29
+
30
+ ### Quick Checklist
31
+ - [ ] Background ops: Use `IDbContextFactory` / Repository Factory (ref: blazor-efcore.md)
32
+ - [ ] JSRuntime: ONLY in `OnAfterRenderAsync(firstRender)`
33
+ - [ ] Program.cs: `UseStaticFiles()` BEFORE `UseAntiforgery()`
34
+ - [ ] File Upload: Specify `maxAllowedSize` in `OpenReadStream()`
35
+ - [ ] RenderMode: NO `@rendermode` on MainLayout
36
+ - [ ] Package Versions: MudBlazor >= 8.15.0 for .NET 10
37
+
38
+ ---
39
+
40
+ ## Mandatory Code Patterns
41
+
42
+ ### Status Validation
43
+
44
+ ```csharp
45
+ // ✅ Validate INVALID states (allows future extensions)
46
+ if (order.Status >= OrderStatus.Completed || order.Status == OrderStatus.Failed)
47
+ throw new InvalidOperationException("Cannot process completed or failed order");
48
+
49
+ // ❌ Never assume single valid flow
50
+ if (order.Status != OrderStatus.PendingPayment)
51
+ throw new InvalidOperationException("Invalid status");
52
+ ```
53
+
54
+ ### Enums with Logical Order
55
+
56
+ ```csharp
57
+ public enum OrderStatus
58
+ {
59
+ Created = 0, PendingPayment = 1, Processing = 2, Completed = 3, // Normal flow
60
+ Failed = 100, Cancelled = 101, Refunded = 102 // Error states (high values)
61
+ }
62
+ ```
63
+
64
+ ### Service Pattern
65
+
66
+ ```csharp
67
+ public async Task<Result<Order>> ProcessAsync(Guid orderId, CancellationToken ct)
68
+ {
69
+ _logger.LogInformation("Processing order {OrderId}", orderId);
70
+ var order = await _repository.GetByIdAsync(orderId, ct);
71
+ if (order == null) return Result.Failure<Order>("Order not found");
72
+ if (order.Status >= OrderStatus.Completed)
73
+ return Result.Failure<Order>("Order already completed");
74
+ // ... process ...
75
+ return Result.Success(order);
76
+ }
77
+ ```
78
+
79
+ **Rules:** Logging at critical points, CancellationToken propagated, Result pattern for business errors, exceptions for infrastructure.
80
+
81
+ **More patterns:** See `code-review.md` for DTOs/contracts naming and service checklists.
82
+
83
+ ---
84
+
85
+ ## Project Structure
86
+
87
+ ```
88
+ src/
89
+ ├── {App}.Domain/ # Entities, Value Objects, Enums, Exceptions
90
+ ├── {App}.Application/ # Services, DTOs, Interfaces, Validators
91
+ ├── {App}.Infrastructure/ # EF Core (DbContext, Configs, Migrations), External Services
92
+ ├── {App}.Web/ # Blazor Server (Program.cs, Components, Pages, wwwroot)
93
+ └── tests/ # UnitTests, IntegrationTests
94
+ ```
95
+
96
+ ### Program.cs Essentials
97
+
98
+ ```csharp
99
+ var builder = WebApplication.CreateBuilder(args);
100
+ builder.Services.AddRazorComponents().AddInteractiveServerComponents();
101
+ builder.Services.AddDbContext<AppDbContext>(o => o.UseSqlServer(connString));
102
+ builder.Services.AddDbContextFactory<AppDbContext>(o => o.UseSqlServer(connString));
103
+ // Register services, factories, Hangfire...
104
+
105
+ var app = builder.Build();
106
+ app.UseHttpsRedirection();
107
+ app.UseStaticFiles(); // BEFORE UseAntiforgery!
108
+ app.UseAntiforgery();
109
+ app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
110
+ app.Run();
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Blazor Component Patterns
116
+
117
+ ### Page with List
118
+
119
+ ```razor
120
+ @page "/orders"
121
+ @inject IOrderService OrderService
122
+
123
+ @if (_orders is null) { <Loading /> }
124
+ else if (!_orders.Any()) { <EmptyState Message="No orders found" /> }
125
+ else
126
+ {
127
+ @foreach (var order in _orders)
128
+ {
129
+ <FluentCard>@order.OrderNumber - @order.Total.ToString("C")</FluentCard>
130
+ }
131
+ }
132
+
133
+ @code {
134
+ private List<OrderDto>? _orders;
135
+ protected override async Task OnInitializedAsync()
136
+ => _orders = await OrderService.GetAllAsync();
137
+ }
138
+ ```
139
+
140
+ ### Form with Validation
141
+
142
+ ```razor
143
+ @page "/orders/new"
144
+ <EditForm Model="_model" OnValidSubmit="HandleSubmit">
145
+ <DataAnnotationsValidator />
146
+ <InputSelect @bind-Value="_model.CustomerId">...</InputSelect>
147
+ <ValidationMessage For="() => _model.CustomerId" />
148
+ <button type="submit" disabled="@_isSubmitting">Save</button>
149
+ </EditForm>
150
+ ```
151
+
152
+ ---
153
+
154
+ ## UI Libraries
155
+
156
+ > **Decision matrix:** See `ui-ux-designer.md` skill for full comparison.
157
+
158
+ | Library | When | Key Advantage |
159
+ |---------|------|---------------|
160
+ | **Fluent UI** | AI-first, Microsoft stack | Performance (~200KB), AI components |
161
+ | **MudBlazor** | Complex dashboards | 140+ components, charts |
162
+ | **Hybrid** | SaaS with AI + analytics | Best of both |
163
+
164
+ ---
165
+
166
+ ## .NET 10 Features
167
+
168
+ ### PersistentState (new)
169
+ ```razor
170
+ @code {
171
+ [PersistentState]
172
+ private int Count { get; set; } = 0; // Survives pre-rendering & circuit disconnections
173
+ }
174
+ ```
175
+
176
+ ### Circuit Pause/Resume (new)
177
+ ```javascript
178
+ document.addEventListener('visibilitychange', () => {
179
+ document.hidden ? Blazor.pauseCircuit() : Blazor.resumeCircuit();
180
+ });
181
+ ```
182
+
183
+ ### Nested Model Validation (new)
184
+ ```csharp
185
+ builder.Services.AddValidation(); // Enables automatic nested model validation
186
+ ```
187
+
188
+ ### Blazor Metrics
189
+ ```csharp
190
+ builder.Services.AddOpenTelemetry()
191
+ .WithTracing(t => t.AddSource("Microsoft.AspNetCore.Components.Server"))
192
+ .WithMetrics(m => m.AddMeter("Microsoft.AspNetCore.Components.Server"));
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Project Checklist
198
+
199
+ - [ ] Clean Architecture layers (Domain, Application, Infrastructure, Web)
200
+ - [ ] EF Core with migrations + IDbContextFactory
201
+ - [ ] Repository Factory for background ops (ref: blazor-efcore.md)
202
+ - [ ] Blazor Server with reusable components
203
+ - [ ] Services with DI + structured logging
204
+ - [ ] Validation (FluentValidation or DataAnnotations)
205
+ - [ ] Hangfire for background jobs
206
+ - [ ] Dockerfile for containerization
207
+
208
+ ---
209
+
210
+ *MORPH-SPEC by Polymorphism Tech*