@polymorphism-tech/morph-spec 4.6.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/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/agents/README.md +14 -14
- package/framework/agents/architecture/standards-architect.md +159 -159
- package/framework/agents/frontend/nextjs-expert.md +87 -127
- package/framework/agents/infrastructure/azure-architect.md +147 -147
- package/framework/agents/infrastructure/infra-architect.md +45 -0
- package/framework/agents.json +1145 -278
- package/framework/rules/frontend-standards.md +0 -3
- package/framework/rules/nextjs-standards.md +17 -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/tool-usage-guide/SKILL.md +3 -3
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +45 -9
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +38 -0
- 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 +15 -1
- package/src/commands/project/update.js +6 -1
- 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 +14 -2
- package/.morph/.morphversion +0 -5
- package/.morph/analytics/threads-log.jsonl +0 -6
- package/.morph/config/config.json +0 -8
- 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 -215
- 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/docs/user-stories.md +0 -34
- 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 -7
- package/.morph/memory/pre-compact-2026-02-23T15-43-03-521Z.json +0 -16
- package/.morph/state.json +0 -48
- package/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
- package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
paths:
|
|
3
3
|
- "**/*.razor"
|
|
4
|
-
- "**/*.tsx"
|
|
5
|
-
- "**/*.ts"
|
|
6
4
|
- "**/*.css"
|
|
7
5
|
- "**/*.scss"
|
|
8
6
|
---
|
|
@@ -10,5 +8,4 @@ paths:
|
|
|
10
8
|
# Frontend Standards
|
|
11
9
|
|
|
12
10
|
@.morph/framework/standards/frontend/blazor/design-checklist.md
|
|
13
|
-
@.morph/framework/standards/frontend/nextjs/nextjs-patterns.md
|
|
14
11
|
@.morph/framework/standards/frontend/design-system/naming.md
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.tsx"
|
|
4
|
+
- "**/*.ts"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Next.js Standards
|
|
8
|
+
|
|
9
|
+
@.morph/framework/standards/frontend/nextjs/naming-conventions.md
|
|
10
|
+
@.morph/framework/standards/frontend/nextjs/project-structure.md
|
|
11
|
+
@.morph/framework/standards/frontend/nextjs/app-router.md
|
|
12
|
+
@.morph/framework/standards/frontend/nextjs/components.md
|
|
13
|
+
@.morph/framework/standards/frontend/nextjs/data-fetching.md
|
|
14
|
+
@.morph/framework/standards/frontend/nextjs/forms.md
|
|
15
|
+
@.morph/framework/standards/frontend/nextjs/state-management.md
|
|
16
|
+
@.morph/framework/standards/frontend/nextjs/testing.md
|
|
17
|
+
@.morph/framework/standards/frontend/nextjs/nextjs-patterns.md
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review-nextjs
|
|
3
|
+
description: Next.js code review checklist covering naming conventions, component architecture (Server vs Client), data fetching patterns, form implementation, state management, TypeScript/Zod discipline, feature boundaries, and testing. Use after implementing Next.js code, before creating PRs, or when reviewing TSX/TS code for compliance with MORPH-SPEC Next.js standards.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js Code Review Checklist
|
|
9
|
+
|
|
10
|
+
> Comprehensive checklist for Next.js code review: naming, component architecture, data fetching, forms, state, TypeScript, structure, and testing.
|
|
11
|
+
> **Ref:** `framework/standards/frontend/nextjs/naming-conventions.md`
|
|
12
|
+
> **Ref:** `framework/standards/frontend/nextjs/app-router.md`
|
|
13
|
+
> **Ref:** `framework/standards/frontend/nextjs/components.md`
|
|
14
|
+
> **Ref:** `framework/standards/frontend/nextjs/data-fetching.md`
|
|
15
|
+
> **Ref:** `framework/standards/frontend/nextjs/forms.md`
|
|
16
|
+
> **Ref:** `framework/standards/frontend/nextjs/state-management.md`
|
|
17
|
+
> **Ref:** `framework/standards/frontend/nextjs/testing.md`
|
|
18
|
+
> **Example:** `references/review-example-nextjs.md` — filled-in review showing expected finding format.
|
|
19
|
+
> **Script:** `scripts/scan-nextjs.mjs` — automated scan for CRITICAL/HIGH violations before manual review.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Step 1 — Run automated scan first
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
node scripts/scan-nextjs.mjs src/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Review and address CRITICAL findings before proceeding with the manual checklist below. Warnings can be addressed during review.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Naming & Style (ref: naming-conventions.md)
|
|
34
|
+
|
|
35
|
+
- [ ] `[CRITICAL]` File names use kebab-case (`user-card.tsx`, NOT `UserCard.tsx`)
|
|
36
|
+
- [ ] `[HIGH]` Components exported as named exports (`export function UserCard`, NOT `export default function UserCard`)
|
|
37
|
+
- [ ] `[HIGH]` Hook files named `use-{action}.ts` and export `use{Action}()`
|
|
38
|
+
- [ ] `[HIGH]` Schema files named `{feature}.schemas.ts` with Zod exports
|
|
39
|
+
- [ ] `[HIGH]` Type files named `{feature}.types.ts` with `z.infer<>` derived types
|
|
40
|
+
- [ ] `[MEDIUM]` No abbreviations in public API names (`repository` not `repo`)
|
|
41
|
+
- [ ] `[MEDIUM]` Feature folder uses kebab-case (`features/user-management/`, NOT `features/userManagement/`)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Component Architecture (ref: app-router.md, components.md)
|
|
46
|
+
|
|
47
|
+
### Server vs Client Discipline
|
|
48
|
+
- [ ] `[CRITICAL]` `'use client'` only on components that use hooks or event handlers
|
|
49
|
+
- [ ] `[CRITICAL]` No `useEffect(() => { fetch(...) }, [])` for data fetching — use Server Components or TanStack Query
|
|
50
|
+
- [ ] `[HIGH]` Server Components used for initial page data (no `'use client'` on page files)
|
|
51
|
+
- [ ] `[HIGH]` `loading.tsx`, `error.tsx` co-located with every `page.tsx`
|
|
52
|
+
- [ ] `[HIGH]` No business logic in `app/` route files — import from `features/`
|
|
53
|
+
|
|
54
|
+
### Three-Tier Hierarchy
|
|
55
|
+
- [ ] `[CRITICAL]` No edits to `components/ui/` files — shadcn primitives are never modified
|
|
56
|
+
- [ ] `[HIGH]` `components/` (Tier 2) has no imports from `features/` — no domain knowledge
|
|
57
|
+
- [ ] `[HIGH]` Feature components (`features/*/components/`) do not import from other features
|
|
58
|
+
- [ ] `[MEDIUM]` Feature cross-dependencies extracted to `components/` or `lib/`
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Data Fetching (ref: data-fetching.md)
|
|
63
|
+
|
|
64
|
+
- [ ] `[CRITICAL]` No `useEffect` + `useState` pattern for API data — use `useQuery`
|
|
65
|
+
- [ ] `[HIGH]` TanStack Query v5 syntax: `useQuery({ queryKey: [...], queryFn: async () => {} })`
|
|
66
|
+
- [ ] `[HIGH]` Query key factory pattern used (`userKeys.lists()`, NOT hardcoded `['users']`)
|
|
67
|
+
- [ ] `[HIGH]` `useMutation` used for POST/PUT/DELETE — not inline `fetch` in handlers
|
|
68
|
+
- [ ] `[HIGH]` API responses validated with Zod before use
|
|
69
|
+
- [ ] `[MEDIUM]` `onSuccess` in `useMutation` invalidates relevant query keys
|
|
70
|
+
- [ ] `[MEDIUM]` `QueryClientProvider` wraps app in `app/layout.tsx`, not per-component
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Forms (ref: forms.md)
|
|
75
|
+
|
|
76
|
+
- [ ] `[CRITICAL]` Zod schema defined BEFORE TypeScript type — type derived with `z.infer<>`
|
|
77
|
+
- [ ] `[HIGH]` `useForm` uses `zodResolver(schema)` — NOT manual validation
|
|
78
|
+
- [ ] `[HIGH]` shadcn `<Form>`, `<FormField>`, `<FormItem>`, `<FormLabel>`, `<FormControl>`, `<FormMessage>` used
|
|
79
|
+
- [ ] `[HIGH]` Form submission uses `useMutation` — NOT direct `fetch` in `onSubmit`
|
|
80
|
+
- [ ] `[MEDIUM]` `isPending` used for loading state — NOT `isLoading` (v5 renamed)
|
|
81
|
+
- [ ] `[MEDIUM]` Root-level errors displayed: `form.formState.errors.root`
|
|
82
|
+
- [ ] `[MEDIUM]` No `useState` for individual form fields — react-hook-form handles this
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## State Management (ref: state-management.md)
|
|
87
|
+
|
|
88
|
+
- [ ] `[HIGH]` No Zustand/Redux installed without documented justification
|
|
89
|
+
- [ ] `[HIGH]` No React Context used for server state (API data) — use TanStack Query
|
|
90
|
+
- [ ] `[MEDIUM]` Local UI state (open/closed, selected) in `useState` — not global store
|
|
91
|
+
- [ ] `[MEDIUM]` Context only for truly global UI: theme, auth user, locale
|
|
92
|
+
- [ ] `[LOW]` No prop drilling beyond 3 levels — consider Context or co-location
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## TypeScript Discipline
|
|
97
|
+
|
|
98
|
+
- [ ] `[CRITICAL]` No `any` type — use `unknown` and narrow, or fix the actual type
|
|
99
|
+
- [ ] `[HIGH]` Types derived from Zod schemas (`type User = z.infer<typeof userSchema>`)
|
|
100
|
+
- [ ] `[HIGH]` No duplicate type definitions — if the server returns it, define it once with Zod
|
|
101
|
+
- [ ] `[MEDIUM]` API response types come from the shared schema, not manually written
|
|
102
|
+
- [ ] `[MEDIUM]` `noUncheckedIndexedAccess` respected — array accesses use optional chaining
|
|
103
|
+
- [ ] `[LOW]` No type assertions (`as User`) without validation
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Feature Structure (ref: project-structure.md)
|
|
108
|
+
|
|
109
|
+
- [ ] `[HIGH]` Feature exposes public API via `features/{name}/index.ts` — no deep path imports
|
|
110
|
+
- [ ] `[HIGH]` Consumers import from index: `from '@/features/users'` NOT `from '@/features/users/components/user-list'`
|
|
111
|
+
- [ ] `[MEDIUM]` New features create: `components/`, `hooks/`, `types/` subdirectories
|
|
112
|
+
- [ ] `[MEDIUM]` TanStack Query hooks in `features/{name}/hooks/` — NOT co-located with components
|
|
113
|
+
- [ ] `[MEDIUM]` Zod schemas in `features/{name}/types/{name}.schemas.ts`
|
|
114
|
+
- [ ] `[LOW]` Feature index only exports what external consumers actually need (no over-exposure)
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Testing (ref: testing.md)
|
|
119
|
+
|
|
120
|
+
- [ ] `[HIGH]` Test files co-located with source (`user-card.test.tsx` next to `user-card.tsx`)
|
|
121
|
+
- [ ] `[HIGH]` `@testing-library/user-event` used — NOT `fireEvent`
|
|
122
|
+
- [ ] `[HIGH]` API calls mocked with MSW — NOT `jest.mock('fetch')` or `global.fetch = jest.fn()`
|
|
123
|
+
- [ ] `[MEDIUM]` Hook tests use `QueryClientWrapper` helper with `retry: false`
|
|
124
|
+
- [ ] `[MEDIUM]` Tests cover happy path + one error path per component
|
|
125
|
+
- [ ] `[LOW]` No snapshot tests — use `expect(screen.getByText(...))`
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Quick Pre-Merge Checklist
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
[ ] node scripts/scan-nextjs.mjs src/ — 0 CRITICAL findings
|
|
133
|
+
[ ] File names are kebab-case (UserCard.tsx → user-card.tsx)
|
|
134
|
+
[ ] 'use client' only on interactive components (hooks or event handlers)
|
|
135
|
+
[ ] No useEffect for data fetching — Server Component or useQuery
|
|
136
|
+
[ ] Zod schema defined first, type derived with z.infer<>
|
|
137
|
+
[ ] zodResolver connected to useForm, useMutation for submit
|
|
138
|
+
[ ] Query key factory used (userKeys.lists() not ['users'])
|
|
139
|
+
[ ] Feature public API via features/{name}/index.ts
|
|
140
|
+
[ ] components/ui/ files untouched (shadcn CLI only)
|
|
141
|
+
[ ] Tests: userEvent not fireEvent, MSW not mock fetch
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
*Covers: naming-conventions.md + app-router.md + components.md + data-fetching.md + forms.md + state-management.md + testing.md + project-structure.md*
|
|
147
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Code Review Report — User Management Feature
|
|
2
|
+
|
|
3
|
+
> Example of a well-structured Next.js code review output. Filled-in reference — not a template.
|
|
4
|
+
|
|
5
|
+
**Scope:** `src/features/users/` + `src/app/(dashboard)/users/page.tsx`
|
|
6
|
+
**Date:** 2026-02-23
|
|
7
|
+
**Reviewer:** code-review-nextjs skill
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Automated Scan Results
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
$ node scripts/scan-nextjs.mjs src/features/users/
|
|
15
|
+
|
|
16
|
+
CRITICAL (1)
|
|
17
|
+
features/users/components/UserList.tsx:1 — React hooks used (useState) without 'use client'
|
|
18
|
+
|
|
19
|
+
HIGH/MEDIUM (2)
|
|
20
|
+
features/users/components/UserList.tsx — PascalCase filename (should be user-list.tsx)
|
|
21
|
+
features/users/components/user-form.tsx — 'use client' directive present but no interactivity detected
|
|
22
|
+
|
|
23
|
+
Summary: 8 files scanned | 3 issues (1 critical, 2 high/medium)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Findings by Severity
|
|
29
|
+
|
|
30
|
+
| Severity | Count |
|
|
31
|
+
|----------|-------|
|
|
32
|
+
| CRITICAL | 2 |
|
|
33
|
+
| HIGH | 3 |
|
|
34
|
+
| MEDIUM | 2 |
|
|
35
|
+
| LOW | 1 |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### [CRITICAL] Missing 'use client' on interactive component
|
|
40
|
+
|
|
41
|
+
**File:** `src/features/users/components/UserList.tsx:1`
|
|
42
|
+
|
|
43
|
+
**Current code:**
|
|
44
|
+
```tsx
|
|
45
|
+
import { useState } from 'react';
|
|
46
|
+
|
|
47
|
+
export function UserList() {
|
|
48
|
+
const [selected, setSelected] = useState<string | null>(null);
|
|
49
|
+
return <div onClick={() => setSelected('test')}>...</div>;
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Suggested fix:**
|
|
54
|
+
```tsx
|
|
55
|
+
'use client';
|
|
56
|
+
|
|
57
|
+
import { useState } from 'react';
|
|
58
|
+
// ... rest unchanged
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Why:** React hooks (`useState`) require `'use client'`. Without it, Next.js treats this as a Server Component and the `useState` call fails at runtime.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### [CRITICAL] useEffect for data fetching
|
|
66
|
+
|
|
67
|
+
**File:** `src/features/users/components/user-list.tsx:8`
|
|
68
|
+
|
|
69
|
+
**Current code:**
|
|
70
|
+
```tsx
|
|
71
|
+
'use client';
|
|
72
|
+
import { useEffect, useState } from 'react';
|
|
73
|
+
|
|
74
|
+
export function UserList() {
|
|
75
|
+
const [users, setUsers] = useState([]);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
fetch('/api/users').then(r => r.json()).then(setUsers);
|
|
78
|
+
}, []);
|
|
79
|
+
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Suggested fix:**
|
|
84
|
+
```tsx
|
|
85
|
+
// Option A — Server Component (no 'use client' needed)
|
|
86
|
+
// app/(dashboard)/users/page.tsx
|
|
87
|
+
async function getUsers() {
|
|
88
|
+
const res = await fetch(`${process.env.API_URL}/api/users`, { next: { revalidate: 30 } });
|
|
89
|
+
return res.json();
|
|
90
|
+
}
|
|
91
|
+
export default async function UsersPage() {
|
|
92
|
+
const users = await getUsers();
|
|
93
|
+
return <UserList initialData={users} />;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Option B — TanStack Query (when client interactivity needed)
|
|
97
|
+
'use client';
|
|
98
|
+
import { useUsers } from '@/features/users/hooks/use-users';
|
|
99
|
+
export function UserList() {
|
|
100
|
+
const { data: users = [], isLoading } = useUsers();
|
|
101
|
+
if (isLoading) return <div>Loading...</div>;
|
|
102
|
+
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Why:** `useEffect` + `useState` for fetching: (1) doubles renders, (2) no caching, (3) no SSR, (4) no error/loading states, (5) can't be cancelled. TanStack Query or Server Components solve all five.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### [HIGH] PascalCase file name
|
|
111
|
+
|
|
112
|
+
**File:** `src/features/users/components/UserList.tsx`
|
|
113
|
+
|
|
114
|
+
**Suggested fix:** Rename to `user-list.tsx`
|
|
115
|
+
|
|
116
|
+
**Why:** Linux servers are case-sensitive. `UserList.tsx` and `user-list.tsx` are different files on the server but the same on macOS/Windows, causing import failures in production.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### [HIGH] Default export on non-page component
|
|
121
|
+
|
|
122
|
+
**File:** `src/features/users/components/user-card.tsx:3`
|
|
123
|
+
|
|
124
|
+
**Current code:**
|
|
125
|
+
```tsx
|
|
126
|
+
export default function UserCard({ user }: { user: User }) {
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Suggested fix:**
|
|
130
|
+
```tsx
|
|
131
|
+
export function UserCard({ user }: { user: User }) {
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Why:** Named exports are refactor-safe — IDEs track renames automatically. Default exports are anonymous in imports (`import X from './user-card'` allows `X` to be anything).
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### [HIGH] Type defined manually instead of deriving from Zod schema
|
|
139
|
+
|
|
140
|
+
**File:** `src/features/users/types/user.types.ts:1`
|
|
141
|
+
|
|
142
|
+
**Current code:**
|
|
143
|
+
```ts
|
|
144
|
+
export type User = {
|
|
145
|
+
id: string;
|
|
146
|
+
name: string;
|
|
147
|
+
email: string;
|
|
148
|
+
role: 'admin' | 'user';
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Suggested fix:**
|
|
153
|
+
```ts
|
|
154
|
+
// user.schemas.ts — single source of truth
|
|
155
|
+
export const userSchema = z.object({
|
|
156
|
+
id: z.string(),
|
|
157
|
+
name: z.string(),
|
|
158
|
+
email: z.string().email(),
|
|
159
|
+
role: z.enum(['admin', 'user']),
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// user.types.ts — derived, never written manually
|
|
163
|
+
export type User = z.infer<typeof userSchema>;
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Why:** Manually written types drift from API responses. `z.infer<>` ensures the TypeScript type is always in sync with the runtime validation.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### [MEDIUM] Deep path import instead of feature index
|
|
171
|
+
|
|
172
|
+
**File:** `src/app/(dashboard)/users/page.tsx:2`
|
|
173
|
+
|
|
174
|
+
**Current code:**
|
|
175
|
+
```tsx
|
|
176
|
+
import { UserList } from '@/features/users/components/user-list';
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Suggested fix:**
|
|
180
|
+
```tsx
|
|
181
|
+
import { UserList } from '@/features/users';
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Why:** Deep path imports expose internal structure. When `user-list.tsx` moves or is renamed, every consumer breaks. The feature index is the stable public API.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### [MEDIUM] Query key not using factory pattern
|
|
189
|
+
|
|
190
|
+
**File:** `src/features/users/hooks/use-users.ts:8`
|
|
191
|
+
|
|
192
|
+
**Current code:**
|
|
193
|
+
```ts
|
|
194
|
+
return useQuery({
|
|
195
|
+
queryKey: ['users'],
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Suggested fix:**
|
|
199
|
+
```ts
|
|
200
|
+
// query-keys.ts
|
|
201
|
+
export const userKeys = {
|
|
202
|
+
all: ['users'] as const,
|
|
203
|
+
lists: () => [...userKeys.all, 'list'] as const,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// use-users.ts
|
|
207
|
+
return useQuery({
|
|
208
|
+
queryKey: userKeys.lists(),
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Why:** Hardcoded `['users']` cannot be selectively invalidated. `queryClient.invalidateQueries({ queryKey: userKeys.lists() })` correctly invalidates only list queries, not detail queries with the same prefix.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### [LOW] Test uses fireEvent instead of userEvent
|
|
216
|
+
|
|
217
|
+
**File:** `src/features/users/components/user-card.test.tsx:14`
|
|
218
|
+
|
|
219
|
+
**Current code:**
|
|
220
|
+
```tsx
|
|
221
|
+
fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Suggested fix:**
|
|
225
|
+
```tsx
|
|
226
|
+
await userEvent.click(screen.getByRole('button', { name: /edit/i }));
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Why:** `fireEvent.click` dispatches a synthetic event. `userEvent.click` simulates the full browser interaction sequence (pointerdown, mousedown, focus, click, etc.) — closer to real user behaviour.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Top Priorities
|
|
234
|
+
|
|
235
|
+
1. `UserList.tsx:1` — CRITICAL missing `'use client'` (2 min fix)
|
|
236
|
+
2. `user-list.tsx:8` — CRITICAL useEffect fetch → useQuery (15 min)
|
|
237
|
+
3. `UserList.tsx` — HIGH rename to `user-list.tsx` (2 min)
|
|
238
|
+
4. `user-card.tsx:3` — HIGH named export (2 min)
|
|
239
|
+
5. `user.types.ts:1` — HIGH derive from Zod (10 min)
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Passed Checks ✅
|
|
244
|
+
|
|
245
|
+
- `components/ui/` files untouched
|
|
246
|
+
- `zodResolver` correctly wired in `user-form.tsx`
|
|
247
|
+
- `isPending` used (v5 correct — not `isLoading`)
|
|
248
|
+
- `loading.tsx` and `error.tsx` present in `app/(dashboard)/users/`
|
|
249
|
+
- Feature has `index.ts` re-exporting public API
|
|
250
|
+
- Test file co-located with component
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -127,7 +127,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
127
127
|
|
|
128
128
|
### Phase 2 — Design (Technical Spec)
|
|
129
129
|
|
|
130
|
-
**Goal:** Analyze schema, create spec.md, contracts.cs, decisions.md
|
|
130
|
+
**Goal:** Analyze schema, create spec.md, contracts-level{N}.cs, decisions.md
|
|
131
131
|
|
|
132
132
|
| Action | Tool | Why |
|
|
133
133
|
|--------|------|-----|
|
|
@@ -141,7 +141,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
141
141
|
| Look up library for ADR | **Context7 MCP** `query_docs()` | Compare library capabilities |
|
|
142
142
|
| Check existing code patterns | **GitHub MCP** `search_code()` | Find patterns in large repos |
|
|
143
143
|
| **Fallback:** Search codebase | **Grep** patterns across project | When no GitHub MCP |
|
|
144
|
-
| Render contracts template | **Bash** `npx morph-spec template render code/dotnet/contracts/contracts.cs ...` | CLI command |
|
|
144
|
+
| Render contracts template (detected level) | **Bash** `npx morph-spec template render code/dotnet/contracts/contracts-level{N}.cs ...` where N = level detected | CLI command |
|
|
145
145
|
| Render spec template | **Bash** `npx morph-spec template render docs/spec ...` | CLI command |
|
|
146
146
|
| Render decisions template | **Bash** `npx morph-spec template render docs/decisions ...` | CLI command |
|
|
147
147
|
| Create schema-analysis.md | **Write** to output directory | Document findings |
|
|
@@ -153,7 +153,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
|
153
153
|
- ❌ Guessing field names without checking schema (use MCP or Grep first!)
|
|
154
154
|
- ❌ Task agent to read a single spec file (just use Read)
|
|
155
155
|
- ❌ WebSearch for database schema (use Supabase MCP or code analysis)
|
|
156
|
-
- ❌ Manually writing contracts.cs from scratch (use template render)
|
|
156
|
+
- ❌ Manually writing contracts-level{N}.cs from scratch (use template render)
|
|
157
157
|
|
|
158
158
|
---
|
|
159
159
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: phase-design
|
|
3
|
-
description: MORPH-SPEC Phase 2 (Design). Analyzes codebase/schema, then produces spec.md, contracts.cs, schema-analysis.md, and decisions.md for the feature. Use after setup phase to create a full technical specification with C# contracts based on the real database schema and architecture decision records.
|
|
3
|
+
description: MORPH-SPEC Phase 2 (Design). Analyzes codebase/schema, then produces spec.md, contracts-level{N}.cs, schema-analysis.md, and decisions.md for the feature. Use after setup phase to create a full technical specification with C# contracts based on the real database schema and architecture decision records.
|
|
4
4
|
argument-hint: "[feature-name]"
|
|
5
5
|
user-invocable: false
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
@@ -35,7 +35,7 @@ Expanda a proposta em especificação técnica completa, contracts, decisões ar
|
|
|
35
35
|
| Ler arquivos de query/tipos (fallback) | **Read** cada arquivo encontrado | — |
|
|
36
36
|
| Pesquisar biblioteca para ADR | **Context7 MCP** `query_docs()` | **WebSearch** + **WebFetch** |
|
|
37
37
|
| Buscar padrões no código | **GitHub MCP** `search_code()` | **Grep** padrões no projeto |
|
|
38
|
-
| Renderizar template contracts
|
|
38
|
+
| 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 | — |
|
|
39
39
|
| Renderizar template spec.md | **Bash** `npx morph-spec template render docs/spec ...` | — |
|
|
40
40
|
| Renderizar template decisions.md | **Bash** `npx morph-spec template render docs/decisions ...` | — |
|
|
41
41
|
| Criar schema-analysis.md | **Write** no diretório de outputs | — |
|
|
@@ -47,7 +47,7 @@ Expanda a proposta em especificação técnica completa, contracts, decisões ar
|
|
|
47
47
|
- ❌ Adivinhar nomes de campos sem verificar schema (use MCP ou Grep primeiro!)
|
|
48
48
|
- ❌ Task agent para ler um único arquivo spec (use Read direto)
|
|
49
49
|
- ❌ WebSearch para schema do banco (use Supabase MCP ou análise de código)
|
|
50
|
-
- ❌ Escrever contracts.cs do zero (use template render)
|
|
50
|
+
- ❌ Escrever contracts-level{N}.cs do zero (use template render)
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
@@ -71,12 +71,48 @@ Parse o JSON para obter `activeAgents`, então use standards context (já carreg
|
|
|
71
71
|
|
|
72
72
|
**Use standards context ao gerar spec.md:**
|
|
73
73
|
- Architecture standards → guiam Technical Architecture section
|
|
74
|
-
- Coding standards → definem contracts.cs patterns
|
|
74
|
+
- Coding standards → definem contracts-level{N}.cs patterns
|
|
75
75
|
- Azure standards → determinam Infrastructure Requirements
|
|
76
76
|
|
|
77
|
+
### Passo 1.5: Detectar Nível de Domínio (domain-architect)
|
|
78
|
+
|
|
79
|
+
**⚠️ OBRIGATÓRIO:** Execute antes de gerar qualquer contrato.
|
|
80
|
+
|
|
81
|
+
**Ref:** `framework/standards/architecture/ddd/complexity-levels.md`
|
|
82
|
+
|
|
83
|
+
O `domain-architect` analisa a `proposal.md` e responde às seguintes perguntas:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
1. A entidade principal tem estados com transições? (Draft → Confirmed → Shipped)
|
|
87
|
+
2. Existem invariants de negócio? ("só cancela se estiver Ativo")
|
|
88
|
+
3. Cálculos derivados existem? (Total, Saldo, Desconto)
|
|
89
|
+
4. Outros módulos precisam reagir a mudanças? (Domain Events com consumidores)
|
|
90
|
+
5. O usuário declarou explicitamente Bounded Context na proposta?
|
|
91
|
+
|
|
92
|
+
→ Nenhuma acima: Nível 1 (CRUD)
|
|
93
|
+
→ 1-4 verdadeiros: Nível 2 (Business Logic)
|
|
94
|
+
→ 5 verdadeiro OU múltiplos domínios com modelos conflitantes: Nível 3 (BC)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Documente no spec.md** (seção `## Domain Complexity`) antes de continuar para o Passo 3.
|
|
98
|
+
|
|
99
|
+
**Template a usar no Passo 4 (contracts-level{N}.cs):**
|
|
100
|
+
|
|
101
|
+
| Nível | Template |
|
|
102
|
+
|-------|----------|
|
|
103
|
+
| 1 | `code/dotnet/contracts/contracts-level1.cs` |
|
|
104
|
+
| 2 | `code/dotnet/contracts/contracts-level2.cs` |
|
|
105
|
+
| 3 | `code/dotnet/contracts/contracts-level3.cs` |
|
|
106
|
+
|
|
107
|
+
**Para Nível 2+:** Preencha o `## Aggregate Blueprint` no spec.md antes de gerar contracts-level{N}.cs.
|
|
108
|
+
|
|
109
|
+
**Para Nível 3:** Adicione `BOUNDED_CONTEXT` como variável ao renderizar o template.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
77
113
|
### Passo 2: Analisar Código Existente (CRÍTICO - FAZER ANTES DE CONTRACTS!)
|
|
78
114
|
|
|
79
|
-
**⚠️ ATENÇÃO:** Este passo é OBRIGATÓRIO antes de gerar `contracts.cs`. Previne geração de DTOs com nomes de campos errados.
|
|
115
|
+
**⚠️ ATENÇÃO:** Este passo é OBRIGATÓRIO antes de gerar `contracts-level{N}.cs`. Previne geração de DTOs com nomes de campos errados.
|
|
80
116
|
|
|
81
117
|
**Delegate para skill dedicada:**
|
|
82
118
|
|
|
@@ -139,7 +175,7 @@ Se houver recursos Azure:
|
|
|
139
175
|
|
|
140
176
|
**SEMPRE usar Bicep para infra!**
|
|
141
177
|
|
|
142
|
-
### Passo 4: Gerar `contracts.cs` (BASEADO NO SCHEMA REAL!)
|
|
178
|
+
### Passo 4: Gerar `contracts-level{N}.cs` (BASEADO NO SCHEMA REAL!)
|
|
143
179
|
|
|
144
180
|
**⚠️ IMPORTANTE:** Use `schema-analysis.md` (do Passo 2) para gerar DTOs corretos!
|
|
145
181
|
|
|
@@ -148,7 +184,7 @@ Se houver recursos Azure:
|
|
|
148
184
|
```bash
|
|
149
185
|
# Use o template de contracts com dados do schema-analysis.md:
|
|
150
186
|
npx morph-spec template render \
|
|
151
|
-
code/dotnet/contracts/contracts.cs \
|
|
187
|
+
code/dotnet/contracts/contracts-level{N}.cs \
|
|
152
188
|
.morph/features/$ARGUMENTS/1-design/contracts.cs \
|
|
153
189
|
'{
|
|
154
190
|
"FEATURE_NAME": "$ARGUMENTS",
|
|
@@ -164,7 +200,7 @@ npx morph-spec template render \
|
|
|
164
200
|
|
|
165
201
|
```bash
|
|
166
202
|
# Leia o template base:
|
|
167
|
-
Read: .morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs
|
|
203
|
+
Read: .morph/framework/templates/code/dotnet/contracts/contracts-level{N}.cs.hbs
|
|
168
204
|
|
|
169
205
|
# Preencha manualmente usando dados de schema-analysis.md
|
|
170
206
|
# Template contém placeholders para:
|
|
@@ -268,7 +304,7 @@ Apresente ao usuário 3 ações sugeridas:
|
|
|
268
304
|
## Critérios de Avanço
|
|
269
305
|
|
|
270
306
|
- [x] `spec.md` completo com todos os requisitos
|
|
271
|
-
- [x] `contracts.cs` com interfaces e DTOs
|
|
307
|
+
- [x] `contracts-level{N}.cs` com interfaces e DTOs
|
|
272
308
|
- [x] `decisions.md` com ADRs relevantes
|
|
273
309
|
- [x] Custos estimados e documentados (se houver infra)
|
|
274
310
|
- [x] State atualizado
|
|
@@ -73,6 +73,44 @@ npx morph-spec approval get $ARGUMENTS design
|
|
|
73
73
|
|
|
74
74
|
---
|
|
75
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
|
+
|
|
76
114
|
### Passo 1: Analisar Spec
|
|
77
115
|
|
|
78
116
|
Leia `.morph/features/$ARGUMENTS/1-design/spec.md` e identifique:
|