@polymorphism-tech/morph-spec 4.8.1 → 4.8.4

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 (44) hide show
  1. package/README.md +2 -2
  2. package/claude-plugin.json +1 -1
  3. package/docs/CHEATSHEET.md +1 -1
  4. package/docs/QUICKSTART.md +1 -1
  5. package/framework/hooks/dev/guard-version-numbers.js +1 -1
  6. package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +1 -1
  7. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +1 -1
  8. package/framework/skills/level-1-workflows/phase-design/SKILL.md +1 -1
  9. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +1 -1
  10. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +1 -1
  11. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +1 -1
  12. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +1 -1
  13. package/package.json +4 -4
  14. package/.morph/analytics/threads-log.jsonl +0 -54
  15. package/.morph/state.json +0 -198
  16. package/docs/ARCHITECTURE.md +0 -328
  17. package/docs/COMMAND-FLOWS.md +0 -398
  18. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -514
  19. package/docs/plans/2026-02-22-claude-settings.md +0 -517
  20. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -730
  21. package/docs/plans/2026-02-22-morph-spec-next.md +0 -480
  22. package/docs/plans/2026-02-22-native-alignment-design.md +0 -201
  23. package/docs/plans/2026-02-22-native-alignment-impl.md +0 -927
  24. package/docs/plans/2026-02-22-native-enrichment-design.md +0 -246
  25. package/docs/plans/2026-02-22-native-enrichment.md +0 -737
  26. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1155
  27. package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -684
  28. package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -439
  29. package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -157
  30. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1256
  31. package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -150
  32. package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1848
  33. package/docs/plans/2026-02-24-cli-radical-simplification.md +0 -592
  34. package/docs/plans/2026-02-24-framework-failure-points.md +0 -125
  35. package/docs/plans/2026-02-24-morph-init-design.md +0 -337
  36. package/docs/plans/2026-02-24-morph-init-impl.md +0 -1269
  37. package/docs/plans/2026-02-24-tutorial-command-design.md +0 -71
  38. package/docs/plans/2026-02-24-tutorial-command.md +0 -298
  39. package/scripts/bump-version.js +0 -248
  40. package/scripts/generate-refs.js +0 -336
  41. package/scripts/generate-standards-registry.js +0 -44
  42. package/scripts/install-dev-hooks.js +0 -138
  43. package/scripts/scan-nextjs.mjs +0 -169
  44. package/scripts/validate-real.mjs +0 -255
