@polymorphism-tech/morph-spec 2.2.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 -1673
  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 -173
  6. package/bin/render-template.js +302 -302
  7. package/bin/semantic-detect-agents.js +246 -246
  8. package/bin/task-manager.js +429 -0
  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 -0
  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 -200
  47. package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
  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 -1060
  53. package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
  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 -0
  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 -0
  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 -0
  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 -0
  223. package/src/lib/mockup-generator.js +366 -0
  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 -0
  229. package/src/lib/validation-runner.js +231 -0
  230. package/src/lib/validators/architecture-validator.js +387 -0
  231. package/src/lib/validators/contract-compliance-validator.js +273 -0
  232. package/src/lib/validators/package-validator.js +360 -0
  233. package/src/lib/validators/ui-contrast-validator.js +422 -0
  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,588 +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
- ## Estrutura de Projeto
21
-
22
- ```
23
- src/
24
- ├── {App}.Domain/ # Entidades, Value Objects, Enums
25
- │ ├── Entities/
26
- │ ├── ValueObjects/
27
- │ ├── Enums/
28
- │ └── Exceptions/
29
-
30
- ├── {App}.Application/ # Serviços, DTOs, Interfaces
31
- │ ├── Services/
32
- │ ├── DTOs/
33
- │ ├── Interfaces/
34
- │ └── Validators/
35
-
36
- ├── {App}.Infrastructure/ # EF Core, External Services
37
- │ ├── Data/
38
- │ │ ├── AppDbContext.cs
39
- │ │ ├── Configurations/
40
- │ │ └── Migrations/
41
- │ ├── Services/
42
- │ └── Extensions/
43
-
44
- ├── {App}.Web/ # Blazor Server
45
- │ ├── Program.cs
46
- │ ├── Components/
47
- │ │ ├── Layout/
48
- │ │ ├── Pages/
49
- │ │ └── Shared/
50
- │ ├── wwwroot/
51
- │ └── appsettings.json
52
-
53
- └── tests/
54
- ├── {App}.UnitTests/
55
- └── {App}.IntegrationTests/
56
- ```
57
-
58
- ## Configuração do Projeto
59
-
60
- ### csproj principal
61
-
62
- ```xml
63
- <!-- {App}.Web.csproj -->
64
- <Project Sdk="Microsoft.NET.Sdk.Web">
65
- <PropertyGroup>
66
- <TargetFramework>net10.0</TargetFramework>
67
- <Nullable>enable</Nullable>
68
- <ImplicitUsings>enable</ImplicitUsings>
69
- </PropertyGroup>
70
-
71
- <ItemGroup>
72
- <ProjectReference Include="..\{App}.Application\{App}.Application.csproj" />
73
- <ProjectReference Include="..\{App}.Infrastructure\{App}.Infrastructure.csproj" />
74
- </ItemGroup>
75
- </Project>
76
- ```
77
-
78
- ### Program.cs
79
-
80
- ```csharp
81
- var builder = WebApplication.CreateBuilder(args);
82
-
83
- // Services
84
- builder.Services.AddRazorComponents()
85
- .AddInteractiveServerComponents();
86
-
87
- // Database
88
- builder.Services.AddDbContext<AppDbContext>(options =>
89
- options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
90
-
91
- // Application Services
92
- builder.Services.AddScoped<IOrderService, OrderService>();
93
- builder.Services.AddScoped<ICustomerService, CustomerService>();
94
-
95
- // Hangfire
96
- builder.Services.AddHangfire(config => config
97
- .UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection")));
98
- builder.Services.AddHangfireServer();
99
-
100
- var app = builder.Build();
101
-
102
- // Pipeline
103
- if (!app.Environment.IsDevelopment())
104
- {
105
- app.UseExceptionHandler("/Error");
106
- app.UseHsts();
107
- }
108
-
109
- app.UseHttpsRedirection();
110
- app.UseStaticFiles();
111
- app.UseAntiforgery();
112
-
113
- app.MapRazorComponents<App>()
114
- .AddInteractiveServerRenderMode();
115
-
116
- app.MapHangfireDashboard("/hangfire");
117
-
118
- app.Run();
119
- ```
120
-
121
- ## Componentes Blazor
122
-
123
- ### Padrões de Componente
124
-
125
- ```razor
126
- @* Components/Pages/Orders/OrderList.razor *@
127
- @page "/orders"
128
- @inject IOrderService OrderService
129
- @inject NavigationManager Navigation
130
-
131
- <PageTitle>Pedidos</PageTitle>
132
-
133
- <div class="container mx-auto p-4">
134
- <div class="flex justify-between items-center mb-6">
135
- <h1 class="text-2xl font-bold">Pedidos</h1>
136
- <button @onclick="CreateNew" class="btn btn-primary">
137
- Novo Pedido
138
- </button>
139
- </div>
140
-
141
- @if (_orders is null)
142
- {
143
- <Loading />
144
- }
145
- else if (!_orders.Any())
146
- {
147
- <EmptyState Message="Nenhum pedido encontrado" />
148
- }
149
- else
150
- {
151
- <DataTable Items="_orders">
152
- <HeaderTemplate>
153
- <th>Número</th>
154
- <th>Cliente</th>
155
- <th>Total</th>
156
- <th>Status</th>
157
- <th>Ações</th>
158
- </HeaderTemplate>
159
- <RowTemplate Context="order">
160
- <td>@order.OrderNumber</td>
161
- <td>@order.CustomerName</td>
162
- <td>@order.Total.ToString("C")</td>
163
- <td><StatusBadge Status="@order.Status" /></td>
164
- <td>
165
- <button @onclick="() => ViewOrder(order.Id)" class="btn btn-sm">
166
- Ver
167
- </button>
168
- </td>
169
- </RowTemplate>
170
- </DataTable>
171
- }
172
- </div>
173
-
174
- @code {
175
- private List<OrderDto>? _orders;
176
-
177
- protected override async Task OnInitializedAsync()
178
- {
179
- _orders = await OrderService.GetAllAsync();
180
- }
181
-
182
- private void CreateNew() => Navigation.NavigateTo("/orders/new");
183
-
184
- private void ViewOrder(int id) => Navigation.NavigateTo($"/orders/{id}");
185
- }
186
- ```
187
-
188
- ### Formulários
189
-
190
- ```razor
191
- @* Components/Pages/Orders/OrderForm.razor *@
192
- @page "/orders/new"
193
- @page "/orders/{Id:int}/edit"
194
- @inject IOrderService OrderService
195
- @inject NavigationManager Navigation
196
-
197
- <PageTitle>@(_isEdit ? "Editar" : "Novo") Pedido</PageTitle>
198
-
199
- <EditForm Model="_model" OnValidSubmit="HandleSubmit">
200
- <DataAnnotationsValidator />
201
-
202
- <div class="space-y-4">
203
- <div>
204
- <label for="customerId">Cliente</label>
205
- <InputSelect @bind-Value="_model.CustomerId" id="customerId" class="input">
206
- <option value="">Selecione...</option>
207
- @foreach (var customer in _customers)
208
- {
209
- <option value="@customer.Id">@customer.Name</option>
210
- }
211
- </InputSelect>
212
- <ValidationMessage For="() => _model.CustomerId" />
213
- </div>
214
-
215
- <div>
216
- <label for="notes">Observações</label>
217
- <InputTextArea @bind-Value="_model.Notes" id="notes" class="input" />
218
- </div>
219
-
220
- <div class="flex gap-2">
221
- <button type="submit" class="btn btn-primary" disabled="@_isSubmitting">
222
- @if (_isSubmitting)
223
- {
224
- <span class="loading"></span>
225
- }
226
- Salvar
227
- </button>
228
- <button type="button" @onclick="Cancel" class="btn">Cancelar</button>
229
- </div>
230
- </div>
231
- </EditForm>
232
-
233
- @code {
234
- [Parameter] public int? Id { get; set; }
235
-
236
- private OrderFormModel _model = new();
237
- private List<CustomerDto> _customers = new();
238
- private bool _isEdit => Id.HasValue;
239
- private bool _isSubmitting;
240
-
241
- protected override async Task OnInitializedAsync()
242
- {
243
- _customers = await CustomerService.GetAllAsync();
244
-
245
- if (_isEdit)
246
- {
247
- var order = await OrderService.GetByIdAsync(Id!.Value);
248
- _model = new OrderFormModel
249
- {
250
- CustomerId = order.CustomerId,
251
- Notes = order.Notes
252
- };
253
- }
254
- }
255
-
256
- private async Task HandleSubmit()
257
- {
258
- _isSubmitting = true;
259
-
260
- try
261
- {
262
- if (_isEdit)
263
- await OrderService.UpdateAsync(Id!.Value, _model);
264
- else
265
- await OrderService.CreateAsync(_model);
266
-
267
- Navigation.NavigateTo("/orders");
268
- }
269
- finally
270
- {
271
- _isSubmitting = false;
272
- }
273
- }
274
-
275
- private void Cancel() => Navigation.NavigateTo("/orders");
276
- }
277
- ```
278
-
279
- ## Services
280
-
281
- ```csharp
282
- // Application/Services/OrderService.cs
283
- public interface IOrderService
284
- {
285
- Task<List<OrderDto>> GetAllAsync(CancellationToken ct = default);
286
- Task<OrderDto> GetByIdAsync(int id, CancellationToken ct = default);
287
- Task<OrderDto> CreateAsync(CreateOrderRequest request, CancellationToken ct = default);
288
- Task UpdateAsync(int id, UpdateOrderRequest request, CancellationToken ct = default);
289
- }
290
-
291
- public class OrderService : IOrderService
292
- {
293
- private readonly AppDbContext _context;
294
- private readonly ILogger<OrderService> _logger;
295
-
296
- public OrderService(AppDbContext context, ILogger<OrderService> logger)
297
- {
298
- _context = context;
299
- _logger = logger;
300
- }
301
-
302
- public async Task<List<OrderDto>> GetAllAsync(CancellationToken ct = default)
303
- {
304
- return await _context.Orders
305
- .Include(o => o.Customer)
306
- .OrderByDescending(o => o.CreatedAt)
307
- .Select(o => new OrderDto
308
- {
309
- Id = o.Id,
310
- OrderNumber = o.OrderNumber,
311
- CustomerName = o.Customer.Name,
312
- Total = o.Total,
313
- Status = o.Status.ToString()
314
- })
315
- .ToListAsync(ct);
316
- }
317
-
318
- public async Task<OrderDto> CreateAsync(CreateOrderRequest request, CancellationToken ct = default)
319
- {
320
- var order = Order.Create(request.CustomerId, request.Items);
321
-
322
- _context.Orders.Add(order);
323
- await _context.SaveChangesAsync(ct);
324
-
325
- _logger.LogInformation("Order {OrderNumber} created", order.OrderNumber);
326
-
327
- return new OrderDto { /* map */ };
328
- }
329
- }
330
- ```
331
-
332
- ---
333
-
334
- ## 🎨 UI Component Libraries
335
-
336
- ### Recomendação para Projetos AI-First
337
-
338
- | Biblioteca | Quando Usar | Vantagens | Desvantagens |
339
- |------------|-------------|-----------|--------------|
340
- | **Fluent UI** ⭐ | Projetos AI-first, Micro-SaaS | Componentes AI nativos, Microsoft integration, Performance (~200KB) | Menos componentes prontos |
341
- | **MudBlazor** | SaaS tradicional, Analytics pesados | 140+ componentes, Charts nativos, Templates prontos | Mais pesado (~500KB), Sem componentes AI |
342
- | **Híbrido** | SaaS complexo com AI | Melhor dos dois mundos | Maior bundle size (~350KB) |
343
-
344
- ### Fluent UI Blazor (Recomendado)
345
-
346
- **Para:**
347
- - Projetos com AI agents/chat
348
- - Integração com Microsoft Agent Framework
349
- - Produtos com UX Copilot-like
350
- - Micro-SaaS que priorizam performance
351
-
352
- **Setup rápido:**
353
- ```bash
354
- dotnet add package Microsoft.FluentUI.AspNetCore.Components
355
- ```
356
-
357
- ```csharp
358
- // Program.cs
359
- builder.Services.AddFluentUIComponents();
360
- ```
361
-
362
- **Exemplo de Chat AI:**
363
- ```razor
364
- <FluentMessageBar Intent="MessageIntent.Success">
365
- <FluentLabel Weight="FontWeight.Bold">AI Assistant</FluentLabel>
366
- <FluentLabel>@_aiResponse</FluentLabel>
367
- </FluentMessageBar>
368
- ```
369
-
370
- **Guia completo:** [Fluent UI Setup](../../.morph/standards/fluent-ui-setup.md)
371
-
372
- ### MudBlazor (Complemento)
373
-
374
- **Para:**
375
- - Grids complexos com filtros avançados
376
- - Charts e dashboards analytics
377
- - Componentes que Fluent UI não tem
378
-
379
- **Setup:**
380
- ```bash
381
- dotnet add package MudBlazor
382
- ```
383
-
384
- **Exemplo de Grid Avançado:**
385
- ```razor
386
- <MudDataGrid T="Order" Items="@_orders"
387
- Filterable="true"
388
- Groupable="true"
389
- Dense="true">
390
- <Columns>
391
- <PropertyColumn Property="x => x.OrderNumber" />
392
- <PropertyColumn Property="x => x.Total" Format="C2" />
393
- </Columns>
394
- </MudDataGrid>
395
- ```
396
-
397
- ### Abordagem Híbrida
398
-
399
- **Quando usar:**
400
- - SaaS com AI + analytics complexos
401
- - Dashboards com charts + chat AI
402
- - Aplicações enterprise completas
403
-
404
- **Pattern:**
405
- - **Base:** Fluent UI (layout, navegação, AI)
406
- - **Complemento:** MudBlazor (grids, charts)
407
-
408
- ```razor
409
- <FluentLayout>
410
- <FluentHeader>...</FluentHeader>
411
- <FluentMain>
412
- @* Grid complexo *@
413
- <MudDataGrid ... />
414
-
415
- @* Chat AI *@
416
- <FluentMessageBar>AI response</FluentMessageBar>
417
- </FluentMain>
418
- </FluentLayout>
419
- ```
420
-
421
- ---
422
-
423
- ## 🎯 Novas Features .NET 10
424
-
425
- ### State Persistence
426
-
427
- **Novo:** Propriedades com `[PersistentState]` são persist idas automaticamente.
428
-
429
- ```razor
430
- @page "/counter"
431
-
432
- <button @onclick="Increment">Count: @Count</button>
433
-
434
- @code {
435
- // Persiste automaticamente em pre-rendering e circuit disconnections
436
- [PersistentState]
437
- private int Count { get; set; } = 0;
438
-
439
- private void Increment() => Count++;
440
- }
441
- ```
442
-
443
- **Quando usar:**
444
- - Componentes com estado que precisam sobreviver a pre-rendering
445
- - Aplicações com circuit disconnections frequentes
446
- - Formulários multi-step
447
-
448
- **Não usar para:**
449
- - Dados sensíveis (passwords, tokens)
450
- - Estado que deve ser recalculado (derived state)
451
-
452
- ### Circuit Pause/Resume
453
-
454
- **Novo:** APIs JavaScript para pausar/resumir circuits.
455
-
456
- ```razor
457
- @inject IJSRuntime JS
458
-
459
- @code {
460
- protected override async Task OnAfterRenderAsync(bool firstRender)
461
- {
462
- if (firstRender)
463
- {
464
- await JS.InvokeVoidAsync("setupCircuitManagement");
465
- }
466
- }
467
- }
468
- ```
469
-
470
- ```javascript
471
- // wwwroot/app.js
472
- function setupCircuitManagement() {
473
- // Pausar quando usuário minimiza/troca de aba
474
- document.addEventListener('visibilitychange', () => {
475
- if (document.hidden) {
476
- Blazor.pauseCircuit(); // Libera recursos do servidor
477
- } else {
478
- Blazor.resumeCircuit(); // Restaura estado
479
- }
480
- });
481
- }
482
- ```
483
-
484
- **Benefícios:**
485
- - Reduz uso de memória do servidor
486
- - Melhora escalabilidade
487
- - Estado mantido durante pausa
488
-
489
- ### Blazor Metrics & Observability
490
-
491
- **Novo:** Métricas específicas de Blazor Server.
492
-
493
- ```csharp
494
- // Program.cs
495
- builder.Services.AddOpenTelemetry()
496
- .WithTracing(tracing =>
497
- {
498
- tracing.AddSource("Microsoft.AspNetCore.Components.Server");
499
- tracing.AddAspireTracing();
500
- })
501
- .WithMetrics(metrics =>
502
- {
503
- metrics.AddMeter("Microsoft.AspNetCore.Components.Server");
504
- metrics.AddAspireMetrics();
505
- });
506
- ```
507
-
508
- **Métricas disponíveis:**
509
- - Page navigations (por rota/componente)
510
- - UI events (eventos e duração)
511
- - Component lifecycle (render diff sizes)
512
- - Active circuits (usuários simultâneos)
513
- - Circuit state (connected/disconnected)
514
-
515
- **Visualização:** Aspire Dashboard integrado.
516
-
517
- ### Hot Reload Aprimorado
518
-
519
- **Automático:** 10x mais rápido no Visual Studio 2026.
520
-
521
- **Nada a fazer:** Apenas use VS 2026 Preview ou `dotnet watch`.
522
-
523
- ### Formulários com Validação Aninhada
524
-
525
- **Novo:** Validação automática de modelos aninhados.
526
-
527
- ```csharp
528
- public class Order
529
- {
530
- [Required]
531
- public string OrderNumber { get; set; } = null!;
532
-
533
- // Modelo aninhado - validado automaticamente
534
- public Customer Customer { get; set; } = new();
535
- public List<OrderItem> Items { get; set; } = new();
536
- }
537
-
538
- public class Customer
539
- {
540
- [Required]
541
- public string Name { get; set; } = null!;
542
-
543
- [EmailAddress]
544
- public string Email { get; set; } = null!;
545
-
546
- // Aninhamento profundo - também validado
547
- public Address ShippingAddress { get; set; } = new();
548
- }
549
- ```
550
-
551
- ```razor
552
- <EditForm Model="@_order" OnValidSubmit="HandleSubmit">
553
- <DataAnnotationsValidator />
554
- <ValidationSummary />
555
- <!-- Campos... -->
556
- </EditForm>
557
- ```
558
-
559
- **Configuração (Program.cs):**
560
- ```csharp
561
- builder.Services.AddValidation(); // Habilita validação aninhada
562
- ```
563
-
564
- ---
565
-
566
- ## 📚 Documentação de Referência
567
-
568
- - [Blazor Documentation](https://learn.microsoft.com/aspnet/core/blazor/)
569
- - [Entity Framework Core 10](https://learn.microsoft.com/ef/core/)
570
- - [ASP.NET Core 10](https://learn.microsoft.com/aspnet/core/)
571
- - [Hangfire](https://docs.hangfire.io/)
572
- - **[Passkeys/WebAuthn](../../.morph/standards/passkeys-auth.md)**
573
- - **[Agent Framework](../../.morph/standards/agent-framework-setup.md)**
574
-
575
- ## Checklist de Projeto
576
-
577
- - [ ] Estrutura de camadas (Domain, Application, Infrastructure, Web)
578
- - [ ] EF Core configurado com migrations
579
- - [ ] Blazor Server com componentes reutilizáveis
580
- - [ ] Services com injeção de dependência
581
- - [ ] Logging estruturado
582
- - [ ] Validação com FluentValidation ou DataAnnotations
583
- - [ ] Hangfire para background jobs
584
- - [ ] Dockerfile para containerização
585
-
586
- ---
587
-
588
- *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*