@polymorphism-tech/morph-spec 1.0.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 (83) hide show
  1. package/README.md +279 -0
  2. package/bin/morph-spec.js +53 -0
  3. package/content/.claude/commands/morph-apply.md +66 -0
  4. package/content/.claude/commands/morph-archive.md +79 -0
  5. package/content/.claude/commands/morph-costs.md +206 -0
  6. package/content/.claude/commands/morph-infra.md +209 -0
  7. package/content/.claude/commands/morph-proposal.md +60 -0
  8. package/content/.claude/commands/morph-status.md +71 -0
  9. package/content/.claude/settings.local.json +15 -0
  10. package/content/.claude/skills/infra/bicep-architect.md +419 -0
  11. package/content/.claude/skills/infra/container-specialist.md +437 -0
  12. package/content/.claude/skills/infra/devops-engineer.md +405 -0
  13. package/content/.claude/skills/integrations/asaas-financial.md +333 -0
  14. package/content/.claude/skills/integrations/azure-identity.md +309 -0
  15. package/content/.claude/skills/integrations/clerk-auth.md +290 -0
  16. package/content/.claude/skills/specialists/azure-architect.md +142 -0
  17. package/content/.claude/skills/specialists/cost-guardian.md +110 -0
  18. package/content/.claude/skills/specialists/ef-modeler.md +200 -0
  19. package/content/.claude/skills/specialists/hangfire-orchestrator.md +245 -0
  20. package/content/.claude/skills/specialists/ms-agent-expert.md +209 -0
  21. package/content/.claude/skills/specialists/po-pm-advisor.md +197 -0
  22. package/content/.claude/skills/specialists/standards-architect.md +78 -0
  23. package/content/.claude/skills/specialists/ui-ux-designer.md +325 -0
  24. package/content/.claude/skills/stacks/dotnet-blazor.md +352 -0
  25. package/content/.claude/skills/stacks/dotnet-nextjs.md +402 -0
  26. package/content/.claude/skills/stacks/shopify.md +445 -0
  27. package/content/.morph/archive/.gitkeep +25 -0
  28. package/content/.morph/config/agents.json +149 -0
  29. package/content/.morph/config/config.template.json +96 -0
  30. package/content/.morph/examples/api-nextjs/README.md +241 -0
  31. package/content/.morph/examples/api-nextjs/contracts.ts +307 -0
  32. package/content/.morph/examples/api-nextjs/spec.md +399 -0
  33. package/content/.morph/examples/api-nextjs/tasks.md +168 -0
  34. package/content/.morph/examples/micro-saas/README.md +125 -0
  35. package/content/.morph/examples/micro-saas/contracts.cs +358 -0
  36. package/content/.morph/examples/micro-saas/decisions.md +246 -0
  37. package/content/.morph/examples/micro-saas/spec.md +236 -0
  38. package/content/.morph/examples/micro-saas/tasks.md +150 -0
  39. package/content/.morph/examples/multi-agent/README.md +309 -0
  40. package/content/.morph/examples/multi-agent/contracts.cs +433 -0
  41. package/content/.morph/examples/multi-agent/spec.md +479 -0
  42. package/content/.morph/examples/multi-agent/tasks.md +185 -0
  43. package/content/.morph/features/.gitkeep +25 -0
  44. package/content/.morph/project.md +159 -0
  45. package/content/.morph/specs/.gitkeep +20 -0
  46. package/content/.morph/standards/architecture.md +190 -0
  47. package/content/.morph/standards/azure.md +184 -0
  48. package/content/.morph/standards/coding.md +342 -0
  49. package/content/.morph/templates/agent.cs +172 -0
  50. package/content/.morph/templates/component.razor +239 -0
  51. package/content/.morph/templates/contracts.cs +217 -0
  52. package/content/.morph/templates/decisions.md +106 -0
  53. package/content/.morph/templates/infra/app-insights.bicep +63 -0
  54. package/content/.morph/templates/infra/container-app-env.bicep +49 -0
  55. package/content/.morph/templates/infra/container-app.bicep +156 -0
  56. package/content/.morph/templates/infra/key-vault.bicep +91 -0
  57. package/content/.morph/templates/infra/main.bicep +155 -0
  58. package/content/.morph/templates/infra/parameters.dev.json +23 -0
  59. package/content/.morph/templates/infra/parameters.prod.json +23 -0
  60. package/content/.morph/templates/infra/sql-database.bicep +103 -0
  61. package/content/.morph/templates/infra/storage.bicep +106 -0
  62. package/content/.morph/templates/integrations/asaas-client.cs +387 -0
  63. package/content/.morph/templates/integrations/asaas-webhook.cs +351 -0
  64. package/content/.morph/templates/integrations/azure-identity-config.cs +288 -0
  65. package/content/.morph/templates/integrations/clerk-config.cs +258 -0
  66. package/content/.morph/templates/job.cs +171 -0
  67. package/content/.morph/templates/migration.cs +83 -0
  68. package/content/.morph/templates/proposal.md +155 -0
  69. package/content/.morph/templates/recap.md +105 -0
  70. package/content/.morph/templates/repository.cs +141 -0
  71. package/content/.morph/templates/saas/subscription.cs +347 -0
  72. package/content/.morph/templates/saas/tenant.cs +338 -0
  73. package/content/.morph/templates/service.cs +139 -0
  74. package/content/.morph/templates/spec.md +147 -0
  75. package/content/.morph/templates/tasks.md +235 -0
  76. package/content/.morph/templates/test.cs +239 -0
  77. package/content/CLAUDE.md +318 -0
  78. package/package.json +50 -0
  79. package/src/commands/doctor.js +132 -0
  80. package/src/commands/init.js +121 -0
  81. package/src/commands/update.js +84 -0
  82. package/src/utils/file-copier.js +50 -0
  83. package/src/utils/logger.js +32 -0
@@ -0,0 +1,352 @@
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 9+ / C# 13+ |
10
+ | **Frontend** | Blazor Server |
11
+ | **Database** | Entity Framework Core 9 + Azure SQL |
12
+ | **Hosting** | Azure Container Apps |
13
+ | **Background** | Hangfire |
14
+ | **AI** | Microsoft Agent Framework |
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>net9.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
+ ## Documentação de Referência
333
+
334
+ - [Blazor Documentation](https://learn.microsoft.com/en-us/aspnet/core/blazor/)
335
+ - [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/)
336
+ - [ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/)
337
+ - [Hangfire](https://docs.hangfire.io/)
338
+
339
+ ## Checklist de Projeto
340
+
341
+ - [ ] Estrutura de camadas (Domain, Application, Infrastructure, Web)
342
+ - [ ] EF Core configurado com migrations
343
+ - [ ] Blazor Server com componentes reutilizáveis
344
+ - [ ] Services com injeção de dependência
345
+ - [ ] Logging estruturado
346
+ - [ ] Validação com FluentValidation ou DataAnnotations
347
+ - [ ] Hangfire para background jobs
348
+ - [ ] Dockerfile para containerização
349
+
350
+ ---
351
+
352
+ *MORPH-SPEC by Polymorphism Tech*