@polymorphism-tech/morph-spec 4.21.0 → 5.0.1

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 (213) hide show
  1. package/CLAUDE.md +57 -71
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +224 -491
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +55 -38
  8. package/framework/MORPH.md +244 -0
  9. package/framework/agents.json +127 -1183
  10. package/framework/commands/morph-apply.md +56 -240
  11. package/framework/commands/morph-archive.md +48 -85
  12. package/framework/commands/morph-preflight.md +7 -7
  13. package/framework/commands/morph-proposal.md +35 -191
  14. package/framework/commands/morph-status.md +19 -50
  15. package/framework/commands/morph-troubleshoot.md +2 -2
  16. package/framework/evals/rubrics/README.md +44 -0
  17. package/framework/evals/rubrics/architecture.md +46 -0
  18. package/framework/evals/rubrics/code-quality.md +50 -0
  19. package/framework/evals/rubrics/contracts.md +47 -0
  20. package/framework/evals/rubrics/test-coverage.md +50 -0
  21. package/framework/evals/scenarios/dotnet-crud.yaml +42 -0
  22. package/framework/evals/scenarios/nextjs-auth.yaml +38 -0
  23. package/framework/evals/suites/standard.yaml +5 -0
  24. package/framework/evals/trace-schema.md +67 -0
  25. package/framework/hooks/claude-code/core/README.md +3 -0
  26. package/framework/hooks/claude-code/core/denylist.json +14 -0
  27. package/framework/hooks/claude-code/{pre-tool-use → core}/enforce-phase-writes.js +5 -5
  28. package/framework/hooks/claude-code/core/post-edit-typecheck.js +69 -0
  29. package/framework/hooks/claude-code/core/pre-bash-denylist.js +29 -0
  30. package/framework/hooks/claude-code/{pre-tool-use → core}/protect-spec-files.js +4 -6
  31. package/framework/hooks/claude-code/{stop → core}/validate-completion.js +13 -82
  32. package/framework/hooks/shared/phase-utils.js +20 -28
  33. package/framework/hooks/shared/state-reader.js +4 -5
  34. package/framework/{skills/level-0-meta/mcp-registry.json → mcp/registry.json} +254 -210
  35. package/framework/phases.json +40 -114
  36. package/framework/rubrics/eval-rubric.json +66 -0
  37. package/framework/skills/README.md +39 -64
  38. package/framework/skills/core/README.md +3 -0
  39. package/framework/skills/core/morph-brainstorming/SKILL.md +102 -0
  40. package/framework/skills/core/morph-eval/SKILL.md +57 -0
  41. package/framework/skills/core/morph-implement/SKILL.md +83 -0
  42. package/framework/skills/core/morph-plan/SKILL.md +64 -0
  43. package/framework/skills/core/morph-review/SKILL.md +62 -0
  44. package/framework/skills/core/morph-stack-scan/SKILL.md +109 -0
  45. package/framework/skills/core/morph-standards/SKILL.md +49 -0
  46. package/framework/standards/STANDARDS.json +32 -0
  47. package/framework/standards/frontend/design-system/ai-image-generation.md +244 -0
  48. package/framework/standards/integration/mcp/mcp-tools.md +48 -0
  49. package/framework/templates/CLAUDE.md.core.guide.md +29 -0
  50. package/framework/templates/CLAUDE.md.core.template +22 -0
  51. package/framework/templates/REGISTRY.json +4 -4
  52. package/framework/workflows/configs/fast-track.json +5 -10
  53. package/framework/workflows/configs/full.json +4 -8
  54. package/framework/workflows/configs/quick.json +32 -0
  55. package/framework/workflows/configs/standard.json +57 -64
  56. package/package.json +7 -6
  57. package/src/commands/mcp/mcp-setup.js +58 -31
  58. package/src/commands/project/doctor.js +69 -70
  59. package/src/commands/project/init.js +26 -5
  60. package/src/commands/project/status.js +18 -19
  61. package/src/commands/state/approve.js +1 -1
  62. package/src/commands/validation/validate-feature.js +18 -112
  63. package/src/core/paths/output-schema.js +133 -151
  64. package/src/core/state/phase-state-machine.js +10 -24
  65. package/src/core/state/state-manager.js +17 -17
  66. package/src/core/workflows/workflow-detector.js +214 -31
  67. package/src/core/workflows/workflow-router.js +204 -0
  68. package/src/dashboard/app/pages/AgentMap.jsx +32 -33
  69. package/src/dashboard/app/pages/LiveState.jsx +1 -1
  70. package/src/dashboard/app/pages/PhasePipeline.jsx +2 -4
  71. package/src/dashboard/app/pages/SkillsLibrary.jsx +2 -3
  72. package/src/dashboard/app/pages/Workflows.jsx +2 -2
  73. package/src/dashboard/scanner/agents-scanner.js +30 -35
  74. package/src/lib/agents/metrics-aggregator.js +1 -1
  75. package/src/lib/agents/output-collector.js +7 -8
  76. package/src/lib/context/context-builder.js +289 -0
  77. package/src/lib/detectors/claude-config-detector.js +19 -3
  78. package/src/lib/generators/context-generator.js +20 -42
  79. package/src/lib/generators/index.js +1 -0
  80. package/src/lib/generators/mandate-generator.js +512 -0
  81. package/src/lib/generators/metadata-extractor.js +1 -1
  82. package/src/lib/generators/recap-generator.js +3 -4
  83. package/src/lib/installers/mcp-installer.js +300 -92
  84. package/src/lib/phase-chain/phase-validator.js +36 -40
  85. package/src/lib/stack/stack-profile.js +74 -91
  86. package/src/lib/tasks/task-parser.js +1 -1
  87. package/src/lib/tasks/wave-resolver.js +353 -0
  88. package/src/lib/validators/checkpoint-persistence.js +2 -2
  89. package/src/lib/validators/content/cross-phase-validator.js +281 -0
  90. package/src/lib/validators/content/index.js +1 -0
  91. package/src/lib/validators/shared/emit-validator-dispatch.js +6 -56
  92. package/src/scripts/global-install.js +2 -27
  93. package/src/utils/agents-installer.js +224 -447
  94. package/src/utils/claude-settings-manager.js +57 -15
  95. package/src/utils/file-copier.js +1 -0
  96. package/src/utils/hooks-installer.js +15 -117
  97. package/src/utils/skills-installer.js +12 -18
  98. package/bin/detect-agents.js +0 -226
  99. package/bin/task-manager.js +0 -1036
  100. package/framework/agents/README.md +0 -13
  101. package/framework/agents/ai-agents/ai-system-architect.md +0 -194
  102. package/framework/agents/ai-agents/vector-search-expert.md +0 -247
  103. package/framework/agents/architecture/architecture-expert.md +0 -98
  104. package/framework/agents/architecture/morph-spec-architect.md +0 -66
  105. package/framework/agents/architecture/packages-validator.md +0 -89
  106. package/framework/agents/architecture/security-expert.md +0 -79
  107. package/framework/agents/architecture/seo-growth-hacker.md +0 -168
  108. package/framework/agents/architecture/standards-architect.md +0 -153
  109. package/framework/agents/backend/dotnet-senior.md +0 -163
  110. package/framework/agents/backend/ef-modeler.md +0 -119
  111. package/framework/agents/backend/hangfire-orchestrator.md +0 -133
  112. package/framework/agents/backend/ms-agent-expert.md +0 -55
  113. package/framework/agents/backend/neon-expert.md +0 -379
  114. package/framework/agents/frontend/css-specialist.md +0 -89
  115. package/framework/agents/frontend/design-system-validator.md +0 -100
  116. package/framework/agents/frontend/gsap-animator.md +0 -131
  117. package/framework/agents/frontend/nextjs-component-validator.md +0 -97
  118. package/framework/agents/frontend/nextjs-expert.md +0 -201
  119. package/framework/agents/frontend/ui-designer.md +0 -259
  120. package/framework/agents/infrastructure/infra-architect.md +0 -215
  121. package/framework/agents/integrations/asaas-financial.md +0 -138
  122. package/framework/agents/integrations/neon-auth.md +0 -151
  123. package/framework/agents/integrations/resend-email.md +0 -127
  124. package/framework/hooks/claude-code/post-tool-use/agent-complete.js +0 -122
  125. package/framework/hooks/claude-code/post-tool-use/dispatch.js +0 -363
  126. package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +0 -78
  127. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +0 -194
  128. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +0 -199
  129. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +0 -55
  130. package/framework/hooks/claude-code/session-start/inject-morph-context.js +0 -323
  131. package/framework/hooks/claude-code/session-start/post-compact-restore.js +0 -41
  132. package/framework/hooks/claude-code/session-start/resume-context.js +0 -77
  133. package/framework/hooks/claude-code/teammate-idle/teammate-idle.js +0 -90
  134. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +0 -114
  135. package/framework/hooks/shared/compact-restore.js +0 -123
  136. package/framework/hooks/shared/dispatch-helpers.js +0 -147
  137. package/framework/hooks/shared/skill-reminder-helpers.js +0 -79
  138. package/framework/hooks/shared/stale-task-reset.js +0 -57
  139. package/framework/hooks/shared/worktree-helpers.js +0 -75
  140. package/framework/skills/level-0-meta/README.md +0 -7
  141. package/framework/skills/level-0-meta/morph-agent-teams/SKILL.md +0 -472
  142. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +0 -174
  143. package/framework/skills/level-0-meta/morph-brainstorming/references/proposal-example.md +0 -138
  144. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +0 -145
  145. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +0 -250
  146. package/framework/skills/level-0-meta/morph-code-review/references/review-example.md +0 -164
  147. package/framework/skills/level-0-meta/morph-code-review/references/review-guidelines.md +0 -100
  148. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +0 -151
  149. package/framework/skills/level-0-meta/morph-code-review-nextjs/SKILL.md +0 -165
  150. package/framework/skills/level-0-meta/morph-code-review-nextjs/references/review-example-nextjs.md +0 -254
  151. package/framework/skills/level-0-meta/morph-code-review-nextjs/scripts/scan-nextjs.mjs +0 -189
  152. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +0 -344
  153. package/framework/skills/level-0-meta/morph-frontend-review/scripts/scan-accessibility.mjs +0 -376
  154. package/framework/skills/level-0-meta/morph-init/SKILL.md +0 -537
  155. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +0 -225
  156. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +0 -382
  157. package/framework/skills/level-0-meta/morph-post-implementation/scripts/detect-dev-server.mjs +0 -153
  158. package/framework/skills/level-0-meta/morph-post-implementation/scripts/detect-stack.mjs +0 -234
  159. package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +0 -106
  160. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +0 -243
  161. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +0 -169
  162. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +0 -148
  163. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +0 -110
  164. package/framework/skills/level-1-workflows/README.md +0 -7
  165. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +0 -269
  166. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +0 -453
  167. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +0 -44
  168. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-authoring-guide.md +0 -55
  169. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +0 -253
  170. package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +0 -38
  171. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +0 -493
  172. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +0 -50
  173. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +0 -46
  174. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +0 -47
  175. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +0 -132
  176. package/framework/skills/level-1-workflows/morph-phase-implement/references/vsa-implementation-guide.md +0 -92
  177. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +0 -257
  178. package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +0 -14
  179. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +0 -291
  180. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -143
  181. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +0 -404
  182. package/framework/skills/level-1-workflows/morph-phase-tasks/scripts/validate-tasks.mjs +0 -112
  183. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +0 -788
  184. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +0 -147
  185. package/framework/squad-templates/backend-only.json +0 -47
  186. package/framework/squad-templates/frontend-only.json +0 -56
  187. package/framework/squad-templates/full-stack.json +0 -74
  188. package/src/commands/agents/agent-metrics.js +0 -174
  189. package/src/commands/agents/audit-dispatch.js +0 -82
  190. package/src/commands/agents/detect-agents.js +0 -275
  191. package/src/commands/agents/dispatch-agents.js +0 -461
  192. package/src/commands/agents/index.js +0 -13
  193. package/src/commands/agents/manage-agents.js +0 -352
  194. package/src/commands/agents/project-metrics.js +0 -74
  195. package/src/commands/phase/phase-reset.js +0 -74
  196. package/src/commands/scope/escalate.js +0 -217
  197. package/src/commands/state/advance-phase.js +0 -600
  198. package/src/commands/state/phase-runner.js +0 -215
  199. package/src/commands/state/state.js +0 -444
  200. package/src/commands/task/expand.js +0 -100
  201. package/src/commands/tasks/index.js +0 -4
  202. package/src/commands/tasks/task.js +0 -105
  203. package/src/commands/templates/index.js +0 -5
  204. package/src/commands/templates/template-render.js +0 -93
  205. package/src/commands/trust/trust.js +0 -118
  206. package/src/lib/agents/agents-manager.js +0 -349
  207. package/src/lib/build/build-runner.js +0 -99
  208. package/src/lib/checkpoints/checkpoint-hooks.js +0 -111
  209. package/src/lib/contracts/sprint-contract-generator.js +0 -137
  210. package/src/lib/scope/impact-analyzer.js +0 -106
  211. package/src/lib/trust/trust-manager.js +0 -157
  212. package/src/utils/tier-helpers.js +0 -24
  213. /package/framework/hooks/claude-code/{post-tool-use → core}/loop-detect.js +0 -0
