@polymorphism-tech/morph-spec 4.5.0 → 4.7.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.
- package/CLAUDE.md +77 -56
- package/README.md +394 -700
- package/docs/ARCHITECTURE.md +331 -0
- package/docs/CHEATSHEET.md +221 -0
- package/docs/COMMAND-FLOWS.md +368 -0
- package/docs/QUICKSTART.md +212 -0
- package/docs/examples/order-management/contracts.cs +84 -0
- package/docs/examples/order-management/proposal.md +24 -0
- package/docs/examples/order-management/spec.md +162 -0
- package/docs/plans/2026-02-23-ddd-architecture-refactor.md +1153 -0
- package/docs/plans/2026-02-23-ddd-nextsteps.md +682 -0
- package/docs/plans/2026-02-23-infra-architect-refactor.md +437 -0
- package/docs/plans/2026-02-23-nextjs-code-review-design.md +156 -0
- package/docs/plans/2026-02-23-nextjs-code-review-impl.md +1254 -0
- package/docs/plans/2026-02-23-nextjs-standards-design.md +149 -0
- package/docs/plans/2026-02-23-nextjs-standards-impl.md +1846 -0
- package/framework/{skills/level-2-domains → agents}/README.md +14 -14
- package/framework/{skills/level-2-domains → agents}/ai-agents/ai-system-architect.md +1 -4
- package/framework/{skills/level-2-domains → agents}/architecture/po-pm-advisor.md +1 -2
- package/framework/{skills/level-2-domains → agents}/architecture/prompt-engineer.md +1 -2
- package/framework/{skills/level-2-domains → agents}/architecture/seo-growth-hacker.md +1 -2
- package/framework/{skills/level-2-domains → agents}/architecture/standards-architect.md +159 -162
- package/framework/agents/backend/api-designer.md +103 -0
- package/framework/{skills/level-2-domains → agents}/backend/dotnet-senior.md +1 -2
- package/framework/agents/backend/ef-modeler.md +119 -0
- package/framework/{skills/level-2-domains → agents}/backend/hangfire-orchestrator.md +1 -4
- package/framework/{skills/level-2-domains → agents}/backend/ms-agent-expert.md +1 -4
- package/framework/{skills/level-2-domains → agents}/frontend/blazor-builder.md +1 -4
- package/framework/agents/frontend/nextjs-expert.md +118 -0
- package/framework/{skills/level-2-domains → agents}/frontend/ui-ux-designer.md +1 -2
- package/framework/{skills/level-2-domains → agents}/infrastructure/azure-architect.md +147 -148
- package/framework/{skills/level-2-domains → agents}/infrastructure/azure-deploy-specialist.md +1 -2
- package/framework/{skills/level-2-domains → agents}/infrastructure/bicep-architect.md +1 -4
- package/framework/{skills/level-2-domains → agents}/infrastructure/container-specialist.md +1 -4
- package/framework/{skills/level-2-domains → agents}/infrastructure/devops-engineer.md +1 -4
- package/framework/agents/infrastructure/infra-architect.md +45 -0
- package/framework/{skills/level-2-domains → agents}/integrations/asaas-financial.md +1 -4
- package/framework/{skills/level-2-domains → agents}/integrations/azure-identity.md +1 -4
- package/framework/{skills/level-2-domains → agents}/integrations/clerk-auth.md +1 -4
- package/framework/{skills/level-2-domains → agents}/integrations/hangfire-integration.md +1 -2
- package/framework/{skills/level-2-domains → agents}/integrations/resend-email.md +1 -4
- package/framework/{skills/level-2-domains → agents}/quality/code-analyzer.md +1 -4
- package/framework/{skills/level-2-domains → agents}/quality/testing-specialist.md +1 -4
- package/framework/agents.json +1145 -278
- package/framework/hooks/claude-code/statusline.py +384 -85
- package/framework/hooks/shared/phase-utils.js +129 -129
- package/framework/rules/frontend-standards.md +0 -3
- package/framework/rules/nextjs-standards.md +17 -0
- package/framework/skills/README.md +66 -0
- package/framework/skills/level-0-meta/{brainstorming.md → brainstorming/SKILL.md} +3 -1
- package/framework/skills/level-0-meta/brainstorming/references/proposal-example.md +138 -0
- package/framework/skills/level-0-meta/{code-review.md → code-review/SKILL.md} +3 -2
- package/framework/skills/level-0-meta/code-review/references/review-example.md +164 -0
- package/framework/skills/level-0-meta/code-review/scripts/scan-csharp.mjs +121 -0
- package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +147 -0
- package/framework/skills/level-0-meta/code-review-nextjs/references/review-example-nextjs.md +254 -0
- package/framework/skills/level-0-meta/{morph-checklist.md → morph-checklist/SKILL.md} +2 -5
- package/framework/skills/{level-1-workflows/morph-replicate.md → level-0-meta/morph-replicate/SKILL.md} +6 -7
- package/framework/skills/level-0-meta/{simulation-checklist.md → simulation-checklist/SKILL.md} +3 -6
- package/framework/skills/level-0-meta/{tool-usage-guide.md → tool-usage-guide/SKILL.md} +4 -5
- package/framework/skills/level-0-meta/{verification-before-completion.md → verification-before-completion/SKILL.md} +3 -1
- package/framework/skills/level-0-meta/verification-before-completion/scripts/check-phase-outputs.mjs +110 -0
- package/framework/skills/level-1-workflows/{phase-clarify.md → phase-clarify/SKILL.md} +3 -3
- package/framework/skills/level-1-workflows/phase-clarify/references/clarifications-example.md +117 -0
- package/framework/skills/level-1-workflows/{phase-codebase-analysis.md → phase-codebase-analysis/SKILL.md} +2 -3
- package/framework/skills/level-1-workflows/{phase-design.md → phase-design/SKILL.md} +46 -182
- package/framework/skills/level-1-workflows/phase-design/references/spec-example.md +253 -0
- package/framework/skills/level-1-workflows/{phase-implement.md → phase-implement/SKILL.md} +3 -3
- package/framework/skills/level-1-workflows/phase-implement/references/recap-example.md +132 -0
- package/framework/skills/level-1-workflows/{phase-setup.md → phase-setup/SKILL.md} +2 -3
- package/framework/skills/level-1-workflows/{phase-tasks.md → phase-tasks/SKILL.md} +42 -3
- package/framework/skills/level-1-workflows/phase-tasks/references/tasks-example.md +231 -0
- package/framework/skills/level-1-workflows/phase-tasks/scripts/validate-tasks.mjs +112 -0
- package/framework/skills/level-1-workflows/{phase-uiux.md → phase-uiux/SKILL.md} +2 -3
- package/framework/standards/STANDARDS.json +121 -0
- package/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
- package/framework/standards/architecture/ddd/complexity-levels.md +108 -0
- package/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
- package/framework/standards/frontend/nextjs/app-router.md +123 -0
- package/framework/standards/frontend/nextjs/components.md +132 -0
- package/framework/standards/frontend/nextjs/data-fetching.md +126 -0
- package/framework/standards/frontend/nextjs/forms.md +128 -0
- package/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
- package/framework/standards/frontend/nextjs/project-structure.md +102 -0
- package/framework/standards/frontend/nextjs/state-management.md +72 -0
- package/framework/standards/frontend/nextjs/testing.md +111 -0
- package/framework/templates/REGISTRY.json +538 -142
- package/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
- package/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
- package/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
- package/framework/templates/docs/spec.md +49 -0
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
- package/framework/templates/project-structure/dotnet-ddd.md +70 -0
- package/framework/workflows/docs/enforcement-pipeline.md +2 -1
- package/package.json +1 -1
- package/scripts/scan-nextjs.mjs +169 -0
- package/src/commands/project/doctor.js +52 -1
- package/src/commands/project/init.js +19 -65
- package/src/commands/project/update.js +7 -63
- package/src/lib/detectors/claude-config-detector.js +1 -3
- package/src/lib/standards/standards-context-injector.js +5 -0
- package/src/lib/validators/nextjs/index.js +6 -0
- package/src/lib/validators/nextjs/next-component-validator.js +181 -0
- package/src/lib/validators/validation-runner.js +5 -0
- package/src/utils/agents-installer.js +16 -4
- package/src/utils/skills-installer.js +59 -15
- package/.morph/.morphversion +0 -5
- package/.morph/analytics/threads-log.jsonl +0 -44
- package/.morph/config/config.json +0 -8
- package/.morph/context/README.md +0 -17
- package/.morph/framework/agents.json +0 -948
- package/.morph/framework/standards/STANDARDS.json +0 -812
- package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
- package/.morph/framework/standards/ai-agents/production.md +0 -415
- package/.morph/framework/standards/ai-agents/setup.md +0 -418
- package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
- package/.morph/framework/standards/ai-agents/workflows.md +0 -354
- package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
- package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
- package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
- package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
- package/.morph/framework/standards/backend/api/rest.md +0 -492
- package/.morph/framework/standards/backend/api/validation.md +0 -88
- package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
- package/.morph/framework/standards/backend/database/ef-core.md +0 -199
- package/.morph/framework/standards/backend/database/migrations.md +0 -393
- package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
- package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
- package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
- package/.morph/framework/standards/backend/dotnet/async.md +0 -366
- package/.morph/framework/standards/backend/dotnet/core.md +0 -117
- package/.morph/framework/standards/backend/dotnet/di.md +0 -439
- package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
- package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
- package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
- package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
- package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
- package/.morph/framework/standards/context/analytics.md +0 -96
- package/.morph/framework/standards/context/bundles.md +0 -110
- package/.morph/framework/standards/context/priming.md +0 -78
- package/.morph/framework/standards/core/architecture.md +0 -185
- package/.morph/framework/standards/core/coding.md +0 -214
- package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
- package/.morph/framework/standards/core/git.md +0 -185
- package/.morph/framework/standards/core/testing.md +0 -295
- package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
- package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
- package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
- package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
- package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
- package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
- package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
- package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
- package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
- package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
- package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
- package/.morph/framework/standards/frontend/blazor/state.md +0 -191
- package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
- package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
- package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -198
- package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
- package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
- package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
- package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
- package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
- package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
- package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
- package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
- package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
- package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
- package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
- package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
- package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
- package/.morph/framework/standards/integration/api/graphql.md +0 -91
- package/.morph/framework/standards/integration/api/grpc.md +0 -114
- package/.morph/framework/standards/integration/api/rest-design.md +0 -95
- package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
- package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
- package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
- package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
- package/.morph/framework/standards/observability/logging.md +0 -131
- package/.morph/framework/standards/observability/metrics.md +0 -121
- package/.morph/framework/standards/observability/monitoring.md +0 -114
- package/.morph/framework/standards/observability/tracing.md +0 -132
- package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
- package/.morph/framework/standards/workflows/thread-management.md +0 -113
- package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
- package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
- package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
- package/.morph/framework/templates/README.md +0 -814
- package/.morph/framework/templates/REGISTRY.json +0 -1492
- package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
- package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
- package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
- package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
- package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
- package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
- package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
- package/.morph/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
- package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
- package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
- package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
- package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
- package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
- package/.morph/framework/templates/code/dotnet/test.cs +0 -239
- package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
- package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
- package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
- package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
- package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
- package/.morph/framework/templates/context/CONTEXT.md +0 -181
- package/.morph/framework/templates/docs/clarifications.md +0 -253
- package/.morph/framework/templates/docs/onboarding.md +0 -123
- package/.morph/framework/templates/docs/proposal.md +0 -182
- package/.morph/framework/templates/docs/schema-analysis.md +0 -119
- package/.morph/framework/templates/docs/spec.md +0 -149
- package/.morph/framework/templates/docs/ui-components.md +0 -124
- package/.morph/framework/templates/docs/ui-design-system.md +0 -76
- package/.morph/framework/templates/docs/ui-flows.md +0 -167
- package/.morph/framework/templates/docs/ui-mockups.md +0 -98
- package/.morph/framework/templates/examples/design-system-examples.md +0 -357
- package/.morph/framework/templates/examples/spec-examples.md +0 -90
- package/.morph/framework/templates/feature/decisions.md +0 -187
- package/.morph/framework/templates/feature/recap.md +0 -146
- package/.morph/framework/templates/feature/tasks.md +0 -199
- package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
- package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
- package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
- package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
- package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
- package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
- package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
- package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
- package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
- package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
- package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
- package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
- package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
- package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
- package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
- package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
- package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
- package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
- package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
- package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
- package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
- package/.morph/framework/templates/infrastructure/github/README.md +0 -593
- package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
- package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
- package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
- package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
- package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
- package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
- package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
- package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
- package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
- package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
- package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
- package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
- package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
- package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
- package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
- package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
- package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
- package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
- package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
- package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
- package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
- package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
- package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
- package/.morph/framework/templates/saas/subscription.cs +0 -347
- package/.morph/framework/templates/saas/tenant.cs +0 -338
- package/.morph/framework/templates/state.template.json +0 -17
- package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
- package/.morph/framework/templates/ui/MudTheme.cs +0 -281
- package/.morph/framework/templates/ui/design-system.css +0 -226
- package/.morph/logs/tool-failures.log +0 -51
- package/.morph/memory/pre-compact-2026-02-22T17-01-01-658Z.json +0 -16
- package/.morph/state.json +0 -48
- package/framework/skills/level-2-domains/backend/api-designer.md +0 -66
- package/framework/skills/level-2-domains/backend/ef-modeler.md +0 -65
- package/framework/skills/level-2-domains/frontend/nextjs-expert.md +0 -161
- package/framework/skills/level-3-technologies/README.md +0 -7
- package/framework/skills/level-4-patterns/README.md +0 -7
- package/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
- package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Feature Recap: Photo Processing Pipeline
|
|
2
|
+
|
|
3
|
+
> Example of a well-structured recap.md. Filled-in reference — not a template.
|
|
4
|
+
|
|
5
|
+
## Summary
|
|
6
|
+
|
|
7
|
+
| Field | Value |
|
|
8
|
+
|-------|-------|
|
|
9
|
+
| **Feature ID** | photo-processing |
|
|
10
|
+
| **Completed** | 2025-01-22 |
|
|
11
|
+
| **Total Tasks** | 11 / 11 |
|
|
12
|
+
| **Time Spent** | ~9h |
|
|
13
|
+
| **Agents Used** | dotnet-senior, azure-architect, blazor-builder |
|
|
14
|
+
| **Stack** | blazor-azure |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Tasks Completed
|
|
19
|
+
|
|
20
|
+
| ID | Title | Category | Duration |
|
|
21
|
+
|----|-------|----------|----------|
|
|
22
|
+
| T001 | Define C# contracts and interfaces | Contract | 25min |
|
|
23
|
+
| T002 | Create ProcessingJob entity and enum | Domain | 30min |
|
|
24
|
+
| T003 | EF Core migration and DbContext setup | Infrastructure | 50min |
|
|
25
|
+
| T004 | Azure Blob Storage service | Infrastructure | 45min |
|
|
26
|
+
| T005 | Implement PhotoProcessingService | Service | 65min |
|
|
27
|
+
| T006 | Implement Hangfire background job | Job | 70min |
|
|
28
|
+
| T007 | Upload and status endpoints | API | 40min |
|
|
29
|
+
| T008 | Blazor upload page component | UI | 60min |
|
|
30
|
+
| T009 | Blazor status polling page | UI | 65min |
|
|
31
|
+
| T010 | Unit tests for PhotoProcessingService | Test | 55min |
|
|
32
|
+
| T011 | Integration tests for upload + status API | Test | 70min |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## What Was Delivered
|
|
37
|
+
|
|
38
|
+
### Functionality
|
|
39
|
+
- Photo upload via Blazor form (10MB limit, .jpg/.png only)
|
|
40
|
+
- Azure Blob Storage integration with `uploads/{jobId}/original.jpg` path structure
|
|
41
|
+
- Hangfire background job with 3-retry exponential backoff (5s/30s/120s)
|
|
42
|
+
- Real-time status polling page (5s interval, stops on terminal state)
|
|
43
|
+
- Download redirect for completed jobs
|
|
44
|
+
|
|
45
|
+
### Backend (.NET)
|
|
46
|
+
- Endpoints: `POST /api/upload`, `GET /api/status/{id}`, `GET /api/download/{id}`
|
|
47
|
+
- Services: `PhotoProcessingService`, `PhotoProcessingJob`
|
|
48
|
+
- Simulation: `FakeBlobStorageService`, `FakePhotoProcessingJob` for dev mode
|
|
49
|
+
|
|
50
|
+
### Frontend (Blazor)
|
|
51
|
+
- Pages: `Upload.razor`, `ProcessingStatus.razor`
|
|
52
|
+
- Polling via `PeriodicTimer` — no SignalR dependency
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Files Created
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
src/Domain/Entities/ProcessingJob.cs
|
|
60
|
+
src/Domain/Enums/ProcessingStatus.cs
|
|
61
|
+
src/Application/PhotoProcessing/Interfaces/IPhotoProcessingService.cs
|
|
62
|
+
src/Application/PhotoProcessing/Commands/UploadPhotoCommand.cs
|
|
63
|
+
src/Application/PhotoProcessing/Queries/GetJobStatusQuery.cs
|
|
64
|
+
src/Application/PhotoProcessing/DTOs/JobStatusDto.cs
|
|
65
|
+
src/Application/PhotoProcessing/PhotoProcessingService.cs
|
|
66
|
+
src/Application/PhotoProcessing/PhotoProcessingJob.cs
|
|
67
|
+
src/Application/PhotoProcessing/FakePhotoProcessingJob.cs
|
|
68
|
+
src/Infrastructure/Storage/IBlobStorageService.cs
|
|
69
|
+
src/Infrastructure/Storage/AzureBlobStorageService.cs
|
|
70
|
+
src/Infrastructure/Storage/FakeBlobStorageService.cs
|
|
71
|
+
src/Infrastructure/Persistence/Configurations/ProcessingJobConfiguration.cs
|
|
72
|
+
src/Web/Endpoints/PhotoProcessingEndpoints.cs
|
|
73
|
+
src/Web/Pages/Upload.razor + .cs
|
|
74
|
+
src/Web/Pages/ProcessingStatus.razor + .cs
|
|
75
|
+
tests/Unit/Application/PhotoProcessing/PhotoProcessingServiceTests.cs
|
|
76
|
+
tests/Integration/Api/PhotoProcessingEndpointTests.cs
|
|
77
|
+
tests/Integration/Fixtures/PhotoProcessingApiFixture.cs
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Files Modified
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
src/Infrastructure/Persistence/AppDbContext.cs
|
|
84
|
+
src/Infrastructure/DependencyInjection.cs
|
|
85
|
+
src/Application/DependencyInjection.cs
|
|
86
|
+
src/Web/Program.cs
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Architecture Decisions
|
|
92
|
+
|
|
93
|
+
| Decision | Rationale |
|
|
94
|
+
|----------|-----------|
|
|
95
|
+
| PeriodicTimer for polling (not SignalR) | Simpler, no hub overhead, sufficient at MVP scale |
|
|
96
|
+
| FakeBlobStorageService as Singleton | Stores in-memory dict; Scoped would lose state between requests |
|
|
97
|
+
| Hangfire RetryCount on entity (not Hangfire built-in) | Domain owns retry state; allows custom error messages per attempt |
|
|
98
|
+
|
|
99
|
+
See full ADRs in `decisions.md`
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Test Coverage
|
|
104
|
+
|
|
105
|
+
| Type | Files | Notes |
|
|
106
|
+
|------|-------|-------|
|
|
107
|
+
| Unit | `PhotoProcessingServiceTests.cs` | Happy path, invalid type, size limit, 404, all statuses |
|
|
108
|
+
| Integration | `PhotoProcessingEndpointTests.cs` | POST /upload, GET /status, GET /download (completed + pending) |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Issues Encountered
|
|
113
|
+
|
|
114
|
+
| Issue | Resolution |
|
|
115
|
+
|-------|-----------|
|
|
116
|
+
| `FakeBlobStorageService` registered as `Scoped` — lost uploads between requests | Changed to `Singleton` per simulation-checklist.md |
|
|
117
|
+
| `PeriodicTimer` not stopping on component dispose | Added `CancellationTokenSource` + dispose pattern in `ProcessingStatus.razor.cs` |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Metrics
|
|
122
|
+
|
|
123
|
+
| Metric | Value |
|
|
124
|
+
|--------|-------|
|
|
125
|
+
| Tasks Completed | 11 / 11 |
|
|
126
|
+
| Checkpoints Passed | 3 (after T003, T006, T009) |
|
|
127
|
+
| Bugs Found | 2 |
|
|
128
|
+
| Bugs Fixed | 2 |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: phase-setup
|
|
3
|
-
description:
|
|
4
|
-
MORPH-SPEC Phase 1 (Setup). Reads project context, identifies the stack, activates relevant agents, and creates the feature folder structure. Called at the start of every feature.
|
|
3
|
+
description: MORPH-SPEC Phase 1 (Setup). Reads project context, detects tech stack, activates relevant agents via detect-agents, and confirms the feature environment. Use at the start of every MORPH-SPEC feature workflow after proposal approval to load standards and initialize the context.
|
|
5
4
|
argument-hint: "[feature-name]"
|
|
6
5
|
user-invocable: false
|
|
7
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
@@ -21,7 +20,7 @@ Inicialize o contexto e prepare o ambiente para uma feature aprovada.
|
|
|
21
20
|
|
|
22
21
|
## Ferramentas Recomendadas
|
|
23
22
|
|
|
24
|
-
> **Ref:** `framework/skills/level-0-meta/tool-usage-guide.md` para guia completo.
|
|
23
|
+
> **Ref:** `framework/skills/level-0-meta/tool-usage-guide/SKILL.md` para guia completo.
|
|
25
24
|
> **Ref:** `framework/standards/integration/mcp/mcp-tools.md` para referência MCP.
|
|
26
25
|
|
|
27
26
|
| Ação | Ferramenta | Alternativa |
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: phase-tasks
|
|
3
|
-
description:
|
|
4
|
-
MORPH-SPEC Phase 4 (Tasks). Breaks the approved design into ordered implementation tasks with dependencies and checkpoints, producing tasks.md. Called after clarifications resolve.
|
|
3
|
+
description: MORPH-SPEC Phase 4 (Tasks). Breaks approved spec into bottom-up ordered implementation tasks (T001...TXXX) with dependencies, checkpoints every 3 tasks, and effort estimates, producing tasks.md. Use after design and clarification phases to create a structured implementation plan before coding starts.
|
|
5
4
|
argument-hint: "[feature-name]"
|
|
6
5
|
disable-model-invocation: true
|
|
7
6
|
user-invocable: false
|
|
@@ -22,8 +21,10 @@ Quebre a especificação em tasks executáveis, defina ordem de execução e est
|
|
|
22
21
|
|
|
23
22
|
## Ferramentas Recomendadas
|
|
24
23
|
|
|
25
|
-
> **Ref:** `framework/skills/level-0-meta/tool-usage-guide.md` para guia completo.
|
|
24
|
+
> **Ref:** `framework/skills/level-0-meta/tool-usage-guide/SKILL.md` para guia completo.
|
|
26
25
|
> **Ref:** `framework/standards/integration/mcp/mcp-tools.md` para referência MCP.
|
|
26
|
+
> **Example:** `references/tasks-example.md` — filled-in tasks.md showing expected granularity and format.
|
|
27
|
+
> **Script:** `scripts/validate-tasks.mjs` — validates tasks.md structure, T### IDs, and required fields.
|
|
27
28
|
|
|
28
29
|
| Ação | Ferramenta | Alternativa |
|
|
29
30
|
|------|------------|-------------|
|
|
@@ -72,6 +73,44 @@ npx morph-spec approval get $ARGUMENTS design
|
|
|
72
73
|
|
|
73
74
|
---
|
|
74
75
|
|
|
76
|
+
### Passo 0: Ler Nível de Domínio
|
|
77
|
+
|
|
78
|
+
**Ref:** `framework/standards/architecture/ddd/complexity-levels.md`
|
|
79
|
+
|
|
80
|
+
Antes de quebrar tasks, leia a seção `## Domain Complexity` do spec.md:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
grep -A15 "## Domain Complexity" ".morph/features/$ARGUMENTS/1-design/spec.md"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> Se a seção não existir no spec.md, assuma **Nível 1 (CRUD)** e documente nos pre-requisitos da task.
|
|
87
|
+
|
|
88
|
+
Use o nível para **restringir** as categorias de tasks às listadas para o nível detectado:
|
|
89
|
+
|
|
90
|
+
| Nível | Categorias de Tasks |
|
|
91
|
+
|-------|---------------------|
|
|
92
|
+
| **1 — CRUD** | `domain` (Entity simples) → `infrastructure` (Repository, EF Config) → `application` (Service CRUD) → `presentation` (API/Page) → `tests` |
|
|
93
|
+
| **2 — Business Logic** | `domain` (AggregateRoot, ValueObjects, DomainEvents) → `infrastructure` (Repository, EF Config) → `application` (Commands, Queries, Handlers) → `presentation` (API/Page) → `tests` |
|
|
94
|
+
| **3 — Bounded Context** | `domain-bc` (BC setup, Aggregates, Events) → `infrastructure` (BC repositories, EF) → `application` (Commands, Queries, Integration handlers) → `presentation` → `tests` |
|
|
95
|
+
|
|
96
|
+
**Nível 1:** Nenhuma task adicional obrigatória — apenas o padrão CRUD nas categorias listadas.
|
|
97
|
+
|
|
98
|
+
**Tasks adicionais obrigatórias por nível:**
|
|
99
|
+
|
|
100
|
+
**Nível 2 apenas:**
|
|
101
|
+
- `T{N}: Implementar AggregateRoot {EntityName} com factory method e invariants` (domain)
|
|
102
|
+
- `T{N}: Implementar ValueObjects: {lista do Aggregate Blueprint}` (domain)
|
|
103
|
+
- `T{N}: Implementar DomainEvents: {lista do Aggregate Blueprint}` (domain)
|
|
104
|
+
- `T{N}: Implementar Command Handlers com MediatR` (application)
|
|
105
|
+
- `T{N}: Implementar Query Handlers com read models` (application)
|
|
106
|
+
|
|
107
|
+
**Nível 3 apenas (além do Nível 2):**
|
|
108
|
+
- `T{N}: Configurar namespace/pasta do Bounded Context {BoundedContext}` (infrastructure)
|
|
109
|
+
- `T{N}: Implementar Integration Events para comunicação cross-BC` (domain-bc)
|
|
110
|
+
- `T{N}: Implementar handlers de Integration Events` (application)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
75
114
|
### Passo 1: Analisar Spec
|
|
76
115
|
|
|
77
116
|
Leia `.morph/features/$ARGUMENTS/1-design/spec.md` e identifique:
|
|
@@ -0,0 +1,231 @@
|
|
|
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:** azure-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:** blazor-builder
|
|
158
|
+
- **Dependencies:** T007
|
|
159
|
+
|
|
160
|
+
**Description:**
|
|
161
|
+
Blazor Server 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:** blazor-builder
|
|
174
|
+
- **Dependencies:** T007
|
|
175
|
+
|
|
176
|
+
**Description:**
|
|
177
|
+
Blazor Server 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
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -0,0 +1,112 @@
|
|
|
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/3-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)
|
|
61
|
+
const taskHeaders = lines
|
|
62
|
+
.map((l, i) => ({ line: i + 1, match: l.match(/^###\s+(T\d{3}):\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);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: phase-uiux
|
|
3
|
-
description:
|
|
4
|
-
MORPH-SPEC Phase 1.5 (UI/UX). Creates design-system.md, mockups.md, components.md, and flows.md before technical spec. Auto-activates for features with UI keywords.
|
|
3
|
+
description: MORPH-SPEC Phase 1.5 (UI/UX). Creates design-system.md, mockups.md, components.md, and flows.md using Figma/Playwright/Context7 MCPs. Use after setup for features with frontend UI components, pages, dashboards, forms, wizards, or visual interactions requiring design documentation.
|
|
5
4
|
argument-hint: "[feature-name]"
|
|
6
5
|
user-invocable: false
|
|
7
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
@@ -21,7 +20,7 @@ Fase condicional para features com front-end. Coleta requisitos de UI/UX, gera w
|
|
|
21
20
|
|
|
22
21
|
## Ferramentas Recomendadas
|
|
23
22
|
|
|
24
|
-
> **Ref:** `framework/skills/level-0-meta/tool-usage-guide.md` para guia completo.
|
|
23
|
+
> **Ref:** `framework/skills/level-0-meta/tool-usage-guide/SKILL.md` para guia completo.
|
|
25
24
|
> **Ref:** `framework/standards/integration/mcp/mcp-tools.md` para referência MCP.
|
|
26
25
|
|
|
27
26
|
| Ação | Ferramenta | Alternativa |
|