@polymorphism-tech/morph-spec 4.3.3 → 4.3.4
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/.morph/analytics/threads-log.jsonl +9 -0
- package/{stacks/blazor-azure/.morph → .morph}/config/config.json +9 -9
- package/.morph/state.json +48 -0
- package/bin/detect-agents.js +1 -2
- package/bin/morph-spec.js +2 -15
- package/{stacks/blazor-azure/.morph/config → framework}/agents.json +948 -948
- package/{stacks/nextjs-supabase/.claude → framework}/commands/morph-infra.md +1 -1
- package/framework/hooks/README.md +282 -0
- package/framework/hooks/agent-stop/validate-and-continue.js +96 -0
- package/framework/hooks/agent-stop/validate-checkpoints.js +101 -0
- package/framework/hooks/agent-stop/validate-tests.js +109 -0
- package/framework/hooks/agent-teams/dispatch.js +67 -0
- package/framework/hooks/agent-teams/phase-advanced.js +80 -0
- package/framework/hooks/agent-teams/task-completed.js +76 -0
- package/framework/hooks/agent-teams/teammate-idle.js +70 -0
- package/framework/hooks/commit-msg/conventional-commits.sh +33 -0
- package/framework/hooks/pre-commit/agents.sh +25 -0
- package/framework/hooks/pre-commit/orchestrator.sh +64 -0
- package/framework/hooks/pre-commit/specs.sh +50 -0
- package/framework/hooks/pre-push/run-tests.sh +44 -0
- package/framework/index/troubleshooting-index.json +184 -0
- package/framework/memory/patterns-learned.md +766 -0
- package/framework/skills/level-0-meta/README.md +7 -0
- package/framework/skills/level-0-meta/code-review.md +226 -0
- package/framework/skills/level-0-meta/morph-checklist.md +117 -0
- package/framework/skills/level-0-meta/simulation-checklist.md +77 -0
- package/framework/skills/level-1-workflows/README.md +7 -0
- package/framework/skills/level-1-workflows/morph-replicate.md +213 -0
- package/framework/skills/level-1-workflows/phase-clarify.md +131 -0
- package/framework/skills/level-1-workflows/phase-design.md +213 -0
- package/framework/skills/level-1-workflows/phase-setup.md +106 -0
- package/framework/skills/level-1-workflows/phase-tasks.md +164 -0
- package/framework/skills/level-1-workflows/phase-uiux.md +169 -0
- package/framework/skills/level-2-domains/README.md +14 -0
- package/framework/skills/level-2-domains/ai-agents/ai-system-architect.md +192 -0
- package/framework/skills/level-2-domains/architecture/po-pm-advisor.md +197 -0
- package/framework/skills/level-2-domains/architecture/prompt-engineer.md +189 -0
- package/framework/skills/level-2-domains/architecture/seo-growth-hacker.md +320 -0
- package/framework/skills/level-2-domains/architecture/standards-architect.md +156 -0
- package/framework/skills/level-2-domains/backend/api-designer.md +59 -0
- package/framework/skills/level-2-domains/backend/dotnet-senior.md +77 -0
- package/framework/skills/level-2-domains/backend/ef-modeler.md +58 -0
- package/framework/skills/level-2-domains/backend/hangfire-orchestrator.md +126 -0
- package/framework/skills/level-2-domains/backend/ms-agent-expert.md +45 -0
- package/framework/skills/level-2-domains/frontend/blazor-builder.md +210 -0
- package/framework/skills/level-2-domains/frontend/nextjs-expert.md +154 -0
- package/framework/skills/level-2-domains/frontend/ui-ux-designer.md +191 -0
- package/framework/skills/level-2-domains/infrastructure/azure-architect.md +142 -0
- package/framework/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +699 -0
- package/framework/skills/level-2-domains/infrastructure/bicep-architect.md +126 -0
- package/framework/skills/level-2-domains/infrastructure/container-specialist.md +131 -0
- package/framework/skills/level-2-domains/infrastructure/devops-engineer.md +119 -0
- package/framework/skills/level-2-domains/integrations/asaas-financial.md +130 -0
- package/framework/skills/level-2-domains/integrations/azure-identity.md +142 -0
- package/framework/skills/level-2-domains/integrations/clerk-auth.md +108 -0
- package/framework/skills/level-2-domains/integrations/hangfire-orchestrator.md +64 -0
- package/framework/skills/level-2-domains/integrations/resend-email.md +119 -0
- package/framework/skills/level-2-domains/quality/code-analyzer.md +235 -0
- package/framework/skills/level-2-domains/quality/testing-specialist.md +126 -0
- package/framework/skills/level-3-technologies/README.md +7 -0
- package/framework/skills/level-4-patterns/README.md +7 -0
- package/framework/squad-templates/backend-only.json +34 -0
- package/framework/squad-templates/frontend-only.json +34 -0
- package/framework/squad-templates/full-stack.json +52 -0
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/IDE-SNIPPETS.md +266 -0
- package/framework/templates/README.md +814 -0
- package/framework/templates/REGISTRY.json +1677 -0
- package/framework/templates/code/dotnet/backend/repository.cs +141 -0
- package/framework/templates/code/dotnet/backend/service.cs +139 -0
- package/framework/templates/code/dotnet/contracts/Commands.cs +74 -0
- package/framework/templates/code/dotnet/contracts/Entities.cs +25 -0
- package/framework/templates/code/dotnet/contracts/Queries.cs +74 -0
- package/framework/templates/code/dotnet/contracts/README.md +74 -0
- package/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -0
- package/framework/templates/code/dotnet/contracts/contracts.cs +217 -0
- package/framework/templates/code/dotnet/database/migration.cs +83 -0
- package/framework/templates/code/dotnet/frontend/component.razor +239 -0
- package/framework/templates/code/dotnet/jobs/agent.cs +163 -0
- package/framework/templates/code/dotnet/jobs/job.cs +171 -0
- package/framework/templates/code/dotnet/test.cs +239 -0
- package/framework/templates/code/sql/rls-policy.sql +57 -0
- package/framework/templates/code/sql/supabase-migration.sql +100 -0
- package/framework/templates/code/sql/supabase-migration.template.sql +113 -0
- package/framework/templates/code/typescript/contracts.ts +168 -0
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -0
- package/framework/templates/context/CONTEXT.md +181 -0
- package/framework/templates/docs/proposal.md +182 -0
- package/framework/templates/docs/spec.md +149 -0
- package/framework/templates/examples/design-system-examples.md +357 -0
- package/framework/templates/examples/spec-examples.md +90 -0
- package/framework/templates/feature/decisions.md +187 -0
- package/framework/templates/feature/recap.md +146 -0
- package/framework/templates/feature/tasks.md +199 -0
- package/framework/templates/infrastructure/azure/Dockerfile.example +82 -0
- package/framework/templates/infrastructure/azure/README.md +286 -0
- package/framework/templates/infrastructure/azure/app-insights.bicep +63 -0
- package/framework/templates/infrastructure/azure/app-service.bicep +164 -0
- package/framework/templates/infrastructure/azure/container-app-env.bicep +49 -0
- package/framework/templates/infrastructure/azure/container-app.bicep +156 -0
- package/framework/templates/infrastructure/azure/deploy-checklist.md +426 -0
- package/framework/templates/infrastructure/azure/deploy.ps1 +229 -0
- package/framework/templates/infrastructure/azure/deploy.sh +208 -0
- package/framework/templates/infrastructure/azure/key-vault.bicep +91 -0
- package/framework/templates/infrastructure/azure/main.bicep +189 -0
- package/framework/templates/infrastructure/azure/parameters.dev.json +29 -0
- package/framework/templates/infrastructure/azure/parameters.prod.json +29 -0
- package/framework/templates/infrastructure/azure/parameters.staging.json +29 -0
- package/framework/templates/infrastructure/azure/sql-database.bicep +103 -0
- package/framework/templates/infrastructure/azure/storage.bicep +106 -0
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -0
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -0
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -0
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -0
- package/framework/templates/infrastructure/docker/easypanel.template.json +54 -0
- package/framework/templates/infrastructure/github/README.md +593 -0
- package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +22 -0
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -0
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -0
- package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +61 -0
- package/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +31 -0
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -0
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -0
- package/framework/templates/integrations/asaas-client.cs +387 -0
- package/framework/templates/integrations/asaas-webhook.cs +351 -0
- package/framework/templates/integrations/azure-identity-config.cs +288 -0
- package/framework/templates/integrations/clerk-config.cs +258 -0
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -0
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -0
- package/framework/templates/meta-prompts/hops/hop-retry.md +78 -0
- package/framework/templates/meta-prompts/hops/hop-validation.md +97 -0
- package/framework/templates/meta-prompts/hops/hop-wrapper.md +36 -0
- package/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +113 -0
- package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -0
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -0
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +126 -0
- package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +43 -0
- package/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -0
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -0
- package/framework/templates/saas/subscription.cs +347 -0
- package/framework/templates/saas/tenant.cs +338 -0
- package/framework/templates/state.template.json +17 -0
- package/framework/templates/ui/FluentDesignTheme.cs +149 -0
- package/framework/templates/ui/MudTheme.cs +281 -0
- package/framework/templates/ui/design-system.css +226 -0
- package/framework/workflows/README.md +1041 -0
- package/framework/workflows/configs/design-impl.json +49 -0
- package/framework/workflows/configs/fast-track.json +42 -0
- package/framework/workflows/configs/full-morph.json +79 -0
- package/framework/workflows/configs/fusion.json +39 -0
- package/framework/workflows/configs/long-running.json +33 -0
- package/framework/workflows/configs/standard.json +60 -0
- package/framework/workflows/configs/ui-refresh.json +49 -0
- package/framework/workflows/configs/zero-touch.json +75 -0
- package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -0
- package/framework/workflows/docs/design-impl.md +37 -0
- package/framework/workflows/docs/enforcement-pipeline.md +668 -0
- package/framework/workflows/docs/fast-track.md +29 -0
- package/framework/workflows/docs/full-morph.md +76 -0
- package/framework/workflows/docs/standard.md +44 -0
- package/framework/workflows/docs/ui-refresh.md +39 -0
- package/package.json +3 -3
- package/src/commands/feature/create-story.js +11 -7
- package/src/commands/project/detect-agents.js +1 -2
- package/src/commands/project/init.js +69 -32
- package/src/commands/project/update.js +2 -2
- package/src/commands/templates/template-customize.js +3 -17
- package/src/commands/templates/template-list.js +1 -15
- package/src/commands/templates/template-render.js +2 -3
- package/src/commands/templates/template-show.js +3 -5
- package/src/core/templates/template-registry.js +9 -23
- package/src/lib/detectors/structure-detector.js +3 -3
- package/src/lib/generators/context-generator.js +18 -6
- package/src/lib/hooks/hook-executor.js +0 -2
- package/src/lib/orchestration/team-orchestrator.js +1 -2
- package/src/lib/standards/standards-context-injector.js +3 -4
- package/src/lib/troubleshooting/troubleshoot-grep.js +3 -9
- package/src/lib/validators/validation-runner.js +1 -2
- package/src/utils/file-copier.js +1 -2
- package/docs/README.md +0 -144
- package/docs/api/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -978
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -1049
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/api/scripts/collapse.js +0 -39
- package/docs/api/scripts/commonNav.js +0 -28
- package/docs/api/scripts/linenumber.js +0 -25
- package/docs/api/scripts/nav.js +0 -12
- package/docs/api/scripts/polyfill.js +0 -4
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/api/scripts/prettify/lang-css.js +0 -2
- package/docs/api/scripts/prettify/prettify.js +0 -28
- package/docs/api/scripts/search.js +0 -99
- package/docs/api/styles/jsdoc.css +0 -776
- package/docs/api/styles/prettify.css +0 -80
- package/docs/cli-auto-detection.md +0 -219
- package/docs/getting-started.md +0 -296
- package/docs/installation.md +0 -361
- package/docs/next-generation/AGENTS.md +0 -521
- package/docs/next-generation/ANALYSIS.md +0 -555
- package/docs/next-generation/ARCHITECTURE.md +0 -436
- package/docs/next-generation/CONTEXT-OPTIMIZATION.md +0 -267
- package/docs/next-generation/EXECUTION-FLOW.md +0 -274
- package/docs/next-generation/FEATURES.md +0 -688
- package/docs/next-generation/META-PROMPTS.md +0 -235
- package/docs/next-generation/MIGRATION-GUIDE.md +0 -253
- package/docs/next-generation/README.md +0 -231
- package/docs/next-generation/ROADMAP.md +0 -801
- package/docs/next-generation/THREAD-MANAGEMENT.md +0 -240
- package/docs/templates.md +0 -418
- package/docs/troubleshooting.md +0 -269
- package/docs/validation-checklist.md +0 -264
- package/scripts/postinstall.js +0 -132
- package/src/lib/stacks/index.js +0 -7
- package/src/lib/stacks/stack-resolver.js +0 -180
- package/stacks/blazor-azure/.claude/commands/morph-deploy.md +0 -529
- package/stacks/blazor-azure/.claude/commands/morph-infra.md +0 -209
- package/stacks/blazor-azure/.morph/.morphversion +0 -5
- package/stacks/blazor-azure/.morph/project/context/README.md +0 -17
- package/stacks/blazor-azure/CLAUDE.md +0 -155
- package/stacks/blazor-azure/README.md +0 -79
- package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +0 -221
- package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +0 -79
- package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +0 -529
- package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +0 -227
- package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +0 -122
- package/stacks/nextjs-supabase/.claude/commands/morph-status.md +0 -86
- package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +0 -122
- package/stacks/nextjs-supabase/.morph/.morphversion +0 -5
- package/stacks/nextjs-supabase/.morph/config/agents.json +0 -345
- package/stacks/nextjs-supabase/.morph/config/config.json +0 -9
- package/stacks/nextjs-supabase/.morph/project/context/README.md +0 -17
- package/stacks/nextjs-supabase/.morph/standards/ai-agents/blazor-ui.md +0 -364
- package/stacks/nextjs-supabase/.morph/standards/ai-agents/production.md +0 -415
- package/stacks/nextjs-supabase/.morph/standards/ai-agents/setup.md +0 -418
- package/stacks/nextjs-supabase/.morph/standards/ai-agents/team-orchestration.md +0 -479
- package/stacks/nextjs-supabase/.morph/standards/ai-agents/workflows.md +0 -354
- package/stacks/nextjs-supabase/.morph/standards/architecture/ddd/aggregates.md +0 -120
- package/stacks/nextjs-supabase/.morph/standards/architecture/ddd/entities.md +0 -99
- package/stacks/nextjs-supabase/.morph/standards/architecture/ddd/value-objects.md +0 -124
- package/stacks/nextjs-supabase/.morph/standards/backend/api/minimal-api.md +0 -494
- package/stacks/nextjs-supabase/.morph/standards/backend/api/rest.md +0 -492
- package/stacks/nextjs-supabase/.morph/standards/backend/api/validation.md +0 -88
- package/stacks/nextjs-supabase/.morph/standards/backend/authentication/passkeys.md +0 -428
- package/stacks/nextjs-supabase/.morph/standards/backend/database/ef-core.md +0 -199
- package/stacks/nextjs-supabase/.morph/standards/backend/database/migrations.md +0 -393
- package/stacks/nextjs-supabase/.morph/standards/backend/database/postgresql/database.md +0 -352
- package/stacks/nextjs-supabase/.morph/standards/backend/database/repository-patterns.md +0 -528
- package/stacks/nextjs-supabase/.morph/standards/backend/database/vector-search-rag.md +0 -541
- package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/async.md +0 -366
- package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/core.md +0 -117
- package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/di.md +0 -439
- package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/program-cs-checklist.md +0 -92
- package/stacks/nextjs-supabase/.morph/standards/backend/integrations/asaas/asaas-api.md +0 -216
- package/stacks/nextjs-supabase/.morph/standards/backend/integrations/clerk/clerk-auth.md +0 -290
- package/stacks/nextjs-supabase/.morph/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
- package/stacks/nextjs-supabase/.morph/standards/backend/integrations/resend/resend-email.md +0 -385
- package/stacks/nextjs-supabase/.morph/standards/context/analytics.md +0 -96
- package/stacks/nextjs-supabase/.morph/standards/context/bundles.md +0 -110
- package/stacks/nextjs-supabase/.morph/standards/context/priming.md +0 -78
- package/stacks/nextjs-supabase/.morph/standards/core/architecture.md +0 -185
- package/stacks/nextjs-supabase/.morph/standards/core/coding.md +0 -214
- package/stacks/nextjs-supabase/.morph/standards/core/git-branching-strategy.md +0 -403
- package/stacks/nextjs-supabase/.morph/standards/core/git.md +0 -185
- package/stacks/nextjs-supabase/.morph/standards/core/testing.md +0 -295
- package/stacks/nextjs-supabase/.morph/standards/data/nosql/blob-storage.md +0 -102
- package/stacks/nextjs-supabase/.morph/standards/data/nosql/cache/redis.md +0 -97
- package/stacks/nextjs-supabase/.morph/standards/data/nosql/cosmos-db.md +0 -118
- package/stacks/nextjs-supabase/.morph/standards/data/vector-search/azure-ai-search.md +0 -121
- package/stacks/nextjs-supabase/.morph/standards/data/vector-search/rag-chunking.md +0 -104
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/design-checklist.md +0 -222
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/fluent-ui-setup.md +0 -595
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/fluent-ui.md +0 -137
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/html-conversion.md +0 -184
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/lifecycle.md +0 -195
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/pitfalls.md +0 -198
- package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/state.md +0 -191
- package/stacks/nextjs-supabase/.morph/standards/frontend/design-system/animations.md +0 -151
- package/stacks/nextjs-supabase/.morph/standards/frontend/design-system/naming.md +0 -64
- package/stacks/nextjs-supabase/.morph/standards/frontend/nextjs/nextjs-patterns.md +0 -198
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/azure.md +0 -624
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/devops/local-development.md +0 -520
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/services/functions.md +0 -486
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/services/service-bus.md +0 -459
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/services/storage.md +0 -407
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/docker/easypanel-deploy.md +0 -196
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/mcp-setup.md +0 -252
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-auth.md +0 -176
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-rls.md +0 -184
- package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-storage.md +0 -153
- package/stacks/nextjs-supabase/.morph/standards/integration/api/graphql.md +0 -91
- package/stacks/nextjs-supabase/.morph/standards/integration/api/grpc.md +0 -114
- package/stacks/nextjs-supabase/.morph/standards/integration/api/rest-design.md +0 -95
- package/stacks/nextjs-supabase/.morph/standards/integration/event-driven/cqrs.md +0 -101
- package/stacks/nextjs-supabase/.morph/standards/integration/event-driven/event-sourcing.md +0 -124
- package/stacks/nextjs-supabase/.morph/standards/integration/event-driven/service-bus.md +0 -95
- package/stacks/nextjs-supabase/.morph/standards/observability/logging.md +0 -131
- package/stacks/nextjs-supabase/.morph/standards/observability/metrics.md +0 -121
- package/stacks/nextjs-supabase/.morph/standards/observability/monitoring.md +0 -114
- package/stacks/nextjs-supabase/.morph/standards/observability/tracing.md +0 -132
- package/stacks/nextjs-supabase/.morph/standards/workflows/parallel-execution.md +0 -112
- package/stacks/nextjs-supabase/.morph/standards/workflows/thread-management.md +0 -113
- package/stacks/nextjs-supabase/CLAUDE.md +0 -155
- package/stacks/nextjs-supabase/README.md +0 -103
- /package/{stacks/blazor-azure/.claude → framework}/commands/morph-apply.md +0 -0
- /package/{stacks/blazor-azure/.claude → framework}/commands/morph-archive.md +0 -0
- /package/{stacks/blazor-azure/.claude → framework}/commands/morph-preflight.md +0 -0
- /package/{stacks/blazor-azure/.claude → framework}/commands/morph-proposal.md +0 -0
- /package/{stacks/blazor-azure/.claude → framework}/commands/morph-status.md +0 -0
- /package/{stacks/blazor-azure/.claude → framework}/commands/morph-troubleshoot.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/ai-agents/blazor-ui.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/ai-agents/production.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/ai-agents/setup.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/ai-agents/team-orchestration.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/ai-agents/workflows.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/architecture/ddd/aggregates.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/architecture/ddd/entities.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/architecture/ddd/value-objects.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/api/minimal-api.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/api/rest.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/api/validation.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/authentication/passkeys.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/database/ef-core.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/database/migrations.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/database/postgresql/database.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/database/repository-patterns.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/database/vector-search-rag.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/dotnet/async.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/dotnet/core.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/dotnet/di.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/dotnet/program-cs-checklist.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/integrations/asaas/asaas-api.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/integrations/clerk/clerk-auth.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/backend/integrations/resend/resend-email.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/context/analytics.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/context/bundles.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/context/priming.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/core/architecture.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/core/coding.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/core/git-branching-strategy.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/core/git.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/core/testing.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/data/nosql/blob-storage.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/data/nosql/cache/redis.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/data/nosql/cosmos-db.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/data/vector-search/azure-ai-search.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/data/vector-search/rag-chunking.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/design-checklist.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/fluent-ui-setup.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/fluent-ui.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/html-conversion.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/lifecycle.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/pitfalls.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/blazor/state.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/design-system/animations.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/design-system/naming.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/frontend/nextjs/nextjs-patterns.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/azure.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/devops/local-development.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/services/functions.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/services/service-bus.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/azure/services/storage.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/docker/easypanel-deploy.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/supabase/mcp-setup.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/supabase/supabase-auth.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/supabase/supabase-pgvector.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/supabase/supabase-rls.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/infrastructure/supabase/supabase-storage.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/integration/api/graphql.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/integration/api/grpc.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/integration/api/rest-design.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/integration/event-driven/cqrs.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/integration/event-driven/event-sourcing.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/integration/event-driven/service-bus.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/observability/logging.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/observability/metrics.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/observability/monitoring.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/observability/tracing.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/workflows/parallel-execution.md +0 -0
- /package/{stacks/blazor-azure/.morph → framework}/standards/workflows/thread-management.md +0 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
@* ============================================================
|
|
2
|
+
BLAZOR COMPONENT TEMPLATE
|
|
3
|
+
Generated by MORPH Framework
|
|
4
|
+
============================================================ *@
|
|
5
|
+
|
|
6
|
+
@page "/{{kebabCase FEATURE_NAME}}/{{kebabCase FEATURE_NAME}}s"
|
|
7
|
+
@attribute [Authorize(Policy = "CanView{{pascalCase FEATURE_NAME}}")]
|
|
8
|
+
@inject I{{pascalCase FEATURE_NAME}}Service {{pascalCase FEATURE_NAME}}Service
|
|
9
|
+
@inject ILogger<{{pascalCase FEATURE_NAME}}List> Logger
|
|
10
|
+
@inject NavigationManager Navigation
|
|
11
|
+
|
|
12
|
+
<PageTitle>{{pascalCase FEATURE_NAME}}s</PageTitle>
|
|
13
|
+
|
|
14
|
+
<div class="container-fluid">
|
|
15
|
+
<div class="row mb-4">
|
|
16
|
+
<div class="col">
|
|
17
|
+
<h1>{{pascalCase FEATURE_NAME}}s</h1>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="col-auto">
|
|
20
|
+
<AuthorizeView Policy="CanManage{{pascalCase FEATURE_NAME}}">
|
|
21
|
+
<button class="btn btn-primary" @onclick="ShowCreateModal">
|
|
22
|
+
<i class="bi bi-plus-lg"></i> New {{pascalCase FEATURE_NAME}}
|
|
23
|
+
</button>
|
|
24
|
+
</AuthorizeView>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
@if (_isLoading)
|
|
29
|
+
{
|
|
30
|
+
<div class="d-flex justify-content-center py-5">
|
|
31
|
+
<div class="spinner-border text-primary" role="status">
|
|
32
|
+
<span class="visually-hidden">Loading...</span>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
}
|
|
36
|
+
else if (_error is not null)
|
|
37
|
+
{
|
|
38
|
+
<div class="alert alert-danger" role="alert">
|
|
39
|
+
<i class="bi bi-exclamation-triangle"></i>
|
|
40
|
+
@_error
|
|
41
|
+
<button class="btn btn-link" @onclick="LoadDataAsync">Retry</button>
|
|
42
|
+
</div>
|
|
43
|
+
}
|
|
44
|
+
else if (_items is null || !_items.Any())
|
|
45
|
+
{
|
|
46
|
+
<div class="text-center py-5">
|
|
47
|
+
<i class="bi bi-inbox display-1 text-muted"></i>
|
|
48
|
+
<p class="lead mt-3">No {{kebabCase FEATURE_NAME}}s found</p>
|
|
49
|
+
<AuthorizeView Policy="CanManage{{pascalCase FEATURE_NAME}}">
|
|
50
|
+
<button class="btn btn-primary" @onclick="ShowCreateModal">
|
|
51
|
+
Create your first {{kebabCase FEATURE_NAME}}
|
|
52
|
+
</button>
|
|
53
|
+
</AuthorizeView>
|
|
54
|
+
</div>
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
{
|
|
58
|
+
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
|
|
59
|
+
@foreach (var item in _items)
|
|
60
|
+
{
|
|
61
|
+
<div class="col">
|
|
62
|
+
<div class="card h-100">
|
|
63
|
+
<div class="card-body">
|
|
64
|
+
<h5 class="card-title">@item.Name</h5>
|
|
65
|
+
<p class="card-text">
|
|
66
|
+
<span class="badge @GetStatusBadgeClass(item.Status)">
|
|
67
|
+
@item.Status
|
|
68
|
+
</span>
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
<div class="card-footer bg-transparent">
|
|
72
|
+
<small class="text-muted">
|
|
73
|
+
Created @item.CreatedAt.ToString("d")
|
|
74
|
+
</small>
|
|
75
|
+
<AuthorizeView Policy="CanManage{{pascalCase FEATURE_NAME}}">
|
|
76
|
+
<div class="float-end">
|
|
77
|
+
<button class="btn btn-sm btn-outline-primary"
|
|
78
|
+
@onclick="() => ShowEditModal(item)">
|
|
79
|
+
Edit
|
|
80
|
+
</button>
|
|
81
|
+
</div>
|
|
82
|
+
</AuthorizeView>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
}
|
|
87
|
+
</div>
|
|
88
|
+
}
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
@* Modal for Create/Edit *@
|
|
92
|
+
@if (_showModal)
|
|
93
|
+
{
|
|
94
|
+
<div class="modal fade show d-block" tabindex="-1" style="background: rgba(0,0,0,0.5)">
|
|
95
|
+
<div class="modal-dialog">
|
|
96
|
+
<div class="modal-content">
|
|
97
|
+
<div class="modal-header">
|
|
98
|
+
<h5 class="modal-title">
|
|
99
|
+
@(_editingItem is null ? "New {{pascalCase FEATURE_NAME}}" : "Edit {{pascalCase FEATURE_NAME}}")
|
|
100
|
+
</h5>
|
|
101
|
+
<button type="button" class="btn-close" @onclick="CloseModal"></button>
|
|
102
|
+
</div>
|
|
103
|
+
<EditForm Model="_formModel" OnValidSubmit="HandleSubmitAsync">
|
|
104
|
+
<DataAnnotationsValidator />
|
|
105
|
+
<div class="modal-body">
|
|
106
|
+
<div class="mb-3">
|
|
107
|
+
<label class="form-label">Name</label>
|
|
108
|
+
<InputText class="form-control" @bind-Value="_formModel.Name" />
|
|
109
|
+
<ValidationMessage For="() => _formModel.Name" />
|
|
110
|
+
</div>
|
|
111
|
+
@* Add more fields as needed *@
|
|
112
|
+
</div>
|
|
113
|
+
<div class="modal-footer">
|
|
114
|
+
<button type="button" class="btn btn-secondary" @onclick="CloseModal">
|
|
115
|
+
Cancel
|
|
116
|
+
</button>
|
|
117
|
+
<button type="submit" class="btn btn-primary" disabled="@_isSaving">
|
|
118
|
+
@if (_isSaving)
|
|
119
|
+
{
|
|
120
|
+
<span class="spinner-border spinner-border-sm"></span>
|
|
121
|
+
}
|
|
122
|
+
Save
|
|
123
|
+
</button>
|
|
124
|
+
</div>
|
|
125
|
+
</EditForm>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@code {
|
|
132
|
+
private List<{{pascalCase FEATURE_NAME}}Dto>? _items;
|
|
133
|
+
private bool _isLoading = true;
|
|
134
|
+
private bool _showModal;
|
|
135
|
+
private bool _isSaving;
|
|
136
|
+
private string? _error;
|
|
137
|
+
private {{pascalCase FEATURE_NAME}}Dto? _editingItem;
|
|
138
|
+
private {{pascalCase FEATURE_NAME}}FormModel _formModel = new();
|
|
139
|
+
|
|
140
|
+
protected override async Task OnInitializedAsync()
|
|
141
|
+
{
|
|
142
|
+
await LoadDataAsync();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private async Task LoadDataAsync()
|
|
146
|
+
{
|
|
147
|
+
_isLoading = true;
|
|
148
|
+
_error = null;
|
|
149
|
+
|
|
150
|
+
try
|
|
151
|
+
{
|
|
152
|
+
_items = await {{pascalCase FEATURE_NAME}}Service.GetAllAsync();
|
|
153
|
+
}
|
|
154
|
+
catch (Exception ex)
|
|
155
|
+
{
|
|
156
|
+
Logger.LogError(ex, "Failed to load {{kebabCase FEATURE_NAME}}s");
|
|
157
|
+
_error = "Failed to load data. Please try again.";
|
|
158
|
+
}
|
|
159
|
+
finally
|
|
160
|
+
{
|
|
161
|
+
_isLoading = false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private void ShowCreateModal()
|
|
166
|
+
{
|
|
167
|
+
_editingItem = null;
|
|
168
|
+
_formModel = new {{pascalCase FEATURE_NAME}}FormModel();
|
|
169
|
+
_showModal = true;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private void ShowEditModal({{pascalCase FEATURE_NAME}}Dto item)
|
|
173
|
+
{
|
|
174
|
+
_editingItem = item;
|
|
175
|
+
_formModel = new {{pascalCase FEATURE_NAME}}FormModel
|
|
176
|
+
{
|
|
177
|
+
Name = item.Name
|
|
178
|
+
// Map other fields
|
|
179
|
+
};
|
|
180
|
+
_showModal = true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private void CloseModal()
|
|
184
|
+
{
|
|
185
|
+
_showModal = false;
|
|
186
|
+
_formModel = new();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private async Task HandleSubmitAsync()
|
|
190
|
+
{
|
|
191
|
+
_isSaving = true;
|
|
192
|
+
|
|
193
|
+
try
|
|
194
|
+
{
|
|
195
|
+
if (_editingItem is null)
|
|
196
|
+
{
|
|
197
|
+
// Create
|
|
198
|
+
var request = new Create{{pascalCase FEATURE_NAME}}Request(_formModel.Name);
|
|
199
|
+
await {{pascalCase FEATURE_NAME}}Service.CreateAsync(request);
|
|
200
|
+
}
|
|
201
|
+
else
|
|
202
|
+
{
|
|
203
|
+
// Update
|
|
204
|
+
var request = new Update{{pascalCase FEATURE_NAME}}Request(_formModel.Name);
|
|
205
|
+
await {{pascalCase FEATURE_NAME}}Service.UpdateAsync(_editingItem.Id, request);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
CloseModal();
|
|
209
|
+
await LoadDataAsync();
|
|
210
|
+
}
|
|
211
|
+
catch (Exception ex)
|
|
212
|
+
{
|
|
213
|
+
Logger.LogError(ex, "Failed to save {{kebabCase FEATURE_NAME}}");
|
|
214
|
+
// Show error to user
|
|
215
|
+
}
|
|
216
|
+
finally
|
|
217
|
+
{
|
|
218
|
+
_isSaving = false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private static string GetStatusBadgeClass({{pascalCase FEATURE_NAME}}Status status) => status switch
|
|
223
|
+
{
|
|
224
|
+
{{pascalCase FEATURE_NAME}}Status.Active => "bg-success",
|
|
225
|
+
{{pascalCase FEATURE_NAME}}Status.Pending => "bg-warning text-dark",
|
|
226
|
+
{{pascalCase FEATURE_NAME}}Status.Completed => "bg-info",
|
|
227
|
+
{{pascalCase FEATURE_NAME}}Status.Failed => "bg-danger",
|
|
228
|
+
_ => "bg-secondary"
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
private class {{pascalCase FEATURE_NAME}}FormModel
|
|
232
|
+
{
|
|
233
|
+
[Required]
|
|
234
|
+
[StringLength(200, MinimumLength = 3)]
|
|
235
|
+
public string Name { get; set; } = string.Empty;
|
|
236
|
+
|
|
237
|
+
// Add more fields as needed
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// MICROSOFT AGENT FRAMEWORK TEMPLATE
|
|
3
|
+
// Generated by MORPH Framework
|
|
4
|
+
// ============================================================
|
|
5
|
+
|
|
6
|
+
using System.ComponentModel;
|
|
7
|
+
using System.Text.Json;
|
|
8
|
+
using Microsoft.Agents.AI;
|
|
9
|
+
using Microsoft.Extensions.AI;
|
|
10
|
+
using Microsoft.Extensions.Logging;
|
|
11
|
+
|
|
12
|
+
namespace {{NAMESPACE}}.Agents.{{pascalCase FEATURE_NAME}};
|
|
13
|
+
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// AI Agent for analyzing {{pascalCase FEATURE_NAME}} data.
|
|
16
|
+
/// Uses Microsoft Agent Framework with IChatClient (gpt-4o-mini by default).
|
|
17
|
+
/// </summary>
|
|
18
|
+
public class {{pascalCase FEATURE_NAME}}AnalyzerAgent(
|
|
19
|
+
IChatClient chatClient,
|
|
20
|
+
ILogger<{{pascalCase FEATURE_NAME}}AnalyzerAgent> logger) : I{{pascalCase FEATURE_NAME}}AnalyzerAgent
|
|
21
|
+
{
|
|
22
|
+
/// <inheritdoc />
|
|
23
|
+
public async Task<{{pascalCase FEATURE_NAME}}AnalysisResult> AnalyzeAsync(
|
|
24
|
+
{{pascalCase FEATURE_NAME}}Data data,
|
|
25
|
+
CancellationToken cancellationToken = default)
|
|
26
|
+
{
|
|
27
|
+
logger.LogInformation("Starting {{pascalCase FEATURE_NAME}} analysis for: {Content}",
|
|
28
|
+
data.Content.Length > 100 ? data.Content[..100] + "..." : data.Content);
|
|
29
|
+
|
|
30
|
+
var agent = new ChatClientAgent(
|
|
31
|
+
chatClient,
|
|
32
|
+
new ChatClientAgentOptions
|
|
33
|
+
{
|
|
34
|
+
Name = "{{pascalCase FEATURE_NAME}}Analyzer",
|
|
35
|
+
Instructions = """
|
|
36
|
+
You are an expert analyst for {{pascalCase FEATURE_NAME}} data.
|
|
37
|
+
|
|
38
|
+
Analyze the provided data and return a JSON object with:
|
|
39
|
+
- summary: Brief summary (1-2 sentences)
|
|
40
|
+
- insights: Array of at least 2 insights
|
|
41
|
+
- recommendations: Array of at least 1 recommendation
|
|
42
|
+
- confidenceScore: Number between 0 and 1
|
|
43
|
+
|
|
44
|
+
Respond ONLY with valid JSON, no additional text.
|
|
45
|
+
""",
|
|
46
|
+
ChatOptions = new ChatOptions
|
|
47
|
+
{
|
|
48
|
+
Tools =
|
|
49
|
+
[
|
|
50
|
+
AIFunctionFactory.Create(GetContextAsync),
|
|
51
|
+
AIFunctionFactory.Create(GetMetricsAsync)
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
var response = await agent.RunAsync(
|
|
57
|
+
$"Analyze this data:\n{data.Content}",
|
|
58
|
+
cancellationToken: cancellationToken);
|
|
59
|
+
|
|
60
|
+
var result = ParseResponse(response.Text);
|
|
61
|
+
|
|
62
|
+
logger.LogInformation(
|
|
63
|
+
"Analysis completed. Confidence: {Confidence:P0}",
|
|
64
|
+
result.ConfidenceScore);
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#region Tools
|
|
70
|
+
|
|
71
|
+
[Description("Gets additional context for the analysis")]
|
|
72
|
+
private async Task<string> GetContextAsync(
|
|
73
|
+
[Description("What context is needed")] string query,
|
|
74
|
+
CancellationToken ct = default)
|
|
75
|
+
{
|
|
76
|
+
// TODO: Implement context retrieval (e.g., from database or search)
|
|
77
|
+
await Task.CompletedTask;
|
|
78
|
+
return $"Context for: {query}";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[Description("Gets relevant metrics for the analysis")]
|
|
82
|
+
private async Task<string> GetMetricsAsync(
|
|
83
|
+
[Description("Metric type to retrieve")] string metricType,
|
|
84
|
+
CancellationToken ct = default)
|
|
85
|
+
{
|
|
86
|
+
// TODO: Implement metrics retrieval
|
|
87
|
+
await Task.CompletedTask;
|
|
88
|
+
return $"Metrics for: {metricType}";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#endregion
|
|
92
|
+
|
|
93
|
+
#region Response Parsing
|
|
94
|
+
|
|
95
|
+
private {{pascalCase FEATURE_NAME}}AnalysisResult ParseResponse(string response)
|
|
96
|
+
{
|
|
97
|
+
try
|
|
98
|
+
{
|
|
99
|
+
var json = response
|
|
100
|
+
.Replace("```json", "")
|
|
101
|
+
.Replace("```", "")
|
|
102
|
+
.Trim();
|
|
103
|
+
|
|
104
|
+
var parsed = JsonSerializer.Deserialize<AnalysisResponse>(json,
|
|
105
|
+
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
106
|
+
|
|
107
|
+
if (parsed is null)
|
|
108
|
+
throw new {{pascalCase FEATURE_NAME}}ProcessingException("Failed to parse analysis response");
|
|
109
|
+
|
|
110
|
+
return new {{pascalCase FEATURE_NAME}}AnalysisResult(
|
|
111
|
+
parsed.Summary ?? "Analysis completed",
|
|
112
|
+
parsed.Insights ?? [],
|
|
113
|
+
parsed.Recommendations ?? [],
|
|
114
|
+
parsed.ConfidenceScore);
|
|
115
|
+
}
|
|
116
|
+
catch (JsonException ex)
|
|
117
|
+
{
|
|
118
|
+
logger.LogError(ex, "Failed to parse AI response: {Response}", response);
|
|
119
|
+
throw new {{pascalCase FEATURE_NAME}}ProcessingException("Failed to parse analysis response", ex);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private class AnalysisResponse
|
|
124
|
+
{
|
|
125
|
+
public string? Summary { get; set; }
|
|
126
|
+
public List<string>? Insights { get; set; }
|
|
127
|
+
public List<string>? Recommendations { get; set; }
|
|
128
|
+
public double ConfidenceScore { get; set; }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#endregion
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ============================================================
|
|
135
|
+
// DEPENDENCY INJECTION SETUP
|
|
136
|
+
// ============================================================
|
|
137
|
+
//
|
|
138
|
+
// In Program.cs:
|
|
139
|
+
//
|
|
140
|
+
// // Register IChatClient (Azure OpenAI with Managed Identity)
|
|
141
|
+
// builder.Services.AddSingleton<IChatClient>(sp =>
|
|
142
|
+
// {
|
|
143
|
+
// var cfg = sp.GetRequiredService<IConfiguration>();
|
|
144
|
+
// return new AzureOpenAIClient(
|
|
145
|
+
// new Uri(cfg["AzureOpenAI:Endpoint"]!),
|
|
146
|
+
// new DefaultAzureCredential())
|
|
147
|
+
// .GetChatClient(cfg["AzureOpenAI:DeploymentName"] ?? "gpt-4o-mini")
|
|
148
|
+
// .AsIChatClient();
|
|
149
|
+
// });
|
|
150
|
+
//
|
|
151
|
+
// // Option A: Register as scoped service
|
|
152
|
+
// builder.Services.AddScoped<I{{pascalCase FEATURE_NAME}}AnalyzerAgent, {{pascalCase FEATURE_NAME}}AnalyzerAgent>();
|
|
153
|
+
//
|
|
154
|
+
// // Option B: Register as keyed agent (recommended for multiple agents)
|
|
155
|
+
// builder.AddAIAgent("{{pascalCase FEATURE_NAME}}Analyzer", (sp, key) =>
|
|
156
|
+
// {
|
|
157
|
+
// var chatClient = sp.GetRequiredService<IChatClient>();
|
|
158
|
+
// return new ChatClientAgent(chatClient,
|
|
159
|
+
// name: key,
|
|
160
|
+
// instructions: "You are an expert {{pascalCase FEATURE_NAME}} analyst.");
|
|
161
|
+
// });
|
|
162
|
+
//
|
|
163
|
+
// ============================================================
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// HANGFIRE JOB TEMPLATE
|
|
3
|
+
// Generated by MORPH Framework
|
|
4
|
+
// ============================================================
|
|
5
|
+
|
|
6
|
+
using Hangfire;
|
|
7
|
+
using Microsoft.Extensions.Logging;
|
|
8
|
+
|
|
9
|
+
namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}}.Jobs;
|
|
10
|
+
|
|
11
|
+
/// <summary>
|
|
12
|
+
/// Background job for processing {{pascalCase FEATURE_NAME}}.
|
|
13
|
+
/// Uses Hangfire for scheduling and retry handling.
|
|
14
|
+
/// </summary>
|
|
15
|
+
public class {{pascalCase FEATURE_NAME}}ProcessorJob(
|
|
16
|
+
I{{pascalCase FEATURE_NAME}}Service service,
|
|
17
|
+
I{{pascalCase FEATURE_NAME}}AnalyzerAgent analyzer,
|
|
18
|
+
ILogger<{{pascalCase FEATURE_NAME}}ProcessorJob> logger) : I{{pascalCase FEATURE_NAME}}ProcessorJob
|
|
19
|
+
{
|
|
20
|
+
/// <summary>
|
|
21
|
+
/// Executes the {{pascalCase FEATURE_NAME}} processing job.
|
|
22
|
+
/// </summary>
|
|
23
|
+
/// <param name="id">The {{pascalCase FEATURE_NAME}} ID to process</param>
|
|
24
|
+
/// <param name="cancellationToken">Cancellation token</param>
|
|
25
|
+
[AutomaticRetry(Attempts = 3, DelaysInSeconds = new[] { 60, 300, 900 })]
|
|
26
|
+
[Queue("default")]
|
|
27
|
+
[JobDisplayName("{{pascalCase FEATURE_NAME}} Processing - ID: {0}")]
|
|
28
|
+
public async Task ExecuteAsync(int id, CancellationToken cancellationToken)
|
|
29
|
+
{
|
|
30
|
+
logger.LogInformation("Starting {{pascalCase FEATURE_NAME}} processing for ID {Id}", id);
|
|
31
|
+
|
|
32
|
+
try
|
|
33
|
+
{
|
|
34
|
+
// Get the entity
|
|
35
|
+
var item = await service.GetByIdAsync(id, cancellationToken);
|
|
36
|
+
if (item is null)
|
|
37
|
+
{
|
|
38
|
+
logger.LogWarning("{{pascalCase FEATURE_NAME}} with ID {Id} not found, skipping", id);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check if already processed
|
|
43
|
+
if (item.Status == {{pascalCase FEATURE_NAME}}Status.Completed)
|
|
44
|
+
{
|
|
45
|
+
logger.LogInformation("{{pascalCase FEATURE_NAME}} {Id} already completed, skipping", id);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Perform analysis (if applicable)
|
|
50
|
+
var analysisData = new {{pascalCase FEATURE_NAME}}Data(item.Name);
|
|
51
|
+
var analysis = await analyzer.AnalyzeAsync(analysisData, cancellationToken);
|
|
52
|
+
|
|
53
|
+
logger.LogInformation(
|
|
54
|
+
"{{pascalCase FEATURE_NAME}} {Id} analyzed. Confidence: {Confidence:P0}",
|
|
55
|
+
id, analysis.ConfidenceScore);
|
|
56
|
+
|
|
57
|
+
// Update status
|
|
58
|
+
// Note: You might need to add a method to update with analysis results
|
|
59
|
+
// await service.CompleteWithAnalysisAsync(id, analysis, cancellationToken);
|
|
60
|
+
|
|
61
|
+
logger.LogInformation("Completed {{pascalCase FEATURE_NAME}} processing for ID {Id}", id);
|
|
62
|
+
}
|
|
63
|
+
catch (Exception ex)
|
|
64
|
+
{
|
|
65
|
+
logger.LogError(ex, "Failed to process {{pascalCase FEATURE_NAME}} {Id}", id);
|
|
66
|
+
throw; // Re-throw to trigger Hangfire retry
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ============================================================
|
|
72
|
+
// RECURRING JOB CONFIGURATION
|
|
73
|
+
// ============================================================
|
|
74
|
+
//
|
|
75
|
+
// For scheduled/recurring jobs, configure in Program.cs:
|
|
76
|
+
//
|
|
77
|
+
// // Run every hour
|
|
78
|
+
// RecurringJob.AddOrUpdate<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
|
|
79
|
+
// "{{kebabCase FEATURE_NAME}}-processor",
|
|
80
|
+
// job => job.ExecuteAsync(0, CancellationToken.None),
|
|
81
|
+
// Cron.Hourly);
|
|
82
|
+
//
|
|
83
|
+
// // Run daily at midnight
|
|
84
|
+
// RecurringJob.AddOrUpdate<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
|
|
85
|
+
// "{{kebabCase FEATURE_NAME}}-daily-processor",
|
|
86
|
+
// job => job.ExecuteAsync(0, CancellationToken.None),
|
|
87
|
+
// Cron.Daily);
|
|
88
|
+
//
|
|
89
|
+
// // Custom cron expression (every 15 minutes)
|
|
90
|
+
// RecurringJob.AddOrUpdate<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
|
|
91
|
+
// "{{kebabCase FEATURE_NAME}}-frequent-processor",
|
|
92
|
+
// job => job.ExecuteAsync(0, CancellationToken.None),
|
|
93
|
+
// "*/15 * * * *");
|
|
94
|
+
//
|
|
95
|
+
// ============================================================
|
|
96
|
+
|
|
97
|
+
// ============================================================
|
|
98
|
+
// BATCH JOB TEMPLATE
|
|
99
|
+
// ============================================================
|
|
100
|
+
|
|
101
|
+
/// <summary>
|
|
102
|
+
/// Batch job for processing multiple {{pascalCase FEATURE_NAME}}s.
|
|
103
|
+
/// </summary>
|
|
104
|
+
public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
|
|
105
|
+
I{{pascalCase FEATURE_NAME}}Service service,
|
|
106
|
+
I{{pascalCase FEATURE_NAME}}ProcessorJob itemProcessor,
|
|
107
|
+
ILogger<{{pascalCase FEATURE_NAME}}BatchProcessorJob> logger)
|
|
108
|
+
{
|
|
109
|
+
/// <summary>
|
|
110
|
+
/// Processes all pending {{pascalCase FEATURE_NAME}}s.
|
|
111
|
+
/// </summary>
|
|
112
|
+
[AutomaticRetry(Attempts = 1)]
|
|
113
|
+
[Queue("batch")]
|
|
114
|
+
[JobDisplayName("{{pascalCase FEATURE_NAME}} Batch Processing")]
|
|
115
|
+
public async Task ProcessAllPendingAsync(CancellationToken cancellationToken)
|
|
116
|
+
{
|
|
117
|
+
logger.LogInformation("Starting batch processing for pending {{pascalCase FEATURE_NAME}}s");
|
|
118
|
+
|
|
119
|
+
var items = await service.GetAllAsync(cancellationToken);
|
|
120
|
+
var pending = items.Where(x => x.Status == {{pascalCase FEATURE_NAME}}Status.Pending).ToList();
|
|
121
|
+
|
|
122
|
+
logger.LogInformation("Found {Count} pending {{pascalCase FEATURE_NAME}}s to process", pending.Count);
|
|
123
|
+
|
|
124
|
+
foreach (var item in pending)
|
|
125
|
+
{
|
|
126
|
+
// Enqueue individual processing jobs
|
|
127
|
+
BackgroundJob.Enqueue<I{{pascalCase FEATURE_NAME}}ProcessorJob>(
|
|
128
|
+
job => job.ExecuteAsync(item.Id, CancellationToken.None));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
logger.LogInformation("Enqueued {Count} processing jobs", pending.Count);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ============================================================
|
|
136
|
+
// HANGFIRE CONFIGURATION
|
|
137
|
+
// ============================================================
|
|
138
|
+
//
|
|
139
|
+
// In Program.cs:
|
|
140
|
+
//
|
|
141
|
+
// // Add Hangfire services
|
|
142
|
+
// builder.Services.AddHangfire(config => config
|
|
143
|
+
// .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
|
|
144
|
+
// .UseSimpleAssemblyNameTypeSerializer()
|
|
145
|
+
// .UseRecommendedSerializerSettings()
|
|
146
|
+
// .UseSqlServerStorage(connectionString, new SqlServerStorageOptions
|
|
147
|
+
// {
|
|
148
|
+
// CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
|
|
149
|
+
// SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
|
|
150
|
+
// QueuePollInterval = TimeSpan.Zero,
|
|
151
|
+
// UseRecommendedIsolationLevel = true,
|
|
152
|
+
// DisableGlobalLocks = true
|
|
153
|
+
// }));
|
|
154
|
+
//
|
|
155
|
+
// builder.Services.AddHangfireServer(options =>
|
|
156
|
+
// {
|
|
157
|
+
// options.Queues = new[] { "default", "batch" };
|
|
158
|
+
// options.WorkerCount = Environment.ProcessorCount * 2;
|
|
159
|
+
// });
|
|
160
|
+
//
|
|
161
|
+
// // Register jobs
|
|
162
|
+
// builder.Services.AddScoped<I{{pascalCase FEATURE_NAME}}ProcessorJob, {{pascalCase FEATURE_NAME}}ProcessorJob>();
|
|
163
|
+
// builder.Services.AddScoped<{{pascalCase FEATURE_NAME}}BatchProcessorJob>();
|
|
164
|
+
//
|
|
165
|
+
// // In app pipeline
|
|
166
|
+
// app.UseHangfireDashboard("/hangfire", new DashboardOptions
|
|
167
|
+
// {
|
|
168
|
+
// Authorization = new[] { new HangfireAuthorizationFilter() }
|
|
169
|
+
// });
|
|
170
|
+
//
|
|
171
|
+
// ============================================================
|