@@ -1,404 +0,0 @@
1
- # Tasks - Photo Processing Pipeline
2
-
3
- > Example of a well-structured tasks.md. This is a filled-in reference — not a template.
4
- > All tasks are atomic (15–60 min), independently commitable, and directly traceable to spec.md.
5
-
6
- | Task ID | Type | Title | Status |
7
- |---------|------|-------|--------|
8
- | T001 | Contract | Define C# contracts and interfaces | Done |
9
- | T002 | Domain | Create ProcessingJob entity and enum | Done |
10
- | T003 | Infra | EF Core migration and DbContext setup | Done |
11
- | T004 | Infra | Azure Blob Storage service | Done |
12
- | T005 | Service | Implement PhotoProcessingService | In Progress |
13
- | T006 | Job | Implement Hangfire background job | Pending |
14
- | T007 | API | Upload and status endpoints (Minimal API) | Pending |
15
- | T008 | UI | Blazor upload page component | Pending |
16
- | T009 | UI | Blazor status polling page | Pending |
17
- | T010 | Test | Unit tests for PhotoProcessingService | Pending |
18
- | T011 | Test | Integration tests for upload + status API | Pending |
19
-
20
- **Status Values:** `Pending | In Progress | Blocked | Done`
21
-
22
- ---
23
-
24
- ## Phase 1: Contracts & Data Model
25
-
26
- ### T001: Define C# contracts and interfaces
27
- - **Type:** Contract
28
- - **Priority:** 1
29
- - **Estimate:** 30min
30
- - **Assigned:** dotnet-senior
31
- - **Dependencies:** None
32
-
33
- **Description:**
34
- Define all service interfaces, command/result records, and DTOs needed for the feature. These become the API contract other tasks depend on — implement data model and services against these interfaces.
35
-
36
- **Deliverables:**
37
- - [ ] Create: `src/Application/PhotoProcessing/Interfaces/IPhotoProcessingService.cs`
38
- - [ ] Create: `src/Application/PhotoProcessing/Commands/UploadPhotoCommand.cs`
39
- - [ ] Create: `src/Application/PhotoProcessing/Queries/GetJobStatusQuery.cs`
40
- - [ ] Create: `src/Application/PhotoProcessing/DTOs/JobStatusDto.cs`
41
-
42
- ---
43
-
44
- ### T002: Create ProcessingJob entity and enum
45
- - **Type:** Domain
46
- - **Priority:** 1
47
- - **Estimate:** 30min
48
- - **Assigned:** dotnet-senior
49
- - **Dependencies:** T001
50
-
51
- **Description:**
52
- Create the `ProcessingJob` domain entity and `ProcessingStatus` enum per the data model in spec.md. Entity must use private setters and expose domain methods for state transitions (`MarkProcessing()`, `MarkCompleted()`, `MarkFailed()`).
53
-
54
- **Deliverables:**
55
- - [ ] Create: `src/Domain/Entities/ProcessingJob.cs`
56
- - [ ] Create: `src/Domain/Enums/ProcessingStatus.cs`
57
-
58
- ---
59
-
60
- ### T003: EF Core migration and DbContext setup
61
- - **Type:** Infrastructure
62
- - **Priority:** 1
63
- - **Estimate:** 45min
64
- - **Assigned:** dotnet-senior
65
- - **Dependencies:** T002
66
-
67
- **Description:**
68
- Add `ProcessingJob` to `AppDbContext`, configure via Fluent API (column lengths, indexes, defaults), and create initial migration. Verify migration applies cleanly to a local SQL Server instance.
69
-
70
- **Deliverables:**
71
- - [ ] Update: `src/Infrastructure/Persistence/AppDbContext.cs`
72
- - [ ] Create: `src/Infrastructure/Persistence/Configurations/ProcessingJobConfiguration.cs`
73
- - [ ] Run: `dotnet ef migrations add AddProcessingJob`
74
- - [ ] Verify: migration applies without errors
75
-
76
- ---
77
-
78
- ## Phase 2: Infrastructure Services
79
-
80
- ### T004: Azure Blob Storage service
81
- - **Type:** Infrastructure
82
- - **Priority:** 1
83
- - **Estimate:** 45min
84
- - **Assigned:** infra-architect
85
- - **Dependencies:** None
86
-
87
- **Description:**
88
- Implement `IBlobStorageService` with upload and generate-URL operations using `Azure.Storage.Blobs` SDK. Register as scoped in DI. Add connection string to `appsettings.json` (placeholder) and Key Vault reference for production.
89
-
90
- **Deliverables:**
91
- - [ ] Create: `src/Infrastructure/Storage/IBlobStorageService.cs`
92
- - [ ] Create: `src/Infrastructure/Storage/AzureBlobStorageService.cs`
93
- - [ ] Create: `src/Infrastructure/Storage/FakeBlobStorageService.cs` (for simulation mode)
94
- - [ ] Update: `src/Infrastructure/DependencyInjection.cs`
95
-
96
- ---
97
-
98
- ### T005: Implement PhotoProcessingService
99
- - **Type:** Service
100
- - **Priority:** 2
101
- - **Estimate:** 1h
102
- - **Assigned:** dotnet-senior
103
- - **Dependencies:** T001, T002, T003, T004
104
-
105
- **Description:**
106
- Implement `IPhotoProcessingService` with `UploadAsync` (validate → blob upload → create job → enqueue Hangfire job) and `GetStatusAsync`. Use result pattern for validation errors; throw `NotFoundException` for missing jobs.
107
-
108
- **Deliverables:**
109
- - [ ] Create: `src/Application/PhotoProcessing/PhotoProcessingService.cs`
110
- - [ ] Update: `src/Application/DependencyInjection.cs`
111
-
112
- ---
113
-
114
- ### T006: Implement Hangfire background job
115
- - **Type:** Job
116
- - **Priority:** 2
117
- - **Estimate:** 1h
118
- - **Assigned:** dotnet-senior
119
- - **Dependencies:** T002, T004
120
-
121
- **Description:**
122
- Implement `IPhotoProcessingJob` that: sets status = Processing → downloads original from Blob → calls AI API → uploads processed photo → sets status = Completed. On exception: increment RetryCount, set Failed if >= 3. Add `[AutomaticRetry(Attempts = 3)]` attribute.
123
-
124
- **Deliverables:**
125
- - [ ] Create: `src/Application/PhotoProcessing/PhotoProcessingJob.cs`
126
- - [ ] Create: `src/Application/PhotoProcessing/FakePhotoProcessingJob.cs` (simulation mode)
127
-
128
- ---
129
-
130
- ## Phase 3: API Endpoints
131
-
132
- ### T007: Upload and status endpoints (Minimal API)
133
- - **Type:** API
134
- - **Priority:** 2
135
- - **Estimate:** 45min
136
- - **Assigned:** dotnet-senior
137
- - **Dependencies:** T005
138
-
139
- **Description:**
140
- Create two endpoints per spec.md:
141
- - `POST /api/upload` — multipart/form-data, returns `{ jobId }`, maps to `UploadPhotoCommand`
142
- - `GET /api/status/{jobId}` — returns `JobStatusDto`
143
- - `GET /api/download/{jobId}` — redirects to Blob URL if Completed, else 404
144
-
145
- **Deliverables:**
146
- - [ ] Create: `src/Web/Endpoints/PhotoProcessingEndpoints.cs`
147
- - [ ] Update: `src/Web/Program.cs` to register endpoint group
148
-
149
- ---
150
-
151
- ## Phase 4: UI Components
152
-
153
- ### T008: Blazor upload page component
154
- - **Type:** UI
155
- - **Priority:** 2
156
- - **Estimate:** 1h
157
- - **Assigned:** nextjs-expert
158
- - **Dependencies:** T007
159
-
160
- **Description:**
161
- Frontend page at `/upload`. File input with client-side validation (type + size before submit). Loading state during upload. Redirect to `/processing/{jobId}` on success. Error message display per spec wireframe.
162
-
163
- **Deliverables:**
164
- - [ ] Create: `src/Web/Pages/Upload.razor`
165
- - [ ] Create: `src/Web/Pages/Upload.razor.cs`
166
-
167
- ---
168
-
169
- ### T009: Blazor status polling page
170
- - **Type:** UI
171
- - **Priority:** 3
172
- - **Estimate:** 1h
173
- - **Assigned:** nextjs-expert
174
- - **Dependencies:** T007
175
-
176
- **Description:**
177
- Frontend page at `/processing/{jobId}`. Polls `GET /api/status/{jobId}` every 5 seconds using `PeriodicTimer`. Shows status label + progress indicator. "Download" button when Completed. "Retry" suggestion when Failed. Stops polling on terminal state.
178
-
179
- **Deliverables:**
180
- - [ ] Create: `src/Web/Pages/ProcessingStatus.razor`
181
- - [ ] Create: `src/Web/Pages/ProcessingStatus.razor.cs`
182
-
183
- ---
184
-
185
- ## Phase 5: Tests
186
-
187
- ### T010: Unit tests for PhotoProcessingService
188
- - **Type:** Test
189
- - **Priority:** 2
190
- - **Estimate:** 1h
191
- - **Assigned:** dotnet-senior
192
- - **Dependencies:** T005
193
-
194
- **Description:**
195
- Unit tests covering: happy path upload, invalid file type rejection, file too large rejection, status retrieval for each status value, not-found case. Use Moq for `IBlobStorageService` and `IProcessingJobRepository`. FluentAssertions for assertions.
196
-
197
- **Deliverables:**
198
- - [ ] Create: `tests/Unit/Application/PhotoProcessing/PhotoProcessingServiceTests.cs`
199
-
200
- ---
201
-
202
- ### T011: Integration tests for upload + status API
203
- - **Type:** Test
204
- - **Priority:** 3
205
- - **Estimate:** 1h
206
- - **Assigned:** dotnet-senior
207
- - **Dependencies:** T007, T010
208
-
209
- **Description:**
210
- Integration tests using `WebApplicationFactory` + in-memory SQLite (or TestContainers for SQL Server). Tests: POST /api/upload returns 200 with jobId, GET /api/status/{jobId} returns correct status, GET /api/download/{completedJobId} returns redirect.
211
-
212
- **Deliverables:**
213
- - [ ] Create: `tests/Integration/Api/PhotoProcessingEndpointTests.cs`
214
- - [ ] Create: `tests/Integration/Fixtures/PhotoProcessingApiFixture.cs`
215
-
216
- ---
217
-
218
- ## Summary
219
-
220
- | Phase | Tasks | Estimate |
221
- |-------|-------|----------|
222
- | Contracts & Data Model | T001–T003 | 1h45m |
223
- | Infrastructure Services | T004–T006 | 2h45m |
224
- | API Endpoints | T007 | 45m |
225
- | UI Components | T008–T009 | 2h |
226
- | Tests | T010–T011 | 2h |
227
- | **Total** | **11 tasks** | **~9h15m** |
228
-
229
- ---
230
-
231
- ---
232
-
233
- # Tasks - Book CRUD (VSA Example)
234
-
235
- > Example of tasks.md for a Vertical Slice Architecture (VSA) feature.
236
- > Key rule: 1 task = 1 complete slice (Handler + Validator + Endpoint together).
237
- > GetAll slices have no Validator — stated explicitly in the task.
238
-
239
- | Task ID | Category | Title | Status |
240
- |---------|----------|-------|--------|
241
- | T001 | entity | Criar Entity Book + registrar DbSet no ApplicationDbContext | Pending |
242
- | T002 | errors | Criar BookErrors (NotFound + outros factory methods) | Pending |
243
- | T003 | tags | Adicionar ApiTags.Books em Constants/ApiTags.cs | Pending |
244
- | T004 | migration | Criar migration AddBook + aplicar ao banco | Pending |
245
- | T005 | slice | Implementar slice CreateBook (Handler + Validator + Endpoint) | Pending |
246
- | T006 | slice | Implementar slice GetAllBooks (Handler + Endpoint, sem Validator) | Pending |
247
- | T007 | slice | Implementar slice GetBookById (Handler + Validator + Endpoint) | Pending |
248
- | T008 | slice | Implementar slice UpdateBook (Handler + Validator + Endpoint) | Pending |
249
- | T009 | slice | Implementar slice DeleteBook (Handler + Validator + Endpoint) | Pending |
250
-
251
- **Status Values:** `Pending | In Progress | Blocked | Done`
252
-
253
- ---
254
-
255
- ## Phase 1: Foundation
256
-
257
- ### T001: Criar Entity Book + registrar DbSet no ApplicationDbContext
258
- - **Category:** entity
259
- - **Estimate:** 20min
260
- - **Dependencies:** None
261
-
262
- **Description:**
263
- Criar a entity `Book` com todos os campos definidos no spec.md. Registrar `DbSet<Book>` no `ApplicationDbContext`. Usar `Guid.CreateVersion7()` para o campo Id — não `Guid.NewGuid()`. Propriedades obrigatórias como `sealed` ou com setters `private init`.
264
-
265
- **Deliverables:**
266
- - [ ] Create: `Entities/Book.cs`
267
- - [ ] Update: `Database/ApplicationDbContext.cs` (add `public DbSet<Book> Books { get; set; } = null!;`)
268
-
269
- ---
270
-
271
- ### T002: Criar BookErrors (NotFound + outros factory methods)
272
- - **Category:** errors
273
- - **Estimate:** 10min
274
- - **Dependencies:** T001
275
-
276
- **Description:**
277
- Criar a classe `BookErrors` static com factory methods para cada tipo de erro da feature. Cada method retorna um `Error` com code e description. Esses erros são compartilhados por todos os slices da BookFeature.
278
-
279
- **Deliverables:**
280
- - [ ] Create: `Features/BookFeature/BookErrors.cs`
281
-
282
- ---
283
-
284
- ### T003: Adicionar ApiTags.Books em Constants/ApiTags.cs
285
- - **Category:** tags
286
- - **Estimate:** 5min
287
- - **Dependencies:** None
288
-
289
- **Description:**
290
- Adicionar a constante `Books` em `ApiTags` para uso em todos os endpoints da feature. Se a constante já existir, pular esta task.
291
-
292
- **Deliverables:**
293
- - [ ] Update: `Constants/ApiTags.cs` (add `public const string Books = "books";`)
294
-
295
- ---
296
-
297
- ### T004: Criar migration AddBook + aplicar ao banco
298
- - **Category:** migration
299
- - **Estimate:** 10min
300
- - **Dependencies:** T001
301
-
302
- **Description:**
303
- Gerar a migration EF Core para a entity `Book` e aplicar ao banco local. Verificar que a migration foi gerada corretamente antes de aplicar.
304
-
305
- **Deliverables:**
306
- - [ ] Run: `dotnet ef migrations add AddBook`
307
- - [ ] Run: `dotnet ef database update`
308
- - [ ] Verify: migration applies without errors
309
-
310
- ---
311
-
312
- ## Phase 2: Slices
313
-
314
- ### T005: Implementar slice CreateBook (Handler + Validator + Endpoint)
315
- - **Category:** slice
316
- - **Estimate:** 45min
317
- - **Dependencies:** T001, T002, T003, T004
318
-
319
- **Description:**
320
- Implementar o slice completo de criação. O arquivo Handler deve conter os records `CreateBookRequest` e `CreateBookResponse` no mesmo arquivo. O Validator deve herdar de `AbstractValidator<CreateBookRequest>`. O Endpoint deve ser `internal sealed` e usar `result.Match()` — nunca `result.Value` sem checar `IsSuccess`.
321
-
322
- Handler injeta: `IRepository<Book>` + `IUnitOfWork`.
323
-
324
- **Deliverables:**
325
- - [ ] Create: `Features/BookFeature/CreateBook/CreateBookHandler.cs`
326
- - [ ] Create: `Features/BookFeature/CreateBook/CreateBookValidator.cs`
327
- - [ ] Create: `Features/BookFeature/CreateBook/CreateBookEndpoint.cs`
328
-
329
- ---
330
-
331
- ### T006: Implementar slice GetAllBooks (Handler + Endpoint, sem Validator)
332
- - **Category:** slice
333
- - **Estimate:** 25min
334
- - **Dependencies:** T001, T004
335
-
336
- **Description:**
337
- Implementar o slice de listagem. GetAll NÃO tem Validator (sem parâmetros de entrada para validar). Handler injeta apenas `IRepository<Book>` — não precisa de `IUnitOfWork` (read-only).
338
-
339
- **Deliverables:**
340
- - [ ] Create: `Features/BookFeature/GetAllBooks/GetAllBooksHandler.cs`
341
- - [ ] Create: `Features/BookFeature/GetAllBooks/GetAllBooksEndpoint.cs`
342
-
343
- ---
344
-
345
- ### T007: Implementar slice GetBookById (Handler + Validator + Endpoint)
346
- - **Category:** slice
347
- - **Estimate:** 30min
348
- - **Dependencies:** T001, T002, T004
349
-
350
- **Description:**
351
- Implementar o slice de busca por ID. Validator verifica que o Guid não é empty. Handler retorna `BookErrors.NotFound()` se o livro não existir. Handler injeta apenas `IRepository<Book>`.
352
-
353
- **Deliverables:**
354
- - [ ] Create: `Features/BookFeature/GetBookById/GetBookByIdHandler.cs`
355
- - [ ] Create: `Features/BookFeature/GetBookById/GetBookByIdValidator.cs`
356
- - [ ] Create: `Features/BookFeature/GetBookById/GetBookByIdEndpoint.cs`
357
-
358
- ---
359
-
360
- ### T008: Implementar slice UpdateBook (Handler + Validator + Endpoint)
361
- - **Category:** slice
362
- - **Estimate:** 45min
363
- - **Dependencies:** T001, T002, T003, T004
364
-
365
- **Description:**
366
- Implementar o slice de atualização. Handler retorna `BookErrors.NotFound()` se o livro não existir antes de atualizar. Handler injeta: `IRepository<Book>` + `IUnitOfWork`.
367
-
368
- **Deliverables:**
369
- - [ ] Create: `Features/BookFeature/UpdateBook/UpdateBookHandler.cs`
370
- - [ ] Create: `Features/BookFeature/UpdateBook/UpdateBookValidator.cs`
371
- - [ ] Create: `Features/BookFeature/UpdateBook/UpdateBookEndpoint.cs`
372
-
373
- ---
374
-
375
- ### T009: Implementar slice DeleteBook (Handler + Validator + Endpoint)
376
- - **Category:** slice
377
- - **Estimate:** 30min
378
- - **Dependencies:** T001, T002, T003, T004
379
-
380
- **Description:**
381
- Implementar o slice de deleção. Handler verifica existência antes de deletar, retorna `BookErrors.NotFound()` se não existir. Handler injeta: `IRepository<Book>` + `IUnitOfWork`.
382
-
383
- **Deliverables:**
384
- - [ ] Create: `Features/BookFeature/DeleteBook/DeleteBookHandler.cs`
385
- - [ ] Create: `Features/BookFeature/DeleteBook/DeleteBookValidator.cs`
386
- - [ ] Create: `Features/BookFeature/DeleteBook/DeleteBookEndpoint.cs`
387
-
388
- ---
389
-
390
- ## Summary
391
-
392
- | Phase | Tasks | Estimate |
393
- |-------|-------|----------|
394
- | Foundation (entity + errors + tags + migration) | T001–T004 | 45min |
395
- | Slices (Create + GetAll + GetById + Update + Delete) | T005–T009 | 2h55m |
396
- | **Total** | **9 tasks** | **~3h40m** |
397
-
398
- > **VSA Note:** No manual DI registration needed — `AddHandlersFromAssembly()`,
399
- > `RegisterApiEndpointsFromAssembly()`, and `AddValidatorsFromAssembly()` discover
400
- > all handlers, endpoints and validators automatically via assembly scanning (Scrutor).
401
-
402
- ---
403
-
404
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,112 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * validate-tasks.mjs
4
- *
5
- * Validates a MORPH-SPEC tasks.md file for structure and completeness.
6
- * Executed locally by Claude via Bash — output returned to Claude.
7
- *
8
- * Usage:
9
- * node validate-tasks.mjs <tasks-file>
10
- * node validate-tasks.mjs .morph/features/my-feature/4-tasks/tasks.md
11
- *
12
- * Checks:
13
- * - Summary table exists with T### IDs and valid statuses
14
- * - Each task header has T### format
15
- * - Each task has Type, Priority, Estimate, Dependencies fields
16
- * - Each task has at least one deliverable checkbox
17
- * - Task IDs are sequential (no gaps)
18
- * - Reports counts by status
19
- */
20
-
21
- import { readFileSync, existsSync } from 'fs';
22
-
23
- const taskFile = process.argv[2];
24
-
25
- if (!taskFile) {
26
- console.error(JSON.stringify({ error: 'Usage: validate-tasks.mjs <tasks-file>' }));
27
- process.exit(1);
28
- }
29
-
30
- if (!existsSync(taskFile)) {
31
- console.error(JSON.stringify({ error: `File not found: ${taskFile}` }));
32
- process.exit(1);
33
- }
34
-
35
- const content = readFileSync(taskFile, 'utf-8');
36
- const lines = content.split('\n');
37
-
38
- const errors = [];
39
- const warnings = [];
40
-
41
- // 1. Parse summary table (| T001 | Type | Title | Status |)
42
- const tableRows = lines.filter(l => /^\|\s*T\d{3}/.test(l));
43
- const VALID_STATUSES = new Set(['Pending', 'In Progress', 'Blocked', 'Done']);
44
- const summaryTasks = [];
45
-
46
- for (const row of tableRows) {
47
- const parts = row.split('|').map(s => s.trim()).filter(Boolean);
48
- if (parts.length < 4) continue;
49
- const [id, , , status] = parts;
50
- summaryTasks.push({ id, status });
51
- if (!VALID_STATUSES.has(status)) {
52
- errors.push(`Task ${id}: invalid status '${status}' — must be one of: ${[...VALID_STATUSES].join(', ')}`);
53
- }
54
- }
55
-
56
- if (summaryTasks.length === 0) {
57
- errors.push('No summary table found — expected rows matching | T### | Type | Title | Status |');
58
- }
59
-
60
- // 2. Parse task headers (### T001: Title or ### T001 — Title or ### T001 - Title)
61
- const taskHeaders = lines
62
- .map((l, i) => ({ line: i + 1, match: l.match(/^###\s+(T\d{3})\s*[—–:\-]\s+(.+)/) }))
63
- .filter(r => r.match);
64
-
65
- // Check sequential IDs
66
- const ids = taskHeaders.map(r => parseInt(r.match[1].slice(1)));
67
- for (let i = 0; i < ids.length; i++) {
68
- if (ids[i] !== i + 1) {
69
- warnings.push(`Task ID gap or duplicate near T${String(ids[i]).padStart(3, '0')} (expected T${String(i + 1).padStart(3, '0')})`);
70
- break;
71
- }
72
- }
73
-
74
- // 3. Check each task section has required fields
75
- for (const { line, match } of taskHeaders) {
76
- const taskId = match[1];
77
- // Collect lines in this task section (until next ### or end)
78
- const start = line; // 1-indexed
79
- let end = lines.length;
80
- for (let i = start; i < lines.length; i++) {
81
- if (i > start - 1 && /^#{1,3}\s/.test(lines[i])) { end = i; break; }
82
- }
83
- const section = lines.slice(start, end).join('\n');
84
-
85
- if (!/\*\*Type:\*\*/.test(section)) errors.push(`${taskId}: missing **Type:** field`);
86
- if (!/\*\*Priority:\*\*/.test(section)) errors.push(`${taskId}: missing **Priority:** field`);
87
- if (!/\*\*Estimate:\*\*/.test(section)) errors.push(`${taskId}: missing **Estimate:** field`);
88
- if (!/\*\*Dependencies:\*\*/.test(section)) warnings.push(`${taskId}: missing **Dependencies:** field`);
89
- if (!/- \[ \]/.test(section)) warnings.push(`${taskId}: no deliverable checkboxes found`);
90
- }
91
-
92
- // 4. Status counts
93
- const statusCounts = {};
94
- for (const { status } of summaryTasks) {
95
- statusCounts[status] = (statusCounts[status] ?? 0) + 1;
96
- }
97
-
98
- const result = {
99
- file: taskFile,
100
- valid: errors.length === 0,
101
- tasks: {
102
- total: summaryTasks.length,
103
- byStatus: statusCounts,
104
- completed: statusCounts['Done'] ?? 0,
105
- remaining: (summaryTasks.length) - (statusCounts['Done'] ?? 0),
106
- },
107
- errors,
108
- warnings,
109
- };
110
-
111
- console.log(JSON.stringify(result, null, 2));
112
- process.exit(errors.length > 0 ? 1 : 0);