@polymorphism-tech/morph-spec 4.11.1 → 4.13.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 +21 -29
- package/bin/morph-spec.js +41 -24
- package/bin/task-manager.js +962 -1341
- package/bin/validate.js +1 -1
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +10 -11
- package/docs/QUICKSTART.md +15 -15
- package/framework/CLAUDE.md +5 -2
- package/framework/agents/README.md +3 -4
- package/framework/agents/ai-agents/ai-system-architect.md +6 -10
- package/framework/agents/architecture/seo-growth-hacker.md +166 -326
- package/framework/agents/architecture/standards-architect.md +21 -31
- package/framework/agents/backend/dotnet-senior.md +160 -86
- package/framework/agents/backend/ef-modeler.md +2 -6
- package/framework/agents/backend/hangfire-orchestrator.md +8 -9
- package/framework/agents/backend/ms-agent-expert.md +1 -1
- package/framework/agents/frontend/nextjs-expert.md +198 -133
- package/framework/agents/frontend/ui-ux-designer.md +226 -267
- package/framework/agents/infrastructure/infra-architect.md +191 -27
- package/framework/agents/integrations/clerk-auth.md +19 -26
- package/framework/agents/integrations/hangfire-integration.md +1 -4
- package/framework/agents.json +226 -1454
- package/framework/commands/morph-apply.md +4 -4
- package/framework/commands/morph-preflight.md +4 -26
- package/framework/commands/morph-proposal.md +19 -19
- package/framework/commands/morph-status.md +2 -2
- package/framework/commands/morph-troubleshoot.md +6 -13
- package/framework/hooks/README.md +1 -6
- package/framework/hooks/claude-code/post-tool-use/agent-complete.js +122 -0
- package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +4 -6
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
- package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
- package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
- package/framework/hooks/claude-code/statusline.py +4 -5
- package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
- package/framework/hooks/shared/compact-restore.js +28 -5
- package/framework/hooks/shared/dispatch-helpers.js +17 -0
- package/framework/hooks/shared/phase-utils.js +4 -8
- package/framework/hooks/shared/state-reader.js +34 -3
- package/framework/phases.json +7 -45
- package/framework/rules/ai-agents-standards.md +15 -0
- package/framework/rules/asaas-standards.md +13 -0
- package/framework/rules/clerk-standards.md +13 -0
- package/framework/rules/csharp-standards.md +8 -4
- package/framework/rules/data-standards.md +18 -0
- package/framework/rules/dotnet-templates.md +87 -0
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/hangfire-standards.md +13 -0
- package/framework/rules/infrastructure-standards.md +27 -16
- package/framework/rules/morph-workflow.md +73 -13
- package/framework/rules/nextjs-standards.md +1 -0
- package/framework/rules/nextjs-templates.md +40 -0
- package/framework/rules/resend-standards.md +12 -0
- package/framework/rules/supabase-standards.md +29 -0
- package/framework/skills/README.md +6 -8
- package/framework/skills/level-0-meta/mcp-registry.json +21 -99
- package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
- package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
- package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
- package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
- package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
- package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
- package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
- package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
- package/framework/skills/level-1-workflows/README.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +58 -124
- package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
- package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
- package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -2
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +275 -61
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
- package/framework/squad-templates/backend-only.json +6 -6
- package/framework/squad-templates/frontend-only.json +17 -8
- package/framework/squad-templates/full-stack.json +29 -24
- package/framework/standards/STANDARDS.json +1021 -2338
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
- package/framework/standards/backend/dotnet/result-pattern.md +213 -0
- package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
- package/framework/standards/backend/dotnet/scrutor.md +158 -0
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
- package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
- package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
- package/framework/standards/integration/mcp/mcp-tools.md +91 -77
- package/framework/templates/IDE-SNIPPETS.md +2 -6
- package/framework/templates/README.md +709 -814
- package/framework/templates/REGISTRY.json +223 -762
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
- package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
- package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
- package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
- package/framework/templates/code/dotnet/backend/repository.cs +148 -141
- package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
- package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
- package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
- package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
- package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
- package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
- package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
- package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
- package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
- package/framework/templates/code/dotnet/jobs/job.cs +21 -17
- package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
- package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
- package/framework/templates/code/dotnet/test.cs +192 -106
- package/framework/templates/context/ARCHITECTURE.md +89 -0
- package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
- package/framework/templates/context/CONTEXT.md +180 -181
- package/framework/templates/context/design-system.md +342 -211
- package/framework/templates/docs/onboarding.md +2 -3
- package/framework/templates/docs/proposal.md +171 -182
- package/framework/templates/docs/spec.md +1 -3
- package/framework/templates/docs/ui-components.md +0 -72
- package/framework/templates/examples/design-system-examples.md +4 -4
- package/framework/templates/feature/decisions.md +0 -66
- package/framework/templates/feature/recap.md +1 -2
- package/framework/templates/infrastructure/github/README.md +56 -593
- package/framework/templates/integrations/clerk-config.cs +0 -41
- package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
- package/framework/templates/project/validate.js +2 -4
- package/framework/templates/ui/design-system.css +1 -1
- package/framework/workflows/README.md +8 -8
- package/framework/workflows/configs/fast-track.json +51 -0
- package/framework/workflows/configs/full.json +68 -0
- package/framework/workflows/configs/standard.json +7 -3
- package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
- package/framework/workflows/docs/enforcement-pipeline.md +18 -19
- package/framework/workflows/docs/full-morph.md +69 -76
- package/framework/workflows/docs/standard.md +49 -44
- package/framework/workflows/docs/ui-refresh.md +1 -1
- package/package.json +3 -3
- package/src/commands/agents/dispatch-agents.js +55 -116
- package/src/commands/context/context-refresh.js +79 -0
- package/src/commands/mcp/mcp-setup.js +28 -6
- package/src/commands/phase/phase-reset.js +1 -1
- package/src/commands/project/doctor.js +10 -32
- package/src/commands/project/init.js +32 -1
- package/src/commands/project/status.js +6 -12
- package/src/commands/scaffold/scaffold.js +131 -0
- package/src/commands/scope/escalate.js +1 -1
- package/src/commands/state/advance-phase.js +15 -29
- package/src/commands/state/state.js +20 -5
- package/src/commands/tasks/task.js +0 -30
- package/src/commands/validation/validate-feature.js +3 -10
- package/src/core/paths/output-schema.js +12 -13
- package/src/core/state/phase-state-machine.js +211 -217
- package/src/core/state/state-manager.js +9 -9
- package/src/lib/agents/agents-manager.js +2 -2
- package/src/lib/agents/output-collector.js +1 -2
- package/src/lib/detectors/design-system-detector.js +4 -4
- package/src/lib/detectors/index.js +1 -11
- package/src/lib/generators/architecture-scanner.js +640 -0
- package/src/lib/generators/context-generator.js +3 -3
- package/src/lib/generators/design-system-generator.js +508 -298
- package/src/lib/generators/index.js +12 -10
- package/src/lib/generators/metadata-extractor.js +386 -387
- package/src/lib/generators/recap-generator.js +4 -4
- package/src/lib/generators/scaffold-generator.js +317 -0
- package/src/lib/generators/settings-generator.js +0 -1
- package/src/lib/phase-chain/phase-validator.js +64 -42
- package/src/lib/stack/stack-profile.js +2 -2
- package/src/lib/standards/digest-builder.js +72 -285
- package/src/lib/tasks/task-parser.js +11 -5
- package/src/lib/validators/architecture/architecture-validator.js +259 -387
- package/src/lib/validators/content/content-validator.js +287 -287
- package/src/lib/validators/css/css-validator.js +340 -352
- package/src/lib/validators/design-system/design-system-validator.js +11 -5
- package/src/lib/validators/packages/package-validator.js +347 -360
- package/src/lib/validators/shared/issue-counter.js +14 -18
- package/src/lib/validators/validation-runner.js +3 -19
- package/src/scripts/setup-infra.js +1 -1
- package/src/utils/agents-installer.js +24 -3
- package/src/utils/file-copier.js +1 -0
- package/src/utils/hooks-installer.js +21 -19
- package/src/utils/skills-installer.js +178 -178
- package/framework/agents/architecture/prompt-engineer.md +0 -195
- package/framework/agents/backend/api-designer.md +0 -106
- package/framework/agents/frontend/blazor-builder.md +0 -229
- package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
- package/framework/agents/infrastructure/azure-architect.md +0 -150
- package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
- package/framework/agents/infrastructure/bicep-architect.md +0 -132
- package/framework/agents/infrastructure/container-specialist.md +0 -137
- package/framework/agents/infrastructure/devops-engineer.md +0 -126
- package/framework/agents/integrations/azure-identity.md +0 -148
- package/framework/agents/quality/code-analyzer.md +0 -239
- package/framework/agents/quality/testing-specialist.md +0 -130
- package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
- package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
- package/framework/index/troubleshooting-index.json +0 -184
- package/framework/rules/testing-standards.md +0 -14
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
- package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
- package/framework/standards/ai-agents/blazor-ui.md +0 -364
- package/framework/standards/architecture/ddd/aggregates.md +0 -120
- package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
- package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
- package/framework/standards/architecture/ddd/entities.md +0 -99
- package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
- package/framework/standards/architecture/ddd/value-objects.md +0 -124
- package/framework/standards/backend/api/minimal-api.md +0 -494
- package/framework/standards/backend/api/rest.md +0 -492
- package/framework/standards/backend/authentication/passkeys.md +0 -428
- package/framework/standards/backend/database/ef-core.md +0 -199
- package/framework/standards/backend/database/migrations.md +0 -393
- package/framework/standards/backend/database/repository-patterns.md +0 -528
- package/framework/standards/backend/dotnet/async.md +0 -366
- package/framework/standards/backend/dotnet/core.md +0 -117
- package/framework/standards/backend/dotnet/di.md +0 -439
- package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
- package/framework/standards/context/analytics.md +0 -96
- package/framework/standards/context/bundles.md +0 -110
- package/framework/standards/context/priming.md +0 -78
- package/framework/standards/core/architecture.md +0 -185
- package/framework/standards/core/coding.md +0 -214
- package/framework/standards/core/git-branching-strategy.md +0 -403
- package/framework/standards/core/git.md +0 -185
- package/framework/standards/core/testing.md +0 -295
- package/framework/standards/data/nosql/blob-storage.md +0 -102
- package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
- package/framework/standards/frontend/blazor/design-checklist.md +0 -222
- package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
- package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
- package/framework/standards/frontend/blazor/html-conversion.md +0 -184
- package/framework/standards/frontend/blazor/lifecycle.md +0 -195
- package/framework/standards/frontend/blazor/pitfalls.md +0 -198
- package/framework/standards/frontend/blazor/state.md +0 -191
- package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -213
- package/framework/standards/infrastructure/azure/azure.md +0 -624
- package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
- package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
- package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
- package/framework/standards/infrastructure/azure/services/functions.md +0 -486
- package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
- package/framework/standards/infrastructure/azure/services/storage.md +0 -407
- package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
- package/framework/standards/integration/api/graphql.md +0 -91
- package/framework/standards/integration/api/grpc.md +0 -114
- package/framework/standards/integration/api/rest-design.md +0 -95
- package/framework/standards/integration/event-driven/cqrs.md +0 -101
- package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
- package/framework/standards/integration/event-driven/service-bus.md +0 -95
- package/framework/standards/observability/logging.md +0 -131
- package/framework/standards/observability/metrics.md +0 -121
- package/framework/standards/observability/monitoring.md +0 -114
- package/framework/standards/observability/tracing.md +0 -132
- package/framework/standards/workflows/parallel-execution.md +0 -112
- package/framework/standards/workflows/thread-management.md +0 -113
- package/framework/templates/code/dotnet/backend/service.cs +0 -139
- package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
- package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
- package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
- package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
- package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
- package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
- package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
- package/framework/templates/code/dotnet/frontend/component.razor +0 -239
- package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
- package/framework/templates/infrastructure/azure/README.md +0 -286
- package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
- package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
- package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
- package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
- package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
- package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
- package/framework/templates/infrastructure/azure/deploy.sh +0 -208
- package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
- package/framework/templates/infrastructure/azure/main.bicep +0 -189
- package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
- package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
- package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
- package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
- package/framework/templates/infrastructure/azure/storage.bicep +0 -106
- package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
- package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
- package/framework/templates/integrations/azure-identity-config.cs +0 -288
- package/framework/templates/project-structure/dotnet-ddd.md +0 -70
- package/framework/templates/saas/subscription.cs +0 -347
- package/framework/templates/saas/tenant.cs +0 -338
- package/framework/templates/ui/FluentDesignTheme.cs +0 -149
- package/framework/templates/ui/MudTheme.cs +0 -281
- package/framework/workflows/configs/nodejs-cli.json +0 -40
- package/src/commands/standards/context-budget.js +0 -89
- package/src/lib/standards/index.js +0 -7
- package/src/lib/standards/standards-context-injector.js +0 -302
- package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
- package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
- package/src/lib/validators/blazor/blazor-validator.js +0 -369
- package/src/lib/validators/blazor/index.js +0 -9
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# Observability Standard: Monitoring
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
Application Insights configuration and KQL query patterns for production monitoring.
|
|
5
|
-
|
|
6
|
-
## Application Insights Setup
|
|
7
|
-
|
|
8
|
-
### Connection String (not Instrumentation Key)
|
|
9
|
-
```csharp
|
|
10
|
-
// appsettings.json — use connection string, not key
|
|
11
|
-
{
|
|
12
|
-
"ApplicationInsights": {
|
|
13
|
-
"ConnectionString": "InstrumentationKey=..." // from Key Vault
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Program.cs
|
|
18
|
-
builder.Services.AddApplicationInsightsTelemetry(
|
|
19
|
-
builder.Configuration["ApplicationInsights:ConnectionString"]);
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Sampling Configuration
|
|
23
|
-
```csharp
|
|
24
|
-
builder.Services.Configure<TelemetryConfiguration>(config =>
|
|
25
|
-
{
|
|
26
|
-
var sampler = new AdaptiveSamplingTelemetryProcessor(null!);
|
|
27
|
-
sampler.MaxTelemetryItemsPerSecond = 5; // Limit volume
|
|
28
|
-
sampler.ExcludedTypes = "Request"; // Don't sample requests
|
|
29
|
-
config.TelemetryProcessorChainBuilder.Use(_ => sampler).Build();
|
|
30
|
-
});
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Dependency Tracking
|
|
34
|
-
```csharp
|
|
35
|
-
// Auto-tracked: HTTP, SQL, Azure SDK calls
|
|
36
|
-
// Manual tracking for custom operations:
|
|
37
|
-
using var operation = telemetryClient.StartOperation<DependencyTelemetry>("ServiceBus.Send");
|
|
38
|
-
operation.Telemetry.Type = "Azure Service Bus";
|
|
39
|
-
operation.Telemetry.Target = queueName;
|
|
40
|
-
try
|
|
41
|
-
{
|
|
42
|
-
await sender.SendMessageAsync(message);
|
|
43
|
-
operation.Telemetry.Success = true;
|
|
44
|
-
}
|
|
45
|
-
catch (Exception ex)
|
|
46
|
-
{
|
|
47
|
-
operation.Telemetry.Success = false;
|
|
48
|
-
telemetryClient.TrackException(ex);
|
|
49
|
-
throw;
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## KQL Queries — Common Scenarios
|
|
54
|
-
|
|
55
|
-
### Request Success Rate (last 24h)
|
|
56
|
-
```kql
|
|
57
|
-
requests
|
|
58
|
-
| where timestamp > ago(24h)
|
|
59
|
-
| summarize
|
|
60
|
-
total = count(),
|
|
61
|
-
failed = countif(success == false),
|
|
62
|
-
successRate = round(100.0 * countif(success == true) / count(), 2)
|
|
63
|
-
| project total, failed, successRate
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Slow Requests (> 2s)
|
|
67
|
-
```kql
|
|
68
|
-
requests
|
|
69
|
-
| where duration > 2000 and timestamp > ago(1h)
|
|
70
|
-
| project timestamp, name, url, duration, resultCode, cloud_RoleInstance
|
|
71
|
-
| order by duration desc
|
|
72
|
-
| take 20
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Exception Summary
|
|
76
|
-
```kql
|
|
77
|
-
exceptions
|
|
78
|
-
| where timestamp > ago(24h)
|
|
79
|
-
| summarize count() by type, outerMessage
|
|
80
|
-
| order by count_ desc
|
|
81
|
-
| take 10
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Dependency Failures
|
|
85
|
-
```kql
|
|
86
|
-
dependencies
|
|
87
|
-
| where success == false and timestamp > ago(1h)
|
|
88
|
-
| project timestamp, name, type, target, duration, resultCode, data
|
|
89
|
-
| order by timestamp desc
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### User Activity Heatmap
|
|
93
|
-
```kql
|
|
94
|
-
customEvents
|
|
95
|
-
| where timestamp > ago(7d)
|
|
96
|
-
| summarize events = count() by bin(timestamp, 1h), name
|
|
97
|
-
| render timechart
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## Alerting Rules
|
|
101
|
-
|
|
102
|
-
| Alert | Condition | Severity |
|
|
103
|
-
|-------|-----------|----------|
|
|
104
|
-
| High error rate | `requests` failure rate > 5% for 5 min | Critical |
|
|
105
|
-
| Slow response | P95 latency > 3s for 10 min | Warning |
|
|
106
|
-
| Exception spike | Exception count > 100/min | Critical |
|
|
107
|
-
| Dependency failure | Any dependency > 10 failures/min | Warning |
|
|
108
|
-
|
|
109
|
-
## Dashboard Required Sections
|
|
110
|
-
- Request volume + success rate (1h/24h/7d)
|
|
111
|
-
- Top slow endpoints
|
|
112
|
-
- Exception breakdown by type
|
|
113
|
-
- Dependency health grid
|
|
114
|
-
- Active user count
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# Observability Standard: Distributed Tracing
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
OpenTelemetry distributed tracing for cross-service correlation and performance analysis.
|
|
5
|
-
|
|
6
|
-
## OpenTelemetry Setup
|
|
7
|
-
|
|
8
|
-
### Packages
|
|
9
|
-
```xml
|
|
10
|
-
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.*" />
|
|
11
|
-
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.*" />
|
|
12
|
-
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.*" />
|
|
13
|
-
<PackageReference Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.*" />
|
|
14
|
-
<PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.*" />
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### Program.cs Configuration
|
|
18
|
-
```csharp
|
|
19
|
-
builder.Services.AddOpenTelemetry()
|
|
20
|
-
.WithTracing(tracing =>
|
|
21
|
-
{
|
|
22
|
-
tracing
|
|
23
|
-
.AddAspNetCoreInstrumentation(opts =>
|
|
24
|
-
{
|
|
25
|
-
opts.RecordException = true;
|
|
26
|
-
opts.Filter = ctx => !ctx.Request.Path.StartsWithSegments("/health");
|
|
27
|
-
})
|
|
28
|
-
.AddHttpClientInstrumentation()
|
|
29
|
-
.AddSqlClientInstrumentation(opts => opts.SetDbStatementForText = true)
|
|
30
|
-
.AddSource(ActivitySource.Name) // Custom activities
|
|
31
|
-
.AddAzureMonitorTraceExporter(opts =>
|
|
32
|
-
{
|
|
33
|
-
opts.ConnectionString = config["ApplicationInsights:ConnectionString"];
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// Custom ActivitySource for domain operations
|
|
38
|
-
public static class Telemetry
|
|
39
|
-
{
|
|
40
|
-
public static readonly ActivitySource ActivitySource = new("MyApp", "1.0.0");
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Custom Span Creation
|
|
45
|
-
|
|
46
|
-
### Service Method Tracing
|
|
47
|
-
```csharp
|
|
48
|
-
public async Task<Order> ProcessOrderAsync(CreateOrderCommand command)
|
|
49
|
-
{
|
|
50
|
-
using var activity = Telemetry.ActivitySource.StartActivity("ProcessOrder");
|
|
51
|
-
activity?.SetTag("order.userId", command.UserId.ToString());
|
|
52
|
-
activity?.SetTag("order.itemCount", command.Items.Count.ToString());
|
|
53
|
-
|
|
54
|
-
try
|
|
55
|
-
{
|
|
56
|
-
var order = await _repository.CreateAsync(command);
|
|
57
|
-
activity?.SetTag("order.id", order.Id.ToString());
|
|
58
|
-
activity?.SetStatus(ActivityStatusCode.Ok);
|
|
59
|
-
return order;
|
|
60
|
-
}
|
|
61
|
-
catch (Exception ex)
|
|
62
|
-
{
|
|
63
|
-
activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
|
|
64
|
-
activity?.RecordException(ex);
|
|
65
|
-
throw;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Baggage (Cross-Service Context)
|
|
71
|
-
```csharp
|
|
72
|
-
// Set correlation ID in baggage (propagates across HTTP calls)
|
|
73
|
-
Activity.Current?.SetBaggage("correlationId", correlationId);
|
|
74
|
-
Activity.Current?.SetBaggage("userId", userId.ToString());
|
|
75
|
-
|
|
76
|
-
// Read baggage downstream
|
|
77
|
-
var correlationId = Activity.Current?.GetBaggageItem("correlationId");
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Trace Context Propagation
|
|
81
|
-
|
|
82
|
-
### HTTP Client (auto-propagated)
|
|
83
|
-
```csharp
|
|
84
|
-
// HttpClient automatically propagates W3C trace context
|
|
85
|
-
// Configure in DI:
|
|
86
|
-
builder.Services.AddHttpClient("ExternalApi")
|
|
87
|
-
.AddOpenTelemetryInstrumentation();
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Service Bus (manual propagation)
|
|
91
|
-
```csharp
|
|
92
|
-
// Sender: inject trace context into message properties
|
|
93
|
-
var message = new ServiceBusMessage(body);
|
|
94
|
-
var activity = Activity.Current;
|
|
95
|
-
if (activity != null)
|
|
96
|
-
{
|
|
97
|
-
message.ApplicationProperties["traceparent"] = activity.Id;
|
|
98
|
-
message.ApplicationProperties["tracestate"] = activity.TraceStateString;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Receiver: restore trace context from message
|
|
102
|
-
if (message.ApplicationProperties.TryGetValue("traceparent", out var traceparent))
|
|
103
|
-
{
|
|
104
|
-
using var linkedActivity = Telemetry.ActivitySource.StartActivity(
|
|
105
|
-
"ProcessMessage",
|
|
106
|
-
ActivityKind.Consumer,
|
|
107
|
-
parentId: traceparent.ToString()!);
|
|
108
|
-
await ProcessAsync(message);
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Trace Sampling Strategy
|
|
113
|
-
|
|
114
|
-
| Environment | Strategy | Rate |
|
|
115
|
-
|-------------|----------|------|
|
|
116
|
-
| Development | Always | 100% |
|
|
117
|
-
| Staging | Adaptive | 10% + errors |
|
|
118
|
-
| Production | Adaptive | 5% + errors |
|
|
119
|
-
|
|
120
|
-
```csharp
|
|
121
|
-
// Production adaptive sampling (errors always sampled)
|
|
122
|
-
.AddAspNetCoreInstrumentation(opts =>
|
|
123
|
-
{
|
|
124
|
-
opts.Enrich = (activity, eventName, obj) =>
|
|
125
|
-
{
|
|
126
|
-
if (obj is HttpResponse response && response.StatusCode >= 400)
|
|
127
|
-
{
|
|
128
|
-
activity.SetSampled(true); // Always sample errors
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
})
|
|
132
|
-
```
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# Workflow Standard: Parallel Execution
|
|
2
|
-
|
|
3
|
-
## When to Use Parallel Execution
|
|
4
|
-
|
|
5
|
-
| Condition | Decision |
|
|
6
|
-
|-----------|----------|
|
|
7
|
-
| 5+ independent tasks | Use P-Threads |
|
|
8
|
-
| Multi-domain (backend + frontend + infra) | Use P-Threads with squad templates |
|
|
9
|
-
| 15+ files to create | Use P-Threads |
|
|
10
|
-
| Tasks have zero dependency overlap | Use P-Threads |
|
|
11
|
-
| Tasks share file scope | Do NOT parallelize |
|
|
12
|
-
| Sequential data flow required | Do NOT parallelize |
|
|
13
|
-
|
|
14
|
-
## Parallelization Planning
|
|
15
|
-
|
|
16
|
-
### Step 1: Dependency Analysis
|
|
17
|
-
```bash
|
|
18
|
-
morph-spec detect-workflow user-auth
|
|
19
|
-
|
|
20
|
-
# Identifies: parallelizable tasks, sequential chains, waves
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Step 2: File Scope Assignment
|
|
24
|
-
Assign exclusive file ownership to each parallel worker:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
Worker A (Backend): Entities/, Services/, Controllers/, DTOs/
|
|
28
|
-
Worker B (Frontend): Pages/, Components/, CSS/
|
|
29
|
-
Worker C (Infra): infra/bicep/, .github/workflows/
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
No overlap allowed. If overlap is unavoidable, make it sequential.
|
|
33
|
-
|
|
34
|
-
### Step 3: Choose Squad Template
|
|
35
|
-
```bash
|
|
36
|
-
morph-spec squad-template use full-stack --feature=user-auth
|
|
37
|
-
|
|
38
|
-
# Creates execution plan based on full-stack.json template:
|
|
39
|
-
# - dotnet-senior (backend lead)
|
|
40
|
-
# - blazor-builder (frontend lead)
|
|
41
|
-
# - bicep-architect (infra lead)
|
|
42
|
-
# - thread-orchestrator (coordinator)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Execution Flow
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
Orchestrator
|
|
49
|
-
│
|
|
50
|
-
├── spawn parallel: Worker A (files: Entities/, Services/)
|
|
51
|
-
├── spawn parallel: Worker B (files: Pages/, Components/)
|
|
52
|
-
└── spawn parallel: Worker C (files: infra/)
|
|
53
|
-
│
|
|
54
|
-
│ [Workers execute concurrently — no interaction]
|
|
55
|
-
│
|
|
56
|
-
├── wait-all (poll or explicit sync)
|
|
57
|
-
│
|
|
58
|
-
├── merge results (check for conflicts)
|
|
59
|
-
├── run integration validation
|
|
60
|
-
└── report consolidated output
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Conflict Resolution
|
|
64
|
-
|
|
65
|
-
### File Conflicts (two workers wrote same file)
|
|
66
|
-
```bash
|
|
67
|
-
# This should NOT happen if scopes are properly defined
|
|
68
|
-
# If it does:
|
|
69
|
-
morph-spec agents review aggregate user-auth \
|
|
70
|
-
--agents=dotnet-senior,blazor-builder \
|
|
71
|
-
--strategy=best-of-n
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Interface Mismatches (A expects contract B didn't fulfill)
|
|
75
|
-
- Document the mismatch in the coordinator report
|
|
76
|
-
- Fix in post-merge sequential step
|
|
77
|
-
- Update contracts.cs to reflect actual implementation
|
|
78
|
-
|
|
79
|
-
## Fusion vs Parallel
|
|
80
|
-
|
|
81
|
-
| Aspect | Parallel (P-Thread) | Fusion (F-Thread) |
|
|
82
|
-
|--------|--------------------|--------------------|
|
|
83
|
-
| Goal | Divide scope | Compete on same scope |
|
|
84
|
-
| Output | Different files | Same files, best one wins |
|
|
85
|
-
| Workers collaborate? | No | No |
|
|
86
|
-
| Merge | Combine all files | Select best implementation |
|
|
87
|
-
| Use case | Large features | Design decisions, quality optimization |
|
|
88
|
-
|
|
89
|
-
## Configuration
|
|
90
|
-
```json
|
|
91
|
-
// llm-interaction.json
|
|
92
|
-
{
|
|
93
|
-
"parallelExecution": {
|
|
94
|
-
"enabled": true,
|
|
95
|
-
"maxConcurrent": 3,
|
|
96
|
-
"defaultStrategy": "best-of-n"
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Squad Templates
|
|
102
|
-
|
|
103
|
-
Pre-defined squad configurations in `framework/squad-templates/`:
|
|
104
|
-
- `full-stack.json` — Backend + Frontend + Infra (6 agents)
|
|
105
|
-
- `backend-only.json` — Backend specialists only (4 agents)
|
|
106
|
-
- `frontend-only.json` — Frontend specialists only (3 agents)
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
morph-spec squad-template list
|
|
110
|
-
morph-spec squad-template show full-stack
|
|
111
|
-
morph-spec squad-template use full-stack --feature=user-auth
|
|
112
|
-
```
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Workflow Standard: Thread Management
|
|
2
|
-
|
|
3
|
-
## Thread Types
|
|
4
|
-
|
|
5
|
-
| Type | Code | Purpose | Lifecycle |
|
|
6
|
-
|------|------|---------|-----------|
|
|
7
|
-
| Base | B-Thread | Default implementation thread | Bounded by feature phase |
|
|
8
|
-
| Parallel | P-Thread | Concurrent isolated execution | Short (1 task scope) |
|
|
9
|
-
| Fusion | F-Thread | Best-of-N competing implementations | Short (1 prompt scope) |
|
|
10
|
-
| Long-Running | L-Thread | Multi-session persistent work | Days/weeks |
|
|
11
|
-
| Zero-Touch | Z-Thread | Fully autonomous execution | Bounded by trust level |
|
|
12
|
-
|
|
13
|
-
## Thread Lifecycle
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
pending → running → completed
|
|
17
|
-
→ failed → (retry) → running
|
|
18
|
-
→ killed
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Creating Threads
|
|
22
|
-
```bash
|
|
23
|
-
# Create a base thread (default)
|
|
24
|
-
morph-spec threads status morph-next-gen
|
|
25
|
-
|
|
26
|
-
# Create parallel threads for feature
|
|
27
|
-
morph-spec spawn-team morph-next-gen --parallel backend,frontend,infra
|
|
28
|
-
|
|
29
|
-
# Create fusion thread
|
|
30
|
-
morph-spec agents fuse \
|
|
31
|
-
--prompt "Implement caching strategy for UserService" \
|
|
32
|
-
--count=3 \
|
|
33
|
-
--strategy=best-of-n \
|
|
34
|
-
--feature=morph-next-gen
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Thread State in state.json
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"threads": {
|
|
41
|
-
"thread-abc12345": {
|
|
42
|
-
"id": "thread-abc12345",
|
|
43
|
-
"type": "parallel",
|
|
44
|
-
"agent": "dotnet-senior",
|
|
45
|
-
"feature": "user-auth",
|
|
46
|
-
"status": "running",
|
|
47
|
-
"startedAt": "2026-02-19T00:00:00Z",
|
|
48
|
-
"events": [
|
|
49
|
-
{ "type": "started", "timestamp": "..." },
|
|
50
|
-
{ "type": "checkpoint_passed", "timestamp": "...", "checkpointNum": 1 }
|
|
51
|
-
],
|
|
52
|
-
"metrics": {
|
|
53
|
-
"tasksCompleted": 3,
|
|
54
|
-
"checkpointsPassed": 1,
|
|
55
|
-
"errors": 0
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Parallel Execution Rules (P-Threads)
|
|
63
|
-
|
|
64
|
-
1. **File scope isolation**: Each P-Thread has exclusive write access to its files
|
|
65
|
-
2. **No cross-thread dependencies**: P-Thread tasks are self-contained
|
|
66
|
-
3. **Shared read access**: All P-Threads can read spec.md, standards, contracts
|
|
67
|
-
4. **Merge on completion**: Coordinator merges results after all P-Threads complete
|
|
68
|
-
5. **Max concurrent**: Default 3, max 5 (configurable in llm-interaction.json)
|
|
69
|
-
|
|
70
|
-
## Dependency Analysis
|
|
71
|
-
```bash
|
|
72
|
-
# Analyze task dependencies for parallel opportunities
|
|
73
|
-
morph-spec detect-workflow morph-next-gen
|
|
74
|
-
|
|
75
|
-
# Output:
|
|
76
|
-
# Parallelizable tasks: T001, T002, T003 (no dependencies)
|
|
77
|
-
# Sequential: T004 (depends on T001), T005 (depends on T002)
|
|
78
|
-
# Execution plan:
|
|
79
|
-
# Wave 1: [T001, T002, T003] (parallel)
|
|
80
|
-
# Wave 2: [T004, T005] (parallel, after wave 1)
|
|
81
|
-
# Wave 3: [T006] (sequential)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Long-Running Threads (L-Threads)
|
|
85
|
-
|
|
86
|
-
### Stop Hooks
|
|
87
|
-
L-Threads run periodic stop hooks every 30 minutes:
|
|
88
|
-
```json
|
|
89
|
-
// llm-interaction.json
|
|
90
|
-
{
|
|
91
|
-
"stopHooks": {
|
|
92
|
-
"enabled": true,
|
|
93
|
-
"interval": 30,
|
|
94
|
-
"maxRetries": 5,
|
|
95
|
-
"hooks": ["validate-and-continue", "validate-checkpoints"]
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Resume Pattern
|
|
101
|
-
```bash
|
|
102
|
-
# Resume L-Thread from bundle
|
|
103
|
-
morph-spec bundle load morph-next-gen
|
|
104
|
-
# Load resume context, continue from checkpoint
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Monitoring
|
|
108
|
-
```bash
|
|
109
|
-
morph-spec threads list morph-next-gen
|
|
110
|
-
morph-spec threads analytics morph-next-gen
|
|
111
|
-
morph-spec threads wait-all morph-next-gen
|
|
112
|
-
morph-spec threads wait-any morph-next-gen
|
|
113
|
-
```
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// SERVICE TEMPLATE
|
|
3
|
-
// Generated by MORPH Framework
|
|
4
|
-
// ============================================================
|
|
5
|
-
|
|
6
|
-
using Microsoft.Extensions.Logging;
|
|
7
|
-
|
|
8
|
-
namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}}.Services;
|
|
9
|
-
|
|
10
|
-
/// <summary>
|
|
11
|
-
/// Service for managing {{pascalCase FEATURE_NAME}} operations.
|
|
12
|
-
/// </summary>
|
|
13
|
-
public class {{pascalCase FEATURE_NAME}}Service(
|
|
14
|
-
I{{pascalCase FEATURE_NAME}}Repository repository,
|
|
15
|
-
ILogger<{{pascalCase FEATURE_NAME}}Service> logger) : I{{pascalCase FEATURE_NAME}}Service
|
|
16
|
-
{
|
|
17
|
-
/// <inheritdoc />
|
|
18
|
-
public async Task<{{pascalCase FEATURE_NAME}}Dto?> GetByIdAsync(int id, CancellationToken cancellationToken = default)
|
|
19
|
-
{
|
|
20
|
-
logger.LogDebug("Getting {{pascalCase FEATURE_NAME}} with ID {Id}", id);
|
|
21
|
-
|
|
22
|
-
var entity = await repository.GetByIdAsync(id, cancellationToken);
|
|
23
|
-
if (entity is null)
|
|
24
|
-
{
|
|
25
|
-
logger.LogWarning("{{pascalCase FEATURE_NAME}} with ID {Id} not found", id);
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return MapToDto(entity);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/// <inheritdoc />
|
|
33
|
-
public async Task<List<{{pascalCase FEATURE_NAME}}Dto>> GetAllAsync(CancellationToken cancellationToken = default)
|
|
34
|
-
{
|
|
35
|
-
logger.LogDebug("Getting all {{pascalCase FEATURE_NAME}}s");
|
|
36
|
-
|
|
37
|
-
var entities = await repository.GetAllAsync(cancellationToken);
|
|
38
|
-
return entities.Select(MapToDto).ToList();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/// <inheritdoc />
|
|
42
|
-
public async Task<{{pascalCase FEATURE_NAME}}Dto> CreateAsync(
|
|
43
|
-
Create{{pascalCase FEATURE_NAME}}Request request,
|
|
44
|
-
CancellationToken cancellationToken = default)
|
|
45
|
-
{
|
|
46
|
-
logger.LogInformation("Creating new {{pascalCase FEATURE_NAME}}: {Name}", request.Name);
|
|
47
|
-
|
|
48
|
-
// Validate
|
|
49
|
-
await ValidateCreateAsync(request, cancellationToken);
|
|
50
|
-
|
|
51
|
-
// Create entity
|
|
52
|
-
var entity = Domain.Entities.{{pascalCase FEATURE_NAME}}.Create(request.Name);
|
|
53
|
-
|
|
54
|
-
// Save
|
|
55
|
-
await repository.AddAsync(entity, cancellationToken);
|
|
56
|
-
await repository.SaveChangesAsync(cancellationToken);
|
|
57
|
-
|
|
58
|
-
logger.LogInformation("Created {{pascalCase FEATURE_NAME}} with ID {Id}", entity.Id);
|
|
59
|
-
|
|
60
|
-
return MapToDto(entity);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/// <inheritdoc />
|
|
64
|
-
public async Task UpdateAsync(
|
|
65
|
-
int id,
|
|
66
|
-
Update{{pascalCase FEATURE_NAME}}Request request,
|
|
67
|
-
CancellationToken cancellationToken = default)
|
|
68
|
-
{
|
|
69
|
-
logger.LogInformation("Updating {{pascalCase FEATURE_NAME}} {Id}", id);
|
|
70
|
-
|
|
71
|
-
var entity = await repository.GetByIdAsync(id, cancellationToken)
|
|
72
|
-
?? throw new {{pascalCase FEATURE_NAME}}NotFoundException(id);
|
|
73
|
-
|
|
74
|
-
// Validate
|
|
75
|
-
await ValidateUpdateAsync(entity, request, cancellationToken);
|
|
76
|
-
|
|
77
|
-
// Update entity
|
|
78
|
-
entity.UpdateName(request.Name);
|
|
79
|
-
|
|
80
|
-
// Save
|
|
81
|
-
repository.Update(entity);
|
|
82
|
-
await repository.SaveChangesAsync(cancellationToken);
|
|
83
|
-
|
|
84
|
-
logger.LogInformation("Updated {{pascalCase FEATURE_NAME}} {Id}", id);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/// <inheritdoc />
|
|
88
|
-
public async Task DeleteAsync(int id, CancellationToken cancellationToken = default)
|
|
89
|
-
{
|
|
90
|
-
logger.LogInformation("Deleting {{pascalCase FEATURE_NAME}} {Id}", id);
|
|
91
|
-
|
|
92
|
-
var entity = await repository.GetByIdAsync(id, cancellationToken)
|
|
93
|
-
?? throw new {{pascalCase FEATURE_NAME}}NotFoundException(id);
|
|
94
|
-
|
|
95
|
-
// Soft delete or remove
|
|
96
|
-
repository.Remove(entity);
|
|
97
|
-
await repository.SaveChangesAsync(cancellationToken);
|
|
98
|
-
|
|
99
|
-
logger.LogInformation("Deleted {{pascalCase FEATURE_NAME}} {Id}", id);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
#region Private Methods
|
|
103
|
-
|
|
104
|
-
private static {{pascalCase FEATURE_NAME}}Dto MapToDto(Domain.Entities.{{pascalCase FEATURE_NAME}} entity)
|
|
105
|
-
{
|
|
106
|
-
return new {{pascalCase FEATURE_NAME}}Dto(
|
|
107
|
-
entity.Id,
|
|
108
|
-
entity.Name,
|
|
109
|
-
entity.Status,
|
|
110
|
-
entity.CreatedAt,
|
|
111
|
-
entity.UpdatedAt
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private async Task ValidateCreateAsync(
|
|
116
|
-
Create{{pascalCase FEATURE_NAME}}Request request,
|
|
117
|
-
CancellationToken cancellationToken)
|
|
118
|
-
{
|
|
119
|
-
// Add validation logic here
|
|
120
|
-
// Example: Check for duplicates
|
|
121
|
-
// var existing = await repository.FindByNameAsync(request.Name, cancellationToken);
|
|
122
|
-
// if (existing is not null)
|
|
123
|
-
// throw new ValidationException("Name already exists");
|
|
124
|
-
|
|
125
|
-
await Task.CompletedTask;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private async Task ValidateUpdateAsync(
|
|
129
|
-
Domain.Entities.{{pascalCase FEATURE_NAME}} entity,
|
|
130
|
-
Update{{pascalCase FEATURE_NAME}}Request request,
|
|
131
|
-
CancellationToken cancellationToken)
|
|
132
|
-
{
|
|
133
|
-
// Add validation logic here
|
|
134
|
-
|
|
135
|
-
await Task.CompletedTask;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
#endregion
|
|
139
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// {{titleCase FEATURE_NAME}} - Commands (CQRS)
|
|
3
|
-
// Generated by MORPH-SPEC Framework
|
|
4
|
-
// ============================================================================
|
|
5
|
-
|
|
6
|
-
using MediatR;
|
|
7
|
-
|
|
8
|
-
namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}}.Commands;
|
|
9
|
-
|
|
10
|
-
// ============================================================================
|
|
11
|
-
// Create Command
|
|
12
|
-
// ============================================================================
|
|
13
|
-
|
|
14
|
-
/// <summary>
|
|
15
|
-
/// Command to create a new {{titleCase FEATURE_NAME}}
|
|
16
|
-
/// </summary>
|
|
17
|
-
public record Create{{pascalCase FEATURE_NAME}}Command : IRequest<Create{{pascalCase FEATURE_NAME}}Result>
|
|
18
|
-
{
|
|
19
|
-
// TODO: Add required properties
|
|
20
|
-
// public required string Name { get; init; }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public record Create{{pascalCase FEATURE_NAME}}Result
|
|
24
|
-
{
|
|
25
|
-
public bool IsSuccess { get; init; }
|
|
26
|
-
public int? Id { get; init; }
|
|
27
|
-
public string? Error { get; init; }
|
|
28
|
-
|
|
29
|
-
public static Create{{pascalCase FEATURE_NAME}}Result Success(int id) => new() { IsSuccess = true, Id = id };
|
|
30
|
-
public static Create{{pascalCase FEATURE_NAME}}Result Failure(string error) => new() { IsSuccess = false, Error = error };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ============================================================================
|
|
34
|
-
// Update Command
|
|
35
|
-
// ============================================================================
|
|
36
|
-
|
|
37
|
-
/// <summary>
|
|
38
|
-
/// Command to update an existing {{titleCase FEATURE_NAME}}
|
|
39
|
-
/// </summary>
|
|
40
|
-
public record Update{{pascalCase FEATURE_NAME}}Command : IRequest<Update{{pascalCase FEATURE_NAME}}Result>
|
|
41
|
-
{
|
|
42
|
-
public required int Id { get; init; }
|
|
43
|
-
// TODO: Add updatable properties
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public record Update{{pascalCase FEATURE_NAME}}Result
|
|
47
|
-
{
|
|
48
|
-
public bool IsSuccess { get; init; }
|
|
49
|
-
public string? Error { get; init; }
|
|
50
|
-
|
|
51
|
-
public static Update{{pascalCase FEATURE_NAME}}Result Success() => new() { IsSuccess = true };
|
|
52
|
-
public static Update{{pascalCase FEATURE_NAME}}Result Failure(string error) => new() { IsSuccess = false, Error = error };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// ============================================================================
|
|
56
|
-
// Delete Command
|
|
57
|
-
// ============================================================================
|
|
58
|
-
|
|
59
|
-
/// <summary>
|
|
60
|
-
/// Command to delete a {{titleCase FEATURE_NAME}}
|
|
61
|
-
/// </summary>
|
|
62
|
-
public record Delete{{pascalCase FEATURE_NAME}}Command : IRequest<Delete{{pascalCase FEATURE_NAME}}Result>
|
|
63
|
-
{
|
|
64
|
-
public required int Id { get; init; }
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public record Delete{{pascalCase FEATURE_NAME}}Result
|
|
68
|
-
{
|
|
69
|
-
public bool IsSuccess { get; init; }
|
|
70
|
-
public string? Error { get; init; }
|
|
71
|
-
|
|
72
|
-
public static Delete{{pascalCase FEATURE_NAME}}Result Success() => new() { IsSuccess = true };
|
|
73
|
-
public static Delete{{pascalCase FEATURE_NAME}}Result Failure(string error) => new() { IsSuccess = false, Error = error };
|
|
74
|
-
}
|