@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,69 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// CONTRACTS: {{titleCase FEATURE_NAME}} — Level 1 (CRUD)
|
|
3
|
+
// Generated by MORPH Framework | Date: {{DATE}}
|
|
4
|
+
// Domain Complexity: CRUD — Entity simples, sem invariants de negócio
|
|
5
|
+
// Ref: framework/standards/architecture/ddd/complexity-levels.md
|
|
6
|
+
// ============================================================
|
|
7
|
+
|
|
8
|
+
using System;
|
|
9
|
+
using System.Collections.Generic;
|
|
10
|
+
using System.Threading;
|
|
11
|
+
using System.Threading.Tasks;
|
|
12
|
+
|
|
13
|
+
namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}};
|
|
14
|
+
|
|
15
|
+
#region Service Interface
|
|
16
|
+
|
|
17
|
+
/// <summary>Service for managing {{pascalCase FEATURE_NAME}} operations.</summary>
|
|
18
|
+
public interface I{{pascalCase FEATURE_NAME}}Service
|
|
19
|
+
{
|
|
20
|
+
Task<{{pascalCase FEATURE_NAME}}Dto?> GetByIdAsync(Guid id, CancellationToken ct = default);
|
|
21
|
+
Task<List<{{pascalCase FEATURE_NAME}}Dto>> GetAllAsync(CancellationToken ct = default);
|
|
22
|
+
Task<{{pascalCase FEATURE_NAME}}Dto> CreateAsync(Create{{pascalCase FEATURE_NAME}}Request request, CancellationToken ct = default);
|
|
23
|
+
Task UpdateAsync(Guid id, Update{{pascalCase FEATURE_NAME}}Request request, CancellationToken ct = default);
|
|
24
|
+
Task DeleteAsync(Guid id, CancellationToken ct = default);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#endregion
|
|
28
|
+
|
|
29
|
+
#region DTOs
|
|
30
|
+
|
|
31
|
+
public record {{pascalCase FEATURE_NAME}}Dto(
|
|
32
|
+
Guid Id,
|
|
33
|
+
string Name,
|
|
34
|
+
DateTime CreatedAt,
|
|
35
|
+
DateTime? UpdatedAt
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
public record Create{{pascalCase FEATURE_NAME}}Request(
|
|
39
|
+
string Name
|
|
40
|
+
// Add required fields
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
public record Update{{pascalCase FEATURE_NAME}}Request(
|
|
44
|
+
string? Name
|
|
45
|
+
// Add updatable fields
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
#endregion
|
|
49
|
+
|
|
50
|
+
#region Repository Interface
|
|
51
|
+
|
|
52
|
+
public interface I{{pascalCase FEATURE_NAME}}Repository
|
|
53
|
+
{
|
|
54
|
+
Task<{{pascalCase FEATURE_NAME}}?> GetByIdAsync(Guid id, CancellationToken ct = default);
|
|
55
|
+
Task<List<{{pascalCase FEATURE_NAME}}>> GetAllAsync(CancellationToken ct = default);
|
|
56
|
+
Task AddAsync({{pascalCase FEATURE_NAME}} entity, CancellationToken ct = default);
|
|
57
|
+
void Update({{pascalCase FEATURE_NAME}} entity);
|
|
58
|
+
void Remove({{pascalCase FEATURE_NAME}} entity);
|
|
59
|
+
Task SaveChangesAsync(CancellationToken ct = default);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#endregion
|
|
63
|
+
|
|
64
|
+
#region Exceptions
|
|
65
|
+
|
|
66
|
+
public class {{pascalCase FEATURE_NAME}}NotFoundException(Guid id)
|
|
67
|
+
: Exception($"{{pascalCase FEATURE_NAME}} '{id}' not found.");
|
|
68
|
+
|
|
69
|
+
#endregion
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// CONTRACTS: {{titleCase FEATURE_NAME}} — Level 2 (Business Logic)
|
|
3
|
+
// Generated by MORPH Framework | Date: {{DATE}}
|
|
4
|
+
// Domain Complexity: Aggregate com invariants, Domain Events, CQRS
|
|
5
|
+
// Ref: framework/standards/architecture/ddd/aggregates.md
|
|
6
|
+
// framework/standards/architecture/ddd/complexity-levels.md
|
|
7
|
+
// ============================================================
|
|
8
|
+
|
|
9
|
+
using System;
|
|
10
|
+
using System.Collections.Generic;
|
|
11
|
+
using System.Threading;
|
|
12
|
+
using System.Threading.Tasks;
|
|
13
|
+
using MediatR;
|
|
14
|
+
|
|
15
|
+
// ===== AGGREGATE ROOT =====
|
|
16
|
+
// Implemente em: Domain/{{pascalCase FEATURE_NAME}}s/Aggregates/{{pascalCase FEATURE_NAME}}.cs
|
|
17
|
+
// Invariants documentados no spec.md > Aggregate Blueprint
|
|
18
|
+
//
|
|
19
|
+
// public sealed class {{pascalCase FEATURE_NAME}} : AggregateRoot
|
|
20
|
+
// {
|
|
21
|
+
// private {{pascalCase FEATURE_NAME}}() { } // EF constructor
|
|
22
|
+
// public static {{pascalCase FEATURE_NAME}} Create(/* params */) { /* validate + RaiseDomainEvent */ }
|
|
23
|
+
// public void {Action}() { /* validate invariant + mutate + RaiseDomainEvent */ }
|
|
24
|
+
// }
|
|
25
|
+
|
|
26
|
+
namespace {{NAMESPACE}}.Domain.{{pascalCase FEATURE_NAME}}s.Events;
|
|
27
|
+
|
|
28
|
+
// ===== DOMAIN EVENTS =====
|
|
29
|
+
|
|
30
|
+
public record {{pascalCase FEATURE_NAME}}CreatedEvent(
|
|
31
|
+
Guid {{pascalCase FEATURE_NAME}}Id,
|
|
32
|
+
Guid UserId
|
|
33
|
+
) : DomainEvent;
|
|
34
|
+
|
|
35
|
+
// Add events per state change: {{pascalCase FEATURE_NAME}}ConfirmedEvent, {{pascalCase FEATURE_NAME}}CancelledEvent, etc.
|
|
36
|
+
|
|
37
|
+
namespace {{NAMESPACE}}.Application.{{pascalCase FEATURE_NAME}}s.Commands;
|
|
38
|
+
|
|
39
|
+
// ===== COMMANDS (CQRS) =====
|
|
40
|
+
|
|
41
|
+
public record Create{{pascalCase FEATURE_NAME}}Command(
|
|
42
|
+
Guid UserId
|
|
43
|
+
// Add fields
|
|
44
|
+
) : IRequest<Create{{pascalCase FEATURE_NAME}}Result>;
|
|
45
|
+
|
|
46
|
+
public record Create{{pascalCase FEATURE_NAME}}Result(Guid Id);
|
|
47
|
+
|
|
48
|
+
// public record Cancel{{pascalCase FEATURE_NAME}}Command(Guid Id, string Reason) : IRequest;
|
|
49
|
+
|
|
50
|
+
namespace {{NAMESPACE}}.Application.{{pascalCase FEATURE_NAME}}s.Queries;
|
|
51
|
+
|
|
52
|
+
// ===== QUERIES =====
|
|
53
|
+
|
|
54
|
+
public record Get{{pascalCase FEATURE_NAME}}Query(Guid Id) : IRequest<{{pascalCase FEATURE_NAME}}Dto?>;
|
|
55
|
+
public record List{{pascalCase FEATURE_NAME}}sQuery() : IRequest<List<{{pascalCase FEATURE_NAME}}Dto>>;
|
|
56
|
+
|
|
57
|
+
namespace {{NAMESPACE}}.Application.{{pascalCase FEATURE_NAME}}s;
|
|
58
|
+
|
|
59
|
+
// ===== DTOs (read models — nunca expõe o Aggregate diretamente) =====
|
|
60
|
+
|
|
61
|
+
public record {{pascalCase FEATURE_NAME}}Dto(
|
|
62
|
+
Guid Id,
|
|
63
|
+
string Status,
|
|
64
|
+
DateTime CreatedAt,
|
|
65
|
+
DateTime? UpdatedAt
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
namespace {{NAMESPACE}}.Domain.{{pascalCase FEATURE_NAME}}s;
|
|
69
|
+
|
|
70
|
+
// ===== REPOSITORY (um por Aggregate Root) =====
|
|
71
|
+
|
|
72
|
+
public interface I{{pascalCase FEATURE_NAME}}Repository
|
|
73
|
+
{
|
|
74
|
+
Task<{{pascalCase FEATURE_NAME}}?> GetAsync(Guid id, CancellationToken ct = default);
|
|
75
|
+
Task AddAsync({{pascalCase FEATURE_NAME}} aggregate, CancellationToken ct = default);
|
|
76
|
+
Task UpdateAsync({{pascalCase FEATURE_NAME}} aggregate, CancellationToken ct = default);
|
|
77
|
+
Task<bool> ExistsAsync(Guid id, CancellationToken ct = default);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ===== EXCEPTIONS =====
|
|
81
|
+
|
|
82
|
+
public class {{pascalCase FEATURE_NAME}}NotFoundException(Guid id)
|
|
83
|
+
: DomainException($"{{pascalCase FEATURE_NAME}} '{id}' not found.");
|
|
84
|
+
|
|
85
|
+
public class {{pascalCase FEATURE_NAME}}InvalidStateException(string message)
|
|
86
|
+
: DomainException(message);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// CONTRACTS: {{titleCase FEATURE_NAME}} — Level 3 (Bounded Context)
|
|
3
|
+
// Generated by MORPH Framework | Date: {{DATE}}
|
|
4
|
+
// Bounded Context: {{BOUNDED_CONTEXT}}
|
|
5
|
+
// Ref: framework/standards/architecture/ddd/bounded-contexts.md
|
|
6
|
+
// framework/standards/architecture/ddd/complexity-levels.md
|
|
7
|
+
// ============================================================
|
|
8
|
+
//
|
|
9
|
+
// ⚠️ REGRAS DE BC:
|
|
10
|
+
// 1. Referências cross-BC APENAS por ID (nunca navigation property)
|
|
11
|
+
// 2. Comunicação cross-BC APENAS via Integration Events
|
|
12
|
+
// 3. Cada BC tem seu próprio repositório (nunca compartilhar DbContext)
|
|
13
|
+
// 4. Linguagem Ubíqua em 1-design/ubiquitous-language.md
|
|
14
|
+
|
|
15
|
+
// ===== TUDO DO NÍVEL 2 DENTRO DO NAMESPACE DO BC =====
|
|
16
|
+
|
|
17
|
+
namespace {{NAMESPACE}}.Domain.{{BOUNDED_CONTEXT}}.{{pascalCase FEATURE_NAME}}s;
|
|
18
|
+
|
|
19
|
+
// Aggregates, ValueObjects, Events — mesma estrutura do Level 2
|
|
20
|
+
// mas dentro do namespace do Bounded Context ({{BOUNDED_CONTEXT}})
|
|
21
|
+
|
|
22
|
+
// ===== INTEGRATION EVENTS (comunicação cross-BC) =====
|
|
23
|
+
|
|
24
|
+
namespace {{NAMESPACE}}.Domain.{{BOUNDED_CONTEXT}}.IntegrationEvents;
|
|
25
|
+
|
|
26
|
+
// Integration Event: cross-BC (Service Bus ou MediatR INotification, assíncrono)
|
|
27
|
+
// Domain Event: intra-BC (MediatR, síncrono) — veja contracts-level2.cs
|
|
28
|
+
|
|
29
|
+
public record {{pascalCase FEATURE_NAME}}IntegrationEvent(
|
|
30
|
+
Guid {{pascalCase FEATURE_NAME}}Id,
|
|
31
|
+
string EventType,
|
|
32
|
+
DateTime OccurredAt
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// ===== CROSS-BC REFERENCES =====
|
|
36
|
+
// Exemplo correto:
|
|
37
|
+
// public class {{pascalCase FEATURE_NAME}} : AggregateRoot
|
|
38
|
+
// {
|
|
39
|
+
// public Guid ExternalBcEntityId { get; private set; } // ✅ por ID
|
|
40
|
+
// // public ExternalEntity External { get; } // ❌ proibido
|
|
41
|
+
// }
|
|
@@ -83,6 +83,55 @@ public interface I{{pascalCase FEATURE_NAME}}Service
|
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
86
|
+
## Domain Complexity
|
|
87
|
+
|
|
88
|
+
**Nível:** {1 — CRUD / 2 — Business Logic / 3 — Bounded Context}
|
|
89
|
+
|
|
90
|
+
**Justificativa:** {Por que este nível foi escolhido — mencionar invariants, eventos ou BCs se Nível 2+}
|
|
91
|
+
|
|
92
|
+
**Padrões Aplicados:**
|
|
93
|
+
- {Nível 1: Entity simples, Service CRUD, DTOs}
|
|
94
|
+
- {Nível 2: AggregateRoot, Value Objects, Domain Events, CQRS}
|
|
95
|
+
- {Nível 3: Bounded Context isolation, cross-BC events, Linguagem Ubíqua}
|
|
96
|
+
|
|
97
|
+
**Padrões Omitidos:**
|
|
98
|
+
- {ex: Bounded Contexts — sistema single-domain}
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Aggregate Blueprint (Nível 2+ apenas)
|
|
103
|
+
|
|
104
|
+
> Omitir esta seção se Nível 1 (CRUD).
|
|
105
|
+
|
|
106
|
+
### Aggregate Root: {EntityName}
|
|
107
|
+
|
|
108
|
+
**Invariants:**
|
|
109
|
+
- {Invariant 1 em linguagem natural}
|
|
110
|
+
- {Invariant 2}
|
|
111
|
+
|
|
112
|
+
**Estados e Transições:**
|
|
113
|
+
```
|
|
114
|
+
{Status.Draft} → Confirm() → {Status.Confirmed} → Cancel() → {Status.Cancelled}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Domain Events:**
|
|
118
|
+
- `{EntityName}CreatedEvent` — publicado ao criar
|
|
119
|
+
- `{EntityName}StatusChangedEvent` — publicado em mudança de estado
|
|
120
|
+
|
|
121
|
+
**Value Objects:**
|
|
122
|
+
- `{ValueObjectName}` — {por que não é primitivo simples}
|
|
123
|
+
|
|
124
|
+
**Referências Cross-Aggregate (por ID):**
|
|
125
|
+
- `{OtherEntity}Id: Guid`
|
|
126
|
+
|
|
127
|
+
### Linguagem Ubíqua
|
|
128
|
+
|
|
129
|
+
| Termo | Definição | Código |
|
|
130
|
+
|-------|-----------|--------|
|
|
131
|
+
| {Termo} | {Definição do negócio} | `{ClassName.MethodName()}` |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
86
135
|
## UI/UX Design (if front-end)
|
|
87
136
|
|
|
88
137
|
### Wireframes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Multi-stage Next.js production build for EasyPanel
|
|
2
|
+
# Stage 1: Dependencies
|
|
3
|
+
FROM node:20-alpine AS deps
|
|
4
|
+
RUN apk add --no-cache libc6-compat
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
COPY package.json package-lock.json* ./
|
|
8
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
9
|
+
|
|
10
|
+
# Stage 2: Build
|
|
11
|
+
FROM node:20-alpine AS builder
|
|
12
|
+
WORKDIR /app
|
|
13
|
+
|
|
14
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
15
|
+
COPY . .
|
|
16
|
+
|
|
17
|
+
# Build args for NEXT_PUBLIC_ variables (must be available at build time)
|
|
18
|
+
ARG NEXT_PUBLIC_APP_URL
|
|
19
|
+
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL
|
|
20
|
+
|
|
21
|
+
RUN npm run build
|
|
22
|
+
|
|
23
|
+
# Stage 3: Production runner
|
|
24
|
+
FROM node:20-alpine AS runner
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
|
|
27
|
+
ENV NODE_ENV=production
|
|
28
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
29
|
+
|
|
30
|
+
RUN addgroup --system --gid 1001 nodejs
|
|
31
|
+
RUN adduser --system --uid 1001 nextjs
|
|
32
|
+
|
|
33
|
+
COPY --from=builder /app/public ./public
|
|
34
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
35
|
+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
36
|
+
|
|
37
|
+
USER nextjs
|
|
38
|
+
|
|
39
|
+
EXPOSE 3000
|
|
40
|
+
ENV PORT=3000
|
|
41
|
+
ENV HOSTNAME="0.0.0.0"
|
|
42
|
+
|
|
43
|
+
CMD ["node", "server.js"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// features/{{kebabCase featureName}}/components/{{kebabCase featureName}}-list.tsx
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import { use{{pascalCase featureName}}s } from '@/features/{{kebabCase featureName}}/hooks/use-{{kebabCase featureName}}s';
|
|
5
|
+
import { DataTable } from '@/components/data-table';
|
|
6
|
+
import type { {{pascalCase featureName}} } from '@/features/{{kebabCase featureName}}/types/{{kebabCase featureName}}.types';
|
|
7
|
+
import type { ColumnDef } from '@tanstack/react-table';
|
|
8
|
+
|
|
9
|
+
const columns: ColumnDef<{{pascalCase featureName}}>[] = [
|
|
10
|
+
{ accessorKey: 'id', header: 'ID' },
|
|
11
|
+
{ accessorKey: 'name', header: 'Name' },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
interface {{pascalCase featureName}}ListProps {
|
|
15
|
+
initialData?: {{pascalCase featureName}}[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function {{pascalCase featureName}}List({ initialData }: {{pascalCase featureName}}ListProps) {
|
|
19
|
+
const { data = initialData ?? [], isLoading } = use{{pascalCase featureName}}s();
|
|
20
|
+
|
|
21
|
+
if (isLoading) {
|
|
22
|
+
return <div className="flex items-center justify-center h-32">Loading...</div>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return <DataTable columns={columns} data={data} />;
|
|
26
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// env.mjs — Zod-validated environment variables
|
|
2
|
+
// Crashes at startup if required vars are missing — no silent undefined
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
const serverSchema = z.object({
|
|
6
|
+
API_URL: z.string().url('API_URL must be a valid URL'),
|
|
7
|
+
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const clientSchema = z.object({
|
|
11
|
+
NEXT_PUBLIC_APP_URL: z.string().url().optional(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Validate server-side env (only available on server)
|
|
15
|
+
const serverEnv = serverSchema.safeParse(process.env);
|
|
16
|
+
if (!serverEnv.success) {
|
|
17
|
+
console.error('❌ Invalid server environment variables:');
|
|
18
|
+
console.error(serverEnv.error.flatten().fieldErrors);
|
|
19
|
+
throw new Error('Invalid environment variables');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Validate client-side env
|
|
23
|
+
const clientEnv = clientSchema.safeParse({
|
|
24
|
+
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
|
|
25
|
+
});
|
|
26
|
+
if (!clientEnv.success) {
|
|
27
|
+
console.error('❌ Invalid client environment variables:');
|
|
28
|
+
console.error(clientEnv.error.flatten().fieldErrors);
|
|
29
|
+
throw new Error('Invalid client environment variables');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const env = { ...serverEnv.data, ...clientEnv.data };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// features/{{kebabCase featureName}}/components/create-{{kebabCase featureName}}-form.tsx
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
6
|
+
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
|
|
7
|
+
import { Input } from '@/components/ui/input';
|
|
8
|
+
import { Button } from '@/components/ui/button';
|
|
9
|
+
import { useCreate{{pascalCase featureName}} } from '@/features/{{kebabCase featureName}}/hooks/use-create-{{kebabCase featureName}}';
|
|
10
|
+
import { create{{pascalCase featureName}}Schema, type Create{{pascalCase featureName}}Input } from '@/features/{{kebabCase featureName}}/types/{{kebabCase featureName}}.schemas';
|
|
11
|
+
|
|
12
|
+
interface Create{{pascalCase featureName}}FormProps {
|
|
13
|
+
onSuccess?: () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function Create{{pascalCase featureName}}Form({ onSuccess }: Create{{pascalCase featureName}}FormProps) {
|
|
17
|
+
const form = useForm<Create{{pascalCase featureName}}Input>({
|
|
18
|
+
resolver: zodResolver(create{{pascalCase featureName}}Schema),
|
|
19
|
+
defaultValues: { name: '' },
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const { mutate: create{{pascalCase featureName}}, isPending } = useCreate{{pascalCase featureName}}();
|
|
23
|
+
|
|
24
|
+
function onSubmit(values: Create{{pascalCase featureName}}Input) {
|
|
25
|
+
create{{pascalCase featureName}}(values, {
|
|
26
|
+
onSuccess: () => { form.reset(); onSuccess?.(); },
|
|
27
|
+
onError: (error) => { form.setError('root', { message: error.message }); },
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Form {...form}>
|
|
33
|
+
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
|
34
|
+
<FormField
|
|
35
|
+
control={form.control}
|
|
36
|
+
name="name"
|
|
37
|
+
render={({ field }) => (
|
|
38
|
+
<FormItem>
|
|
39
|
+
<FormLabel>Name</FormLabel>
|
|
40
|
+
<FormControl>
|
|
41
|
+
<Input placeholder="Enter name" {...field} />
|
|
42
|
+
</FormControl>
|
|
43
|
+
<FormMessage />
|
|
44
|
+
</FormItem>
|
|
45
|
+
)}
|
|
46
|
+
/>
|
|
47
|
+
{form.formState.errors.root && (
|
|
48
|
+
<p className="text-sm text-destructive">{form.formState.errors.root.message}</p>
|
|
49
|
+
)}
|
|
50
|
+
<Button type="submit" disabled={isPending}>
|
|
51
|
+
{isPending ? 'Creating...' : 'Create {{pascalCase featureName}}'}
|
|
52
|
+
</Button>
|
|
53
|
+
</form>
|
|
54
|
+
</Form>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// app/(dashboard)/{{kebabCase featureName}}/page.tsx
|
|
2
|
+
// Server Component — fetches initial data, renders feature component
|
|
3
|
+
import { {{pascalCase featureName}}List } from '@/features/{{kebabCase featureName}}';
|
|
4
|
+
|
|
5
|
+
async function get{{pascalCase featureName}}List() {
|
|
6
|
+
const res = await fetch(`${process.env.API_URL}/api/{{kebabCase featureName}}`, {
|
|
7
|
+
next: { revalidate: 30 },
|
|
8
|
+
headers: { 'Content-Type': 'application/json' },
|
|
9
|
+
});
|
|
10
|
+
if (!res.ok) throw new Error('Failed to fetch {{featureName}}');
|
|
11
|
+
return res.json();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default async function {{pascalCase featureName}}Page() {
|
|
15
|
+
const data = await get{{pascalCase featureName}}List();
|
|
16
|
+
return (
|
|
17
|
+
<div className="container py-6">
|
|
18
|
+
<h1 className="text-2xl font-bold mb-6">{{pascalCase featureName}}</h1>
|
|
19
|
+
<{{pascalCase featureName}}List initialData={data} />
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": false,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noUncheckedIndexedAccess": true,
|
|
9
|
+
"noImplicitOverride": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"module": "esnext",
|
|
14
|
+
"moduleResolution": "bundler",
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"isolatedModules": true,
|
|
17
|
+
"jsx": "preserve",
|
|
18
|
+
"incremental": true,
|
|
19
|
+
"plugins": [{ "name": "next" }],
|
|
20
|
+
"paths": {
|
|
21
|
+
"@/*": ["./src/*"]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
25
|
+
"exclude": ["node_modules"]
|
|
26
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// features/{{kebabCase featureName}}/hooks/use-{{kebabCase featureName}}s.ts
|
|
2
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { {{camelCase featureName}}Schema } from '@/features/{{kebabCase featureName}}/types/{{kebabCase featureName}}.schemas';
|
|
5
|
+
import type { Create{{pascalCase featureName}}Input } from '@/features/{{kebabCase featureName}}/types/{{kebabCase featureName}}.types';
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// Query Key Factory
|
|
9
|
+
// ============================================
|
|
10
|
+
|
|
11
|
+
export const {{camelCase featureName}}Keys = {
|
|
12
|
+
all: ['{{kebabCase featureName}}'] as const,
|
|
13
|
+
lists: () => [...{{camelCase featureName}}Keys.all, 'list'] as const,
|
|
14
|
+
detail: (id: string) => [...{{camelCase featureName}}Keys.all, 'detail', id] as const,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// ============================================
|
|
18
|
+
// List Hook (TanStack Query v5 syntax)
|
|
19
|
+
// ============================================
|
|
20
|
+
|
|
21
|
+
const {{camelCase featureName}}ListSchema = z.array({{camelCase featureName}}Schema);
|
|
22
|
+
|
|
23
|
+
export function use{{pascalCase featureName}}s() {
|
|
24
|
+
return useQuery({
|
|
25
|
+
queryKey: {{camelCase featureName}}Keys.lists(),
|
|
26
|
+
queryFn: async () => {
|
|
27
|
+
const res = await fetch('/api/{{kebabCase featureName}}');
|
|
28
|
+
if (!res.ok) throw new Error('Failed to fetch {{featureName}}');
|
|
29
|
+
return {{camelCase featureName}}ListSchema.parse(await res.json());
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ============================================
|
|
35
|
+
// Create Mutation
|
|
36
|
+
// ============================================
|
|
37
|
+
|
|
38
|
+
export function useCreate{{pascalCase featureName}}() {
|
|
39
|
+
const queryClient = useQueryClient();
|
|
40
|
+
return useMutation({
|
|
41
|
+
mutationFn: async (input: Create{{pascalCase featureName}}Input) => {
|
|
42
|
+
const res = await fetch('/api/{{kebabCase featureName}}', {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: { 'Content-Type': 'application/json' },
|
|
45
|
+
body: JSON.stringify(input),
|
|
46
|
+
});
|
|
47
|
+
if (!res.ok) throw new Error('Failed to create {{featureName}}');
|
|
48
|
+
return res.json();
|
|
49
|
+
},
|
|
50
|
+
onSuccess: () => {
|
|
51
|
+
queryClient.invalidateQueries({ queryKey: {{camelCase featureName}}Keys.lists() });
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Estrutura de Pastas .NET + DDD
|
|
2
|
+
|
|
3
|
+
> Gerado na fase de Design baseado no Domain Complexity Level.
|
|
4
|
+
> Ref: framework/standards/architecture/ddd/complexity-levels.md
|
|
5
|
+
|
|
6
|
+
## Nível 1 — CRUD
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
src/{App}.Domain/
|
|
10
|
+
Entities/
|
|
11
|
+
{EntityName}.cs
|
|
12
|
+
Interfaces/
|
|
13
|
+
I{EntityName}Repository.cs
|
|
14
|
+
|
|
15
|
+
src/{App}.Application/
|
|
16
|
+
Features/{FeatureName}/
|
|
17
|
+
{FeatureName}Service.cs
|
|
18
|
+
DTOs/
|
|
19
|
+
{FeatureName}Dto.cs
|
|
20
|
+
Create{FeatureName}Request.cs
|
|
21
|
+
Update{FeatureName}Request.cs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Nível 2 — Business Logic
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/{App}.Domain/
|
|
28
|
+
{EntityName}s/
|
|
29
|
+
Aggregates/
|
|
30
|
+
{EntityName}.cs
|
|
31
|
+
ValueObjects/
|
|
32
|
+
{ValueObjectName}.cs
|
|
33
|
+
Events/
|
|
34
|
+
{EntityName}CreatedEvent.cs
|
|
35
|
+
Exceptions/
|
|
36
|
+
{EntityName}NotFoundException.cs
|
|
37
|
+
I{EntityName}Repository.cs
|
|
38
|
+
|
|
39
|
+
src/{App}.Application/
|
|
40
|
+
{EntityName}s/
|
|
41
|
+
Commands/
|
|
42
|
+
Create{EntityName}Command.cs
|
|
43
|
+
Create{EntityName}Handler.cs
|
|
44
|
+
Queries/
|
|
45
|
+
Get{EntityName}Query.cs
|
|
46
|
+
Get{EntityName}Handler.cs
|
|
47
|
+
{EntityName}Dto.cs
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Nível 3 — Bounded Context
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
src/{App}.Domain/
|
|
54
|
+
{BoundedContext}/
|
|
55
|
+
{EntityName}s/
|
|
56
|
+
Aggregates/
|
|
57
|
+
{EntityName}.cs
|
|
58
|
+
ValueObjects/
|
|
59
|
+
Events/
|
|
60
|
+
Exceptions/
|
|
61
|
+
IntegrationEvents/
|
|
62
|
+
{EntityName}IntegrationEvent.cs
|
|
63
|
+
|
|
64
|
+
src/{App}.Application/
|
|
65
|
+
{BoundedContext}/
|
|
66
|
+
{EntityName}s/
|
|
67
|
+
Commands/
|
|
68
|
+
Queries/
|
|
69
|
+
{EntityName}Dto.cs
|
|
70
|
+
```
|
|
@@ -105,7 +105,8 @@ export function loadStandardsForAgent(agentId, projectPath) {
|
|
|
105
105
|
|-------|------------------|
|
|
106
106
|
| `blazor-builder` | blazor-lifecycle, blazor-state, blazor-efcore, blazor-pitfalls, html-to-blazor, fluent-ui-blazor, css-*, coding, architecture |
|
|
107
107
|
| `ai-system-architect` | agent-framework-*, architecture, coding |
|
|
108
|
-
| `
|
|
108
|
+
| `infra-architect` | azure, architecture, dotnet10-compatibility, infrastructure (tier-2 Infrastructure Squad Leader) |
|
|
109
|
+
| `azure-architect` | azure, architecture, dotnet10-compatibility (tier-3 specialist) |
|
|
109
110
|
| `ms-agent-expert` | agent-framework-*, coding, architecture |
|
|
110
111
|
|
|
111
112
|
### Usage
|