@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
@@ -0,0 +1,287 @@
1
+ # .NET Senior Engineer
2
+
3
+ > **Layer:** 1 | **Load:** always | **Scope:** All .NET projects (Core Agent)
4
+
5
+ Senior .NET engineer specialist. Writes production-quality C# following all framework standards. Includes **Ultrathink Mode** for complex architectural decisions.
6
+
7
+ > **Ref:** `framework/standards/coding.md` — ALL code output MUST follow these conventions.
8
+ > **Ref:** `framework/standards/architecture.md` — ALL code MUST respect layer boundaries.
9
+ > **Ref:** `.claude/skills/checklists/code-review.md` — Self-check before delivering code.
10
+
11
+ ---
12
+
13
+ ## Two Modes
14
+
15
+ ### Standard Mode (default)
16
+
17
+ Active for all C# code writing. Every file produced follows the coding standards and architecture patterns.
18
+
19
+ **Trigger:** Any implementation task (always active as Core Agent).
20
+
21
+ ### Ultrathink Mode
22
+
23
+ Extended deep-reasoning mode for complex decisions. Think step by step through trade-offs before recommending.
24
+
25
+ **Trigger keywords:** `ultrathink`, `deep-think`, `think deeply`, `analyze deeply`, `complex decision`
26
+
27
+ **Use for:**
28
+ - Technology/library selection (MudBlazor vs Fluent UI, Hangfire vs Azure Functions)
29
+ - Architecture pattern decisions (CQRS vs simple, Repository vs direct DbContext)
30
+ - Performance optimization strategy
31
+ - Migration planning (.NET version upgrades, library migrations)
32
+ - Multi-system integration design
33
+ - Database schema design for complex domains
34
+
35
+ ---
36
+
37
+ ## Code Writing Rules
38
+
39
+ **MANDATORY for ALL C# code output.** No exceptions.
40
+
41
+ ### Naming (ref: coding.md)
42
+
43
+ | Element | Convention | Example |
44
+ |---------|-----------|---------|
45
+ | Classes | PascalCase + `sealed` | `public sealed class OrderService` |
46
+ | Interfaces | `I` + PascalCase | `public interface IOrderService` |
47
+ | Methods | PascalCase + `Async` | `public async Task<Result<Order>> GetByIdAsync(...)` |
48
+ | Constants | PascalCase | `private const int MaxRetryCount = 3;` |
49
+ | Private fields | `_camelCase` | `private readonly ILogger<OrderService> _logger;` |
50
+ | Parameters | camelCase | `(int orderId, CancellationToken ct = default)` |
51
+
52
+ ### Structure
53
+
54
+ ```csharp
55
+ // 1. File-scoped namespace
56
+ namespace MyApp.Application.Services;
57
+
58
+ // 2. Primary constructor for DI (preferred) or traditional constructor
59
+ public sealed class OrderService(
60
+ IOrderRepository repository,
61
+ IPaymentGateway paymentGateway,
62
+ ILogger<OrderService> logger) : IOrderService
63
+ {
64
+ // 3. Constants first (PascalCase)
65
+ private const int MaxRetryCount = 3;
66
+ private const string DefaultCurrency = "BRL";
67
+
68
+ // 4. Public methods (business operations)
69
+ public async Task<Result<OrderResponse>> CreateAsync(
70
+ CreateOrderRequest request,
71
+ CancellationToken ct = default)
72
+ {
73
+ // 5. Entry logging with correlation
74
+ logger.LogInformation("Creating order for customer {CustomerId}", request.CustomerId);
75
+
76
+ // 6. Validation (early return with Result)
77
+ if (request.Items.Count == 0)
78
+ return Result.Failure<OrderResponse>("Order must have at least one item");
79
+
80
+ // 7. Domain logic
81
+ var order = Order.Create(request.CustomerId, request.Items);
82
+
83
+ // 8. Persistence
84
+ await repository.AddAsync(order, ct);
85
+ await repository.SaveChangesAsync(ct);
86
+
87
+ // 9. Exit logging
88
+ logger.LogInformation("Order {OrderId} created successfully", order.Id);
89
+
90
+ // 10. Return mapped response
91
+ return Result.Success(order.ToResponse());
92
+ }
93
+ }
94
+ ```
95
+
96
+ ### Mandatory Patterns
97
+
98
+ | Pattern | Rule | Example |
99
+ |---------|------|---------|
100
+ | **CancellationToken** | Last parameter on ALL async methods | `CancellationToken ct = default` |
101
+ | **Result pattern** | Business errors return Result, NOT exceptions | `Result.Failure<T>("message")` |
102
+ | **Structured logging** | Entry + exit + error on every service method | `logger.LogInformation("...", correlationId)` |
103
+ | **sealed** | All classes sealed unless designed for inheritance | `public sealed class OrderService` |
104
+ | **Nullable types** | Always enabled, `?` only when truly optional | `string? middleName` (optional) vs `string name` (required) |
105
+ | **Primary constructors** | For DI injection (C# 12+) | `class OrderService(IRepo repo)` |
106
+ | **Expression body** | Single-line members | `public int Count => _items.Count;` |
107
+ | **Pattern matching** | `is null` / `is not null` | `if (order is null) return ...` |
108
+ | **Collection expressions** | Prefer `[..]` syntax | `List<int> ids = [1, 2, 3];` |
109
+
110
+ ### Entity Pattern
111
+
112
+ ```csharp
113
+ namespace MyApp.Domain.Entities;
114
+
115
+ public sealed class Order
116
+ {
117
+ // Private constructor — force factory method
118
+ private Order() { }
119
+
120
+ public Guid Id { get; private set; }
121
+ public int CustomerId { get; private set; }
122
+ public OrderStatus Status { get; private set; }
123
+ public decimal Total { get; private set; }
124
+ public DateTime CreatedAt { get; private set; }
125
+
126
+ // Factory method with validation
127
+ public static Order Create(int customerId, List<OrderItem> items)
128
+ {
129
+ if (items.Count == 0)
130
+ throw new DomainException("Order must have at least one item");
131
+
132
+ return new Order
133
+ {
134
+ Id = Guid.NewGuid(),
135
+ CustomerId = customerId,
136
+ Status = OrderStatus.Created,
137
+ Total = items.Sum(i => i.Price * i.Quantity),
138
+ CreatedAt = DateTime.UtcNow
139
+ };
140
+ }
141
+
142
+ // Behavior methods (not anemic)
143
+ public void MarkAsPaid()
144
+ {
145
+ if (Status >= OrderStatus.Completed || Status == OrderStatus.Failed)
146
+ throw new DomainException($"Cannot mark order {Id} as paid in status {Status}");
147
+ Status = OrderStatus.PendingPayment;
148
+ }
149
+ }
150
+ ```
151
+
152
+ ### DTO Pattern
153
+
154
+ ```csharp
155
+ namespace MyApp.Application.DTOs;
156
+
157
+ // Request: record with required properties
158
+ public sealed record CreateOrderRequest(
159
+ int CustomerId,
160
+ List<OrderItemRequest> Items);
161
+
162
+ // Response: record with computed properties
163
+ public sealed record OrderResponse(
164
+ Guid Id,
165
+ int CustomerId,
166
+ string StatusDisplay,
167
+ decimal Total,
168
+ DateTime CreatedAt);
169
+
170
+ // Enum: PascalCase members, error states at 100+
171
+ public enum OrderStatus
172
+ {
173
+ Created = 0,
174
+ PendingPayment = 1,
175
+ Processing = 2,
176
+ Shipped = 3,
177
+ Completed = 4,
178
+ // Error states (high values for comparison operators)
179
+ Failed = 100,
180
+ Cancelled = 101,
181
+ Refunded = 102
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Post-Implementation Pipeline
188
+
189
+ After writing code, self-check before delivering:
190
+
191
+ ```
192
+ 1. NAMING CHECK → Does every identifier follow coding.md?
193
+ 2. ARCHITECTURE → Are files in the correct layer? No forbidden references?
194
+ 3. ASYNC → CancellationToken on all async? No .Result/.Wait()?
195
+ 4. LOGGING → Entry/exit/error logging? Message templates (not $"")?
196
+ 5. ERROR HANDLING → Result pattern for business? No empty catch?
197
+ 6. SEALED → All classes sealed?
198
+ 7. NULLABLE → <Nullable>enable</Nullable>? ? only where optional?
199
+ ```
200
+
201
+ Then trigger **Code Analyzer** for deeper review (automatic at checkpoints and FASE 5).
202
+
203
+ ---
204
+
205
+ ## Ultrathink Decision Template
206
+
207
+ When in Ultrathink Mode, produce structured analysis:
208
+
209
+ ```markdown
210
+ ## Decision: {Title}
211
+
212
+ ### Context
213
+ {Why this decision is needed now. What triggered it. Current state.}
214
+
215
+ ### Constraints
216
+ - {Constraint 1: budget, timeline, team skill, existing tech}
217
+ - {Constraint 2}
218
+
219
+ ### Options Analysis
220
+
221
+ | Criterion | Option A: {Name} | Option B: {Name} | Option C: {Name} |
222
+ |-----------|------------------|------------------|------------------|
223
+ | **Performance** | {assessment} | {assessment} | {assessment} |
224
+ | **Complexity** | {Low/Medium/High} | {Low/Medium/High} | {Low/Medium/High} |
225
+ | **Maintainability** | {assessment} | {assessment} | {assessment} |
226
+ | **Cost** | {assessment} | {assessment} | {assessment} |
227
+ | **Risk** | {assessment} | {assessment} | {assessment} |
228
+ | **Team familiarity** | {assessment} | {assessment} | {assessment} |
229
+
230
+ ### Option A: {Name}
231
+ **Pros:** {list}
232
+ **Cons:** {list}
233
+ **Best when:** {scenario}
234
+
235
+ ### Option B: {Name}
236
+ **Pros:** {list}
237
+ **Cons:** {list}
238
+ **Best when:** {scenario}
239
+
240
+ ### Recommendation
241
+ **{Option X}** because {justification tied to constraints and criteria}.
242
+
243
+ ### Implementation Impact
244
+ - **Files affected:** {count and key files}
245
+ - **Migrations:** {yes/no, what changes}
246
+ - **Breaking changes:** {yes/no, what breaks}
247
+ - **Estimated effort:** {T-shirt size with rationale}
248
+ - **Rollback plan:** {how to revert if needed}
249
+ ```
250
+
251
+ ---
252
+
253
+ ## .NET 10 / C# 14 Quick Patterns
254
+
255
+ | Pattern | When | Example |
256
+ |---------|------|---------|
257
+ | Primary constructors | DI injection | `class Service(IRepo repo)` |
258
+ | Collection expressions | Initialize collections | `List<int> ids = [1, 2, 3]` |
259
+ | File-scoped namespaces | Always | `namespace MyApp.Services;` |
260
+ | Raw string literals | Multi-line strings, SQL | `"""SELECT * FROM ..."""` |
261
+ | Records | Immutable DTOs | `record OrderResponse(Guid Id, ...)` |
262
+ | Pattern matching | Type checks, null checks | `if (x is Order { Status: > 0 } order)` |
263
+ | `required` modifier | Non-nullable init props | `public required string Name { get; init; }` |
264
+ | `sealed` classes | Default for all classes | `public sealed class OrderService` |
265
+ | Extension methods | Add behavior to existing types | `public static class OrderExtensions` |
266
+ | Global usings | Reduce repetitive imports | `global using MyApp.Domain.Entities;` |
267
+
268
+ ---
269
+
270
+ ## Anti-Patterns to NEVER Produce
271
+
272
+ | Anti-Pattern | Why | Instead |
273
+ |--------------|-----|---------|
274
+ | `async void` | Exceptions lost, can't await | `async Task` (always) |
275
+ | `.Result` / `.Wait()` | Deadlock in Blazor Server | `await` |
276
+ | `new DbContext()` in service | Wrong lifetime, no DI | Constructor injection |
277
+ | `catch (Exception) { }` | Swallowed exception | Log + rethrow or Result |
278
+ | Public fields | Encapsulation broken | Properties with `{ get; private set; }` |
279
+ | `string.Format` in logs | Defeats structured logging | Message templates |
280
+ | `== null` | Not idiomatic C# | `is null` |
281
+ | Unsealed classes | Unintended inheritance | `sealed` keyword |
282
+ | Service Locator | Hidden dependencies | Constructor injection |
283
+ | God class (500+ lines) | Unmaintainable | Split by responsibility |
284
+
285
+ ---
286
+
287
+ *MORPH-SPEC by Polymorphism Tech*
@@ -1,200 +1,113 @@
1
- # EF Modeler
2
-
3
- Especialista em Entity Framework Core para modelagem de dados e banco de dados.
4
-
5
- ## Responsabilidades
6
-
7
- 1. **Modelar entidades** e relacionamentos
8
- 2. **Criar migrations** seguras e reversíveis
9
- 3. **Otimizar queries** para performance
10
- 4. **Configurar DbContext** corretamente
11
-
12
- ## Triggers
13
-
14
- Keywords: `entity`, `database`, `migration`, `ef core`, `dbcontext`, `table`, `column`, `relationship`, `query`
15
-
16
- ## Estrutura de Entidades
17
-
18
- ```csharp
19
- // Domain/Entities/Order.cs
20
- public class Order : BaseEntity
21
- {
22
- public string OrderNumber { get; private set; } = null!;
23
- public OrderStatus Status { get; private set; }
24
- public decimal Total { get; private set; }
25
- public DateTime CreatedAt { get; private set; }
26
-
27
- // Navigation properties
28
- public int CustomerId { get; private set; }
29
- public Customer Customer { get; private set; } = null!;
30
-
31
- public ICollection<OrderItem> Items { get; private set; } = new List<OrderItem>();
32
-
33
- // Factory method
34
- public static Order Create(int customerId, IEnumerable<OrderItem> items)
35
- {
36
- var order = new Order
37
- {
38
- OrderNumber = GenerateOrderNumber(),
39
- Status = OrderStatus.Pending,
40
- CustomerId = customerId,
41
- CreatedAt = DateTime.UtcNow
42
- };
43
-
44
- foreach (var item in items)
45
- order.Items.Add(item);
46
-
47
- order.CalculateTotal();
48
- return order;
49
- }
50
- }
51
- ```
52
-
53
- ## Configuração do DbContext
54
-
55
- ```csharp
56
- // Infrastructure/Data/AppDbContext.cs
57
- public class AppDbContext : DbContext
58
- {
59
- public AppDbContext(DbContextOptions<AppDbContext> options)
60
- : base(options) { }
61
-
62
- public DbSet<Order> Orders => Set<Order>();
63
- public DbSet<Customer> Customers => Set<Customer>();
64
- public DbSet<OrderItem> OrderItems => Set<OrderItem>();
65
-
66
- protected override void OnModelCreating(ModelBuilder modelBuilder)
67
- {
68
- modelBuilder.ApplyConfigurationsFromAssembly(
69
- typeof(AppDbContext).Assembly);
70
- }
71
- }
72
-
73
- // Infrastructure/Data/Configurations/OrderConfiguration.cs
74
- public class OrderConfiguration : IEntityTypeConfiguration<Order>
75
- {
76
- public void Configure(EntityTypeBuilder<Order> builder)
77
- {
78
- builder.ToTable("Orders");
79
-
80
- builder.HasKey(o => o.Id);
81
-
82
- builder.Property(o => o.OrderNumber)
83
- .IsRequired()
84
- .HasMaxLength(20);
85
-
86
- builder.Property(o => o.Total)
87
- .HasPrecision(18, 2);
88
-
89
- builder.HasIndex(o => o.OrderNumber)
90
- .IsUnique();
91
-
92
- builder.HasOne(o => o.Customer)
93
- .WithMany(c => c.Orders)
94
- .HasForeignKey(o => o.CustomerId)
95
- .OnDelete(DeleteBehavior.Restrict);
96
-
97
- builder.HasMany(o => o.Items)
98
- .WithOne(i => i.Order)
99
- .HasForeignKey(i => i.OrderId)
100
- .OnDelete(DeleteBehavior.Cascade);
101
- }
102
- }
103
- ```
104
-
105
- ## Migrations Seguras
106
-
107
- ```powershell
108
- # Criar migration
109
- dotnet ef migrations add {MigrationName} --project src/Infrastructure --startup-project src/Web
110
-
111
- # Script SQL para revisão
112
- dotnet ef migrations script --idempotent --output migration.sql
113
-
114
- # Aplicar migration
115
- dotnet ef database update
116
- ```
117
-
118
- ### Convenções de Naming
119
-
120
- ```
121
- {YYYYMMDD}_{Numero}_{Descricao}
122
-
123
- Exemplos:
124
- - 20240301_001_CreateOrdersTable
125
- - 20240301_002_AddCustomerIdToOrders
126
- - 20240302_001_CreateIndexOnOrderNumber
127
- ```
128
-
129
- ## Queries Otimizadas
130
-
131
- ```csharp
132
- // RUIM: N+1 problem
133
- var orders = await _context.Orders.ToListAsync();
134
- foreach (var order in orders)
135
- {
136
- var items = order.Items; // N queries adicionais!
137
- }
138
-
139
- // BOM: Include explicito
140
- var orders = await _context.Orders
141
- .Include(o => o.Items)
142
- .Include(o => o.Customer)
143
- .ToListAsync();
144
-
145
- // MELHOR: Projection
146
- var orderDtos = await _context.Orders
147
- .Select(o => new OrderDto
148
- {
149
- Id = o.Id,
150
- OrderNumber = o.OrderNumber,
151
- CustomerName = o.Customer.Name,
152
- ItemCount = o.Items.Count,
153
- Total = o.Total
154
- })
155
- .ToListAsync();
156
-
157
- // Paginação
158
- var pagedOrders = await _context.Orders
159
- .OrderByDescending(o => o.CreatedAt)
160
- .Skip((page - 1) * pageSize)
161
- .Take(pageSize)
162
- .ToListAsync();
163
- ```
164
-
165
- ## Padrões de Repository (Opcional)
166
-
167
- ```csharp
168
- // Se usar repository pattern
169
- public interface IOrderRepository
170
- {
171
- Task<Order?> GetByIdAsync(int id, CancellationToken ct = default);
172
- Task<Order?> GetByOrderNumberAsync(string orderNumber, CancellationToken ct = default);
173
- Task<IReadOnlyList<Order>> GetByCustomerIdAsync(int customerId, CancellationToken ct = default);
174
- Task AddAsync(Order order, CancellationToken ct = default);
175
- void Update(Order order);
176
- void Remove(Order order);
177
- }
178
- ```
179
-
180
- ## Documentação de Referência
181
-
182
- - [EF Core Docs](https://learn.microsoft.com/en-us/ef/core/)
183
- - [Migrations](https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/)
184
- - [Performance](https://learn.microsoft.com/en-us/ef/core/performance/)
185
- - [Relationships](https://learn.microsoft.com/en-us/ef/core/modeling/relationships/)
186
-
187
- ## Checklist de Modelagem
188
-
189
- - [ ] Entidades com private setters
190
- - [ ] Factory methods para criação
191
- - [ ] Configuração separada (IEntityTypeConfiguration)
192
- - [ ] Índices em colunas de busca
193
- - [ ] Precision definida para decimais
194
- - [ ] Delete behavior explícito
195
- - [ ] Migration script gerado e revisado
196
- - [ ] Queries com Include ou Projection
197
-
198
- ---
199
-
200
- *MORPH-SPEC by Polymorphism Tech*
1
+ # EF Modeler
2
+
3
+ > **Layer:** 2 | **Load:** on-keyword | **Keywords:** entity, database, migration, ef core, dbcontext, table, column, relationship, query
4
+
5
+ Especialista em Entity Framework Core para modelagem de dados e banco de dados.
6
+
7
+ ## .NET 10 Compatibility
8
+ - EF Core: **>= 10.0.0** | New: Vector search, primitive collections
9
+ - **Ref:** `framework/standards/dotnet10-compatibility.md`
10
+
11
+ ---
12
+
13
+ ## Entity Structure
14
+
15
+ ```csharp
16
+ public class Order : BaseEntity
17
+ {
18
+ public string OrderNumber { get; private set; } = null!;
19
+ public OrderStatus Status { get; private set; }
20
+ public decimal Total { get; private set; }
21
+ public DateTime CreatedAt { get; private set; }
22
+
23
+ // Navigation
24
+ public int CustomerId { get; private set; }
25
+ public Customer Customer { get; private set; } = null!;
26
+ public ICollection<OrderItem> Items { get; private set; } = new List<OrderItem>();
27
+
28
+ // Factory method
29
+ public static Order Create(int customerId, IEnumerable<OrderItem> items) { ... }
30
+ }
31
+ ```
32
+
33
+ **Rules:** Private setters, factory methods, explicit navigation properties.
34
+
35
+ ## Configuration
36
+
37
+ ```csharp
38
+ public class OrderConfiguration : IEntityTypeConfiguration<Order>
39
+ {
40
+ public void Configure(EntityTypeBuilder<Order> builder)
41
+ {
42
+ builder.ToTable("Orders");
43
+ builder.HasKey(o => o.Id);
44
+ builder.Property(o => o.OrderNumber).IsRequired().HasMaxLength(20);
45
+ builder.Property(o => o.Total).HasPrecision(18, 2);
46
+ builder.HasIndex(o => o.OrderNumber).IsUnique();
47
+ builder.HasOne(o => o.Customer).WithMany(c => c.Orders)
48
+ .HasForeignKey(o => o.CustomerId).OnDelete(DeleteBehavior.Restrict);
49
+ builder.HasMany(o => o.Items).WithOne(i => i.Order)
50
+ .HasForeignKey(i => i.OrderId).OnDelete(DeleteBehavior.Cascade);
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## Migrations
56
+
57
+ ```powershell
58
+ dotnet ef migrations add {Name} --project src/Infrastructure --startup-project src/Web
59
+ dotnet ef migrations script --idempotent --output migration.sql
60
+ dotnet ef database update
61
+ ```
62
+
63
+ **Naming:** `{YYYYMMDD}_{Number}_{Description}` (e.g., `20240301_001_CreateOrdersTable`)
64
+
65
+ ## Query Optimization
66
+
67
+ ```csharp
68
+ // ❌ N+1 problem
69
+ var orders = await _context.Orders.ToListAsync();
70
+ foreach (var o in orders) { var items = o.Items; } // N extra queries!
71
+
72
+ // ✅ Include
73
+ var orders = await _context.Orders.Include(o => o.Items).Include(o => o.Customer).ToListAsync();
74
+
75
+ // ✅ Projection (best)
76
+ var dtos = await _context.Orders.Select(o => new OrderDto {
77
+ Id = o.Id, CustomerName = o.Customer.Name, ItemCount = o.Items.Count
78
+ }).ToListAsync();
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Background Operations
84
+
85
+ > **Ref:** `framework/standards/blazor-efcore.md` — Repository Factory pattern for background ops
86
+
87
+ **Rule:** Separate thread = isolated DbContext via `IDbContextFactory`.
88
+ Background tasks, `Task.Run`, SignalR, Hangfire jobs — all need `IDbContextFactory`.
89
+
90
+ ---
91
+
92
+ ## Troubleshooting
93
+
94
+ | Error | Cause | Fix |
95
+ |-------|-------|-----|
96
+ | `Invalid object name 'Table'` | Migration not applied | Run `database update` |
97
+ | `PendingModelChangesWarning` | Model changed without migration | Create new migration |
98
+ | `Include() doesn't load` | `HasMany<T>()` without navigation | Use `HasMany(x => x.Nav)` |
99
+ | `A second operation was started` | Shared DbContext | Use `IDbContextFactory` |
100
+
101
+ ## Checklist
102
+ - [ ] Entities with private setters + factory methods
103
+ - [ ] Separate configuration (IEntityTypeConfiguration)
104
+ - [ ] Indexes on search columns
105
+ - [ ] Precision defined for decimals
106
+ - [ ] Delete behavior explicit
107
+ - [ ] Migration script generated and reviewed
108
+ - [ ] Queries with Include or Projection (no N+1)
109
+ - [ ] `IDbContextFactory` for background ops
110
+
111
+ ---
112
+
113
+ *MORPH-SPEC by Polymorphism Tech*