@@ -1,684 +0,0 @@
1
- # DDD Next Steps Implementation Plan
2
-
3
- **Status:** COMPLETE
4
-
5
- > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
6
-
7
- **Goal:** Fechar os 5 gaps pós-refactor DDD: instalação nativa do domain-architect, remoção do template legado contracts.cs, phase-tasks DDD-aware, system prompt enriquecido do domain-architect, e exemplo end-to-end de feature Level 2.
8
-
9
- **Architecture:** Cada task é independente e toca uma camada diferente: agents-installer (JS), templates (remoção + registry), skills (markdown), agents.json (JSON), e docs/examples (markdown). Nenhuma task depende de outra para executar.
10
-
11
- **Tech Stack:** Node.js ESM, `node:test`, Handlebars v2.0, JSON, Markdown.
12
-
13
- ---
14
-
15
- ## Contexto Crítico
16
-
17
- - Worktree: criar em `.worktrees/feat-ddd-nextsteps` a partir de `main`
18
- - Test suite baseline: 659 pass, 0 fail, 1 skip
19
- - `src/utils/agents-installer.js` — filtra tier 1+2, instala `morph-{id}.md` em `.claude/agents/`
20
- - `framework/agents.json` v3.2.0-hierarchical — `domain-architect` é tier 2, `always_active: true`
21
- - Arquivos com referência ao template legado `contracts.cs`:
22
- - `framework/skills/level-1-workflows/phase-design/SKILL.md` (linha 38)
23
- - `framework/skills/level-0-meta/tool-usage-guide/SKILL.md` (linha ~144)
24
- - `framework/templates/REGISTRY.json` (entrada `code/dotnet/contracts/contracts.cs`)
25
- - `framework/templates/code/dotnet/contracts/contracts.cs` (o próprio arquivo — DELETAR)
26
- - `framework/templates/code/dotnet/contracts/contracts.cs.hbs` (se existir — DELETAR)
27
-
28
- ---
29
-
30
- ## Task 1: domain-architect como native subagent — verificar + testar
31
-
32
- **Files:**
33
- - Modify: `test/utils/agents-installer.test.js`
34
-
35
- **Step 1: Verificar que domain-architect está sendo instalado**
36
-
37
- ```bash
38
- node -e "
39
- import { installAgents } from './src/utils/agents-installer.js';
40
- import { mkdtempSync } from 'fs';
41
- import { tmpdir } from 'os';
42
- import { join } from 'path';
43
-
44
- const out = mkdtempSync(join(tmpdir(), 'morph-test-'));
45
- await installAgents(process.cwd(), out);
46
- const files = require('fs').readdirSync(join(out, '.claude', 'agents'));
47
- console.log(files.filter(f => f.includes('domain-architect')));
48
- " --input-type=module
49
- ```
50
-
51
- **Forma mais simples — usar o executável:**
52
- ```bash
53
- node --test test/utils/agents-installer.test.js 2>&1 | grep -i "domain"
54
- ```
55
-
56
- **Step 2: Ler `test/utils/agents-installer.test.js` para entender a estrutura atual**
57
-
58
- ```bash
59
- # Procurar onde estão os testes de agent names específicos
60
- grep -n "domain\|tier.*2\|morph-" test/utils/agents-installer.test.js | head -20
61
- ```
62
-
63
- **Step 3: Escrever o failing test** — adicionar dentro da suite `installAgents` existente:
64
-
65
- ```javascript
66
- test('installs domain-architect as morph-domain-architect.md', async () => {
67
- const { agentFiles, agentsDir } = await setupInstall();
68
- const file = agentFiles.find(f => f === 'morph-domain-architect.md');
69
- assert.ok(file, 'morph-domain-architect.md must be installed');
70
-
71
- const content = readFileSync(join(agentsDir, file), 'utf8');
72
- assert.ok(content.includes('domain-architect') || content.includes('Domain Modeling'),
73
- 'File must reference domain-architect');
74
- assert.ok(content.includes('ddd') || content.includes('aggregate') || content.includes('complexity'),
75
- 'File must mention DDD concepts');
76
- });
77
-
78
- test('domain-architect is installed with tier-2 defaults (no Task tool)', async () => {
79
- const { agentFiles, agentsDir } = await setupInstall();
80
- const content = readFileSync(join(agentsDir, 'morph-domain-architect.md'), 'utf8');
81
- assert.ok(!content.includes('Task'), 'Tier-2 agent must NOT have Task tool');
82
- assert.match(content, /maxTurns.*20/, 'Tier-2 agent must have maxTurns: 20');
83
- });
84
- ```
85
-
86
- > **Nota:** `setupInstall` é o helper já existente no test file — leia o arquivo para entender o padrão exato antes de escrever os testes.
87
-
88
- **Step 4: Rodar para ver falhar**
89
-
90
- ```bash
91
- node --test test/utils/agents-installer.test.js 2>&1 | grep -E "pass|fail"
92
- ```
93
-
94
- Esperado: novos testes falham (domain-architect não encontrado) OU já passam (se já instalado).
95
-
96
- Se já passam: os testes são válidos como regressão. Commit assim mesmo.
97
- Se falham: investigar o agente no agents.json — verificar se `tier: 2` está correto.
98
-
99
- **Step 5: Rodar suite para confirmar nenhuma regressão**
100
-
101
- ```bash
102
- node --test test/utils/agents-installer.test.js 2>&1 | grep -E "# (pass|fail)"
103
- ```
104
-
105
- **Step 6: Commit**
106
-
107
- ```bash
108
- git add test/utils/agents-installer.test.js
109
- git commit -m "test(agents): add domain-architect native subagent installation tests"
110
- ```
111
-
112
- ---
113
-
114
- ## Task 2: Remover template legado contracts.cs + atualizar referências
115
-
116
- **Files:**
117
- - Delete: `framework/templates/code/dotnet/contracts/contracts.cs`
118
- - Delete: `framework/templates/code/dotnet/contracts/contracts.cs.hbs` (se existir)
119
- - Modify: `framework/skills/level-1-workflows/phase-design/SKILL.md`
120
- - Modify: `framework/skills/level-0-meta/tool-usage-guide/SKILL.md`
121
- - Modify: `framework/templates/REGISTRY.json`
122
- - Modify: `test/templates/contracts-levels.test.js` (adicionar teste de ausência)
123
-
124
- **Step 1: Confirmar quais arquivos existem e todas as referências**
125
-
126
- ```bash
127
- ls framework/templates/code/dotnet/contracts/
128
- grep -rn "contracts\.cs" framework/skills/ framework/templates/ .claude/skills/ --include="*.md" --include="*.json" | grep -v "level1\|level2\|level3\|contracts-level"
129
- ```
130
-
131
- **Step 2: Deletar o template legado**
132
-
133
- ```bash
134
- rm framework/templates/code/dotnet/contracts/contracts.cs
135
- # Se existir:
136
- rm -f "framework/templates/code/dotnet/contracts/contracts.cs.hbs"
137
- ```
138
-
139
- **Step 3: Atualizar `framework/templates/REGISTRY.json`**
140
-
141
- Remover a entrada com `"path": "code/dotnet/contracts/contracts.cs"`.
142
-
143
- Verificar: `node -e "const r=JSON.parse(require('fs').readFileSync('framework/templates/REGISTRY.json')); console.log(r.templates?.filter(t=>t.path?.includes('contracts.cs')&&!t.path?.includes('level')))"`
144
-
145
- Esperado: array vazio.
146
-
147
- **Step 4: Atualizar `framework/skills/level-1-workflows/phase-design/SKILL.md`**
148
-
149
- Localizar a linha na tabela "Ferramentas Recomendadas" que diz:
150
- ```
151
- | Renderizar template contracts.cs | **Bash** `npx morph-spec template render code/dotnet/contracts/contracts.cs ...` | — |
152
- ```
153
-
154
- Substituir por:
155
- ```
156
- | Renderizar template contracts (nível detectado) | **Bash** `npx morph-spec template render code/dotnet/contracts/contracts-level{N}.cs ...` onde N = nível detectado no Passo 1.5 | — |
157
- ```
158
-
159
- **Step 5: Atualizar `framework/skills/level-0-meta/tool-usage-guide/SKILL.md`**
160
-
161
- Localizar a linha que referencia `contracts.cs` genérico (~linha 144) e substituir pela versão com level{N}.
162
-
163
- **Step 6: Adicionar teste de ausência em `test/templates/contracts-levels.test.js`**
164
-
165
- ```javascript
166
- test('legacy contracts.cs template no longer exists', () => {
167
- const legacyPath = join(FRAMEWORK_DIR, 'templates', 'code', 'dotnet', 'contracts', 'contracts.cs');
168
- assert.throws(
169
- () => readFileSync(legacyPath),
170
- { code: 'ENOENT' },
171
- 'Legacy contracts.cs must not exist — use contracts-level1/2/3.cs instead'
172
- );
173
- });
174
- ```
175
-
176
- **Step 7: Rodar testes**
177
-
178
- ```bash
179
- node --test test/templates/contracts-levels.test.js 2>&1 | grep -E "# (pass|fail)"
180
- ```
181
- Esperado: 8 pass (7 anteriores + 1 novo), 0 fail.
182
-
183
- **Step 8: Rodar suite completa**
184
-
185
- ```bash
186
- node --test 2>&1 | grep -E "# (pass|fail)"
187
- ```
188
- Esperado: 0 fail.
189
-
190
- **Step 9: Commit**
191
-
192
- ```bash
193
- git add -A framework/templates/code/dotnet/contracts/ \
194
- framework/templates/REGISTRY.json \
195
- framework/skills/level-1-workflows/phase-design/SKILL.md \
196
- framework/skills/level-0-meta/tool-usage-guide/SKILL.md \
197
- test/templates/contracts-levels.test.js
198
- git commit -m "feat(templates): remove legacy contracts.cs — level1/2/3 are the only contracts templates"
199
- ```
200
-
201
- ---
202
-
203
- ## Task 3: phase-tasks DDD-aware
204
-
205
- **Files:**
206
- - Modify: `framework/skills/level-1-workflows/phase-tasks/SKILL.md`
207
-
208
- **Step 1: Ler o arquivo atual** para entender onde inserir
209
-
210
- ```bash
211
- grep -n "Passo\|Step\|### " framework/skills/level-1-workflows/phase-tasks/SKILL.md | head -20
212
- ```
213
-
214
- **Step 2: Inserir "Passo 0" ANTES do Passo 1 atual**
215
-
216
- O Passo 0 lê o nível de domínio do spec.md e ajusta a geração de tasks:
217
-
218
- ```markdown
219
- ### Passo 0: Ler Nível de Domínio
220
-
221
- **Ref:** `framework/standards/architecture/ddd/complexity-levels.md`
222
-
223
- Antes de quebrar tasks, leia a seção `## Domain Complexity` do spec.md:
224
-
225
- ```bash
226
- # Extrair nível do spec.md
227
- grep -A2 "## Domain Complexity" .morph/features/$ARGUMENTS/1-design/spec.md
228
- ```
229
-
230
- Use o nível para ajustar as categorias de tasks:
231
-
232
- | Nível | Categorias de Tasks |
233
- |-------|---------------------|
234
- | **1 — CRUD** | `domain` (Entity simples) → `infrastructure` (Repository, EF Config) → `application` (Service CRUD) → `presentation` (API/Page) → `tests` |
235
- | **2 — Business Logic** | `domain` (AggregateRoot, ValueObjects, DomainEvents) → `infrastructure` (Repository, EF Config) → `application` (Commands, Queries, Handlers) → `presentation` (API/Page) → `tests` |
236
- | **3 — Bounded Context** | `domain-bc` (BC setup, Aggregates, Events) → `infrastructure` (BC repositories, EF) → `application` (Commands, Queries, Integration handlers) → `presentation` → `tests` |
237
-
238
- **Tasks adicionais obrigatórias por nível:**
239
-
240
- **Nível 2 only:**
241
- - `T{N}: Implementar AggregateRoot {EntityName} com factory method e invariants` (domain)
242
- - `T{N}: Implementar ValueObjects: {lista}` (domain)
243
- - `T{N}: Implementar DomainEvents: {lista}` (domain)
244
- - `T{N}: Implementar Command Handlers com MediatR` (application)
245
- - `T{N}: Implementar Query Handlers com read models` (application)
246
-
247
- **Nível 3 only (além do Nível 2):**
248
- - `T{N}: Configurar namespace/pasta do Bounded Context {BC}` (infrastructure)
249
- - `T{N}: Implementar Integration Events para comunicação cross-BC` (domain-bc)
250
- - `T{N}: Implementar handlers de Integration Events` (application)
251
-
252
- ---
253
- ```
254
-
255
- **Step 3: Verificar que a inserção está antes do Passo 1**
256
-
257
- ```bash
258
- grep -n "Passo 0\|Passo 1\|complexity" framework/skills/level-1-workflows/phase-tasks/SKILL.md | head -10
259
- ```
260
- Esperado: Passo 0 antes do Passo 1, referência a complexity-levels.md presente.
261
-
262
- **Step 4: Commit**
263
-
264
- ```bash
265
- git add framework/skills/level-1-workflows/phase-tasks/SKILL.md
266
- git commit -m "feat(skills): add Passo 0 DDD-aware task generation to phase-tasks — 3 level task templates"
267
- ```
268
-
269
- ---
270
-
271
- ## Task 4: Enriquecer system prompt do domain-architect
272
-
273
- **Files:**
274
- - Modify: `framework/agents.json`
275
-
276
- **Step 1: Ler o `spawn_prompt` atual do domain-architect**
277
-
278
- ```bash
279
- node -e "
280
- const a = JSON.parse(require('fs').readFileSync('framework/agents.json', 'utf8'));
281
- const da = a.agents.find(x => x.id === 'domain-architect');
282
- console.log(JSON.stringify(da.teammate, null, 2));
283
- "
284
- ```
285
-
286
- **Step 2: Atualizar os campos do domain-architect**
287
-
288
- Mudanças necessárias no objeto `domain-architect`:
289
-
290
- 1. `standards` — adicionar os 3 novos standards DDD:
291
- ```json
292
- "standards": [
293
- "core/coding.md",
294
- "core/architecture.md",
295
- "architecture/ddd/complexity-levels.md",
296
- "architecture/ddd/aggregates.md",
297
- "architecture/ddd/entities.md",
298
- "architecture/ddd/value-objects.md",
299
- "architecture/ddd/bounded-contexts.md",
300
- "architecture/ddd/ubiquitous-language.md"
301
- ]
302
- ```
303
-
304
- 2. `teammate.spawn_prompt` — substituir pelo prompt enriquecido:
305
- ```
306
- You are the Domain Modeling Leader for MORPH-SPEC. Your primary responsibility is detecting the correct domain complexity level and producing the Aggregate Blueprint before any contracts are generated.
307
-
308
- ALWAYS start with the 5-question complexity detection:
309
- 1. Does the main entity have state transitions? (Draft → Confirmed → Shipped) → Yes = Level 2+
310
- 2. Are there business invariants? ("can only cancel if Active") → Yes = Level 2+
311
- 3. Are there derived calculations? (Total, Balance, Discount) → Yes = Level 2+
312
- 4. Do other modules need to react to changes? (Domain Events with consumers) → Yes = Level 2+
313
- 5. Did the user explicitly declare a Bounded Context? Or are there 3+ domains with conflicting models? → Yes = Level 3
314
- If none of the above: Level 1 (CRUD)
315
-
316
- For Level 1: Use contracts-level1.cs template. No AggregateRoot, no Domain Events.
317
- For Level 2: Use contracts-level2.cs template. Design AggregateRoot with factory methods, invariants, Value Objects, Domain Events.
318
- For Level 3: Use contracts-level3.cs template. Add BOUNDED_CONTEXT namespace, Integration Events, cross-BC ID references only.
319
-
320
- Document in spec.md under ## Domain Complexity and ## Aggregate Blueprint (Level 2+).
321
- Coordinate ef-modeler for persistence design and event-architect for Domain Event patterns.
322
- Ref: framework/standards/architecture/ddd/complexity-levels.md
323
- ```
324
-
325
- **Step 3: Aplicar as mudanças com Edit tool** (não reescrever o JSON todo)
326
-
327
- Usar Edit para substituir `"standards": [` block e `"spawn_prompt":` value no domain-architect.
328
-
329
- **Step 4: Validar JSON**
330
-
331
- ```bash
332
- node -e "
333
- const a = JSON.parse(require('fs').readFileSync('framework/agents.json', 'utf8'));
334
- const da = a.agents.find(x => x.id === 'domain-architect');
335
- console.log('standards count:', da.standards.length);
336
- console.log('spawn_prompt length:', da.teammate.spawn_prompt.length);
337
- console.log('mentions complexity-levels:', da.teammate.spawn_prompt.includes('complexity-levels'));
338
- "
339
- ```
340
- Esperado: standards count >= 8, spawn_prompt length > 500, mentions complexity-levels: true.
341
-
342
- **Step 5: Rodar testes do agents-installer para garantir nenhuma regressão**
343
-
344
- ```bash
345
- node --test test/utils/agents-installer.test.js 2>&1 | grep -E "# (pass|fail)"
346
- ```
347
- Esperado: 0 fail.
348
-
349
- **Step 6: Commit**
350
-
351
- ```bash
352
- git add framework/agents.json
353
- git commit -m "feat(agents): enrich domain-architect spawn_prompt with 5-question detection + standards list"
354
- ```
355
-
356
- ---
357
-
358
- ## Task 5: Exemplo end-to-end Level 2 (Order Management)
359
-
360
- **Files:**
361
- - Create: `docs/examples/order-management/proposal.md`
362
- - Create: `docs/examples/order-management/spec.md`
363
- - Create: `docs/examples/order-management/contracts.cs`
364
-
365
- Este exemplo serve como referência viva de como um feature Level 2 deve se parecer após passar pelo pipeline completo. É documentação — sem testes unitários.
366
-
367
- **Step 1: Criar `docs/examples/order-management/proposal.md`**
368
-
369
- ```markdown
370
- # Proposal: Order Management
371
-
372
- **Feature:** order-management
373
- **Type:** Business Logic (Level 2 candidate)
374
- **Stack:** .NET 10 / C# 14, Blazor Server, EF Core, Azure SQL
375
-
376
- ## User Story
377
- Como usuário autenticado, quero criar e gerenciar pedidos de compra para que eu possa
378
- acompanhar o status dos meus pedidos e receber notificações de mudanças.
379
-
380
- ## Acceptance Criteria
381
- - [ ] Usuário pode criar um pedido com 1+ itens
382
- - [ ] Pedido começa no status Draft
383
- - [ ] Pedido só pode ser Confirmado se tiver pelo menos 1 item
384
- - [ ] Pedido Confirmado não pode receber mais itens
385
- - [ ] Total do pedido é calculado automaticamente
386
- - [ ] Sistema notifica quando pedido é Confirmado
387
-
388
- ## Out of Scope
389
- - Pagamento (feature separada)
390
- - Envio/logística
391
- ```
392
-
393
- **Step 2: Criar `docs/examples/order-management/spec.md`**
394
-
395
- Preencher o template de spec.md para este feature, incluindo as seções DDD obrigatórias:
396
-
397
- ```markdown
398
- # Feature Specification: Order Management
399
-
400
- | Field | Value |
401
- |-------|-------|
402
- | **ID** | order-management |
403
- | **Status** | Approved |
404
- | **Created** | 2026-02-23 |
405
- | **Stack** | .NET 10 / Blazor Server / EF Core |
406
- | **Complexity** | Medium |
407
- | **Agents** | Core: All / Specialists: domain-architect, ef-modeler, event-architect |
408
-
409
- ---
410
-
411
- ## Overview
412
-
413
- **Problem:** Usuários precisam criar e gerenciar pedidos com rastreamento de status.
414
-
415
- **Solution:** Aggregate Order com factory method, invariants de estado, e Domain Events para notificações.
416
-
417
- **Success Criteria:**
418
- - [ ] Order CRUD com validações de negócio
419
- - [ ] Status tracking com transições controladas
420
- - [ ] Notificação ao confirmar pedido
421
-
422
- ---
423
-
424
- ## Requirements
425
-
426
- **Functional:**
427
- FR001: Criar pedido com mínimo 1 item | FR002: Confirmar pedido (Draft → Confirmed) | FR003: Cancelar pedido (Draft/Confirmed → Cancelled) | FR004: Calcular total automaticamente
428
-
429
- **Non-Functional:**
430
- NFR001: Performance - operações < 200ms | NFR002: Consistência - invariants garantidas em toda operação
431
-
432
- ---
433
-
434
- ## User Stories
435
-
436
- ### US001: Criar Pedido
437
- **As** usuário autenticado **I want** criar um pedido com itens **so that** posso comprar produtos
438
-
439
- **Acceptance Criteria:**
440
- 1. Pedido criado com status Draft
441
- 2. Total calculado na criação
442
-
443
- **Edge Cases:** Lista de itens vazia → erro 400
444
-
445
- ---
446
-
447
- ## Technical Design
448
-
449
- ### Stack
450
- | Component | Technology |
451
- |-----------|------------|
452
- | Frontend | Blazor Server |
453
- | Backend | .NET 10 / C# 14 |
454
- | Database | Azure SQL / EF Core |
455
-
456
- ### Data Model
457
-
458
- #### Order
459
- | Column | Type | Constraints |
460
- |--------|------|-------------|
461
- | Id | Guid | PK |
462
- | UserId | Guid | FK (reference by ID — cross-aggregate) |
463
- | Status | OrderStatus | Enum |
464
- | CreatedAt | datetime2 | Default: GETUTCDATE() |
465
- | UpdatedAt | datetime2 | Nullable |
466
-
467
- #### OrderItem (owned entity)
468
- | Column | Type | Constraints |
469
- |--------|------|-------------|
470
- | Id | Guid | PK |
471
- | OrderId | Guid | FK |
472
- | ProductId | Guid | Reference by ID |
473
- | Quantity | int | > 0 |
474
- | UnitPrice | decimal(18,2) | > 0 |
475
-
476
- ### Contracts
477
- > **Ref:** `framework/templates/code/dotnet/contracts/contracts-level2.cs`
478
-
479
- ---
480
-
481
- ## Domain Complexity
482
-
483
- **Nível:** 2 — Business Logic
484
-
485
- **Justificativa:** Order tem estados com transições controladas (Draft → Confirmed → Cancelled),
486
- invariants de negócio (não confirmar sem itens, não adicionar itens a pedido confirmado),
487
- cálculo derivado (Total), e outros módulos precisam reagir (NotificationService ao OrderConfirmed).
488
-
489
- **Padrões Aplicados:**
490
- - AggregateRoot com factory method estático
491
- - Value Objects: Money (UnitPrice, Total)
492
- - Domain Events: OrderCreatedEvent, OrderConfirmedEvent, OrderCancelledEvent
493
- - CQRS com MediatR
494
-
495
- **Padrões Omitidos:**
496
- - Bounded Contexts — sistema single-domain, desnecessário
497
-
498
- ---
499
-
500
- ## Aggregate Blueprint (Nível 2+ apenas)
501
-
502
- ### Aggregate Root: Order
503
-
504
- **Invariants:**
505
- - Order só pode ser Confirmado se Status == Draft E tiver pelo menos 1 item
506
- - Order Confirmado não pode receber mais itens (AddItem lança DomainException)
507
- - Order Cancelado não pode ser reativado (estado terminal)
508
-
509
- **Estados e Transições:**
510
- ```
511
- {Draft} → Confirm() → {Confirmed}
512
- {Draft} → Cancel() → {Cancelled}
513
- {Confirmed} → Cancel() → {Cancelled}
514
- ```
515
-
516
- **Domain Events:**
517
- - `OrderCreatedEvent` — publicado ao criar (Create factory method)
518
- - `OrderConfirmedEvent` — publicado ao confirmar (Confirm method)
519
- - `OrderCancelledEvent` — publicado ao cancelar (Cancel method)
520
-
521
- **Value Objects:**
522
- - `Money` — UnitPrice e Total não são decimals simples: têm validação (> 0) e operações (Add, Multiply)
523
-
524
- **Referências Cross-Aggregate (por ID):**
525
- - `UserId: Guid` — nunca `User User { get; }`
526
- - `ProductId: Guid` em OrderItem — nunca `Product Product { get; }`
527
-
528
- ### Linguagem Ubíqua
529
-
530
- | Termo | Definição | Código |
531
- |-------|-----------|--------|
532
- | Order | Pedido de compra de um usuário | `Order` (AggregateRoot) |
533
- | Draft | Pedido criado, ainda editável | `OrderStatus.Draft` |
534
- | Confirm | Ato de finalizar e submeter um pedido | `Order.Confirm()` |
535
- | OrderItem | Linha de produto dentro de um pedido | `OrderItem` (Entity owned) |
536
- | Total | Soma calculada de todos os itens | `Order.Total` (property calculada) |
537
-
538
- ---
539
-
540
- ## Flows
541
-
542
- ### Confirmar Pedido
543
- **Trigger:** Usuário clica "Confirmar Pedido"
544
- 1. Frontend → `POST /api/orders/{id}/confirm`
545
- 2. API → `ConfirmOrderCommand(OrderId)`
546
- 3. Handler → `repository.GetAsync(id)` → `order.Confirm()` → `repository.UpdateAsync(order)`
547
- 4. `OrderConfirmedEvent` publicado → NotificationService envia email
548
- **End State:** Order.Status = Confirmed
549
-
550
- ---
551
-
552
- ## Definition of Done
553
- - [ ] Aggregate implementado com todos os invariants
554
- - [ ] Domain Events publicados e consumidos
555
- - [ ] Testes unitários do Aggregate (sem EF)
556
- - [ ] Testes de integração do Handler
557
- - [ ] API endpoint documentado
558
- ```
559
-
560
- **Step 3: Criar `docs/examples/order-management/contracts.cs`**
561
-
562
- Exemplo real de contracts-level2.cs preenchido para Order:
563
-
564
- ```csharp
565
- // ============================================================
566
- // CONTRACTS: Order Management — Level 2 (Business Logic)
567
- // Example of correctly filled contracts-level2.cs template
568
- // Feature: order-management | Date: 2026-02-23
569
- // ============================================================
570
-
571
- // ===== AGGREGATE ROOT =====
572
- // Implementado em: Domain/Orders/Aggregates/Order.cs
573
- //
574
- // Invariants (do spec.md > Aggregate Blueprint):
575
- // - Confirm() só é válido se Status == Draft E Items.Any()
576
- // - AddItem() lança DomainException se Status != Draft
577
- // - Cancel() é válido de Draft ou Confirmed → Cancelled (terminal)
578
-
579
- // Domain/Orders/Events:
580
- public record OrderCreatedEvent(Guid OrderId, Guid UserId) : DomainEvent;
581
- public record OrderConfirmedEvent(Guid OrderId, Guid UserId, decimal Total) : DomainEvent;
582
- public record OrderCancelledEvent(Guid OrderId, string Reason) : DomainEvent;
583
-
584
- // Application/Orders/Commands:
585
- public record CreateOrderCommand(Guid UserId, List<CreateOrderItemRequest> Items)
586
- : IRequest<CreateOrderResult>;
587
- public record CreateOrderResult(Guid OrderId);
588
-
589
- public record ConfirmOrderCommand(Guid OrderId) : IRequest;
590
- public record CancelOrderCommand(Guid OrderId, string Reason) : IRequest;
591
-
592
- // Application/Orders/Queries:
593
- public record GetOrderQuery(Guid OrderId) : IRequest<OrderDto?>;
594
- public record ListOrdersByUserQuery(Guid UserId, int Page = 1, int PageSize = 20)
595
- : IRequest<PagedResult<OrderDto>>;
596
-
597
- // Application/Orders — DTOs (read models):
598
- public record OrderDto(
599
- Guid Id,
600
- Guid UserId,
601
- string Status,
602
- decimal Total,
603
- List<OrderItemDto> Items,
604
- DateTime CreatedAt,
605
- DateTime? UpdatedAt
606
- );
607
-
608
- public record OrderItemDto(Guid ProductId, int Quantity, decimal UnitPrice, decimal Subtotal);
609
-
610
- public record CreateOrderItemRequest(Guid ProductId, int Quantity, decimal UnitPrice);
611
-
612
- // Domain/Orders — Repository:
613
- public interface IOrderRepository
614
- {
615
- Task<Order?> GetAsync(Guid id, CancellationToken ct = default);
616
- Task<List<Order>> GetByUserAsync(Guid userId, CancellationToken ct = default);
617
- Task AddAsync(Order order, CancellationToken ct = default);
618
- Task UpdateAsync(Order order, CancellationToken ct = default);
619
- Task<bool> ExistsAsync(Guid id, CancellationToken ct = default);
620
- }
621
-
622
- // Exceptions:
623
- public class OrderNotFoundException(Guid id) : DomainException($"Order '{id}' not found.");
624
- public class OrderInvalidStateException(string message) : DomainException(message);
625
- ```
626
-
627
- **Step 4: Verificar que os 3 arquivos foram criados**
628
-
629
- ```bash
630
- ls docs/examples/order-management/
631
- ```
632
- Esperado: `contracts.cs`, `proposal.md`, `spec.md`
633
-
634
- **Step 5: Commit**
635
-
636
- ```bash
637
- git add docs/examples/order-management/
638
- git commit -m "docs(examples): add order-management Level 2 reference example — proposal + spec + contracts"
639
- ```
640
-
641
- ---
642
-
643
- ## Verificação Final
644
-
645
- ```bash
646
- # Testes
647
- node --test 2>&1 | grep -E "# (pass|fail|skip)"
648
-
649
- # Sem referências ao template legado
650
- grep -rn "contracts\.cs" framework/skills/ framework/templates/ \
651
- --include="*.md" --include="*.json" | grep -v "level1\|level2\|level3\|contracts-level\|contracts\.cs\.hbs"
652
-
653
- # domain-architect é tier 2 e tem standards DDD
654
- node -e "
655
- const a = JSON.parse(require('fs').readFileSync('framework/agents.json', 'utf8'));
656
- const da = a.agents.find(x => x.id === 'domain-architect');
657
- console.log('tier:', da.tier);
658
- console.log('standards:', da.standards.filter(s => s.includes('ddd')));
659
- "
660
-
661
- # Exemplo existe
662
- ls docs/examples/order-management/
663
- ```
664
-
665
- ---
666
-
667
- ## Resumo das Mudanças
668
-
669
- | Categoria | Arquivos | Tipo |
670
- |-----------|---------|------|
671
- | Tests | `test/utils/agents-installer.test.js` | +2 testes domain-architect |
672
- | Templates | `contracts.cs`, `contracts.cs.hbs` | DELETE |
673
- | Templates | `REGISTRY.json` | Remove entrada legada |
674
- | Skills | `phase-design/SKILL.md`, `tool-usage-guide/SKILL.md` | Atualizar referências |
675
- | Tests | `test/templates/contracts-levels.test.js` | +1 teste ausência legado |
676
- | Skills | `phase-tasks/SKILL.md` | +Passo 0 DDD-aware |
677
- | Agents | `agents.json` | domain-architect standards + spawn_prompt |
678
- | Docs | `docs/examples/order-management/` | 3 novos arquivos |
679
-
680
- **5 tasks — ~1h30 de execução.**
681
-
682
- ---
683
-
684
- *MORPH-SPEC by Polymorphism Tech*