@polymorphism-tech/morph-spec 7.7.3 → 7.8.1
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 +2 -2
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +1 -1
- package/framework/MORPH.md +3 -2
- package/framework/agents.json +1 -1
- package/framework/commands/commit.md +166 -166
- package/framework/commands/morph-infra.md +215 -215
- package/framework/commands/morph-preflight.md +205 -205
- package/framework/commands/morph-troubleshoot.md +124 -124
- package/framework/evals/scenarios/dotnet-crud.yaml +1 -1
- package/framework/hooks/claude-code/statusline.py +679 -679
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/activity-logger.js +160 -160
- package/framework/hooks/shared/hook-response.js +45 -45
- package/framework/hooks/shared/payload-utils.js +78 -78
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/rubrics/backend.json +41 -41
- package/framework/rules/ai-agents-standards.md +45 -45
- package/framework/rules/dotnet-templates.md +86 -87
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/infrastructure-standards.md +27 -27
- package/framework/rules/neon-standards.md +25 -25
- package/framework/rules/nextjs-standards.md +20 -20
- package/framework/rules/nextjs-templates.md +40 -40
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +1 -1
- package/framework/skills/core/morph-brainstorming/SKILL.md +9 -5
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-implement/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +11 -6
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +13 -7
- package/framework/skills/core/morph-stack-scan/SKILL.md +5 -5
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/standards/STANDARDS.json +1 -1
- package/framework/standards/ai-agents/agent-session.md +160 -160
- package/framework/standards/ai-agents/batching.md +193 -193
- package/framework/standards/ai-agents/context-providers.md +188 -188
- package/framework/standards/ai-agents/mcp-server.md +250 -250
- package/framework/standards/ai-agents/mcp-tools.md +197 -197
- package/framework/standards/ai-agents/middleware-patterns.md +207 -207
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
- package/framework/standards/ai-agents/modalities-vision.md +201 -201
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
- package/framework/standards/ai-agents/production.md +275 -275
- package/framework/standards/ai-agents/prompts-in-db.md +214 -214
- package/framework/standards/ai-agents/providers/model-registry.md +158 -158
- package/framework/standards/ai-agents/service-tier-flex.md +135 -135
- package/framework/standards/ai-agents/structured-output.md +249 -249
- package/framework/standards/ai-agents/sweet-spot.md +109 -109
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +34 -35
- package/framework/standards/backend/api/validation.md +2 -2
- package/framework/standards/backend/dotnet/scrutor.md +1 -3
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +42 -37
- package/framework/standards/data/nosql/cache/redis.md +2 -2
- package/framework/templates/CLAUDE.md.core.template +1 -1
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/README.md +0 -1
- package/framework/templates/REGISTRY.json +0 -21
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/abstractions/handler.cs +0 -3
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/constants/api-tags.cs +1 -1
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -282
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/handler.cs.hbs +23 -24
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/dotnet/jobs/job.cs +15 -15
- package/framework/templates/code/dotnet/test.cs +72 -101
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +113 -113
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +1 -1
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/index.js +13 -13
- package/src/commands/mcp/mcp-setup.js +519 -519
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/update.js +7 -4
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/HookInspector.jsx +418 -418
- package/src/dashboard/app/pages/LiveState.jsx +239 -239
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/hooks-scanner.js +41 -41
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/scanner/standards-scanner.js +26 -26
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/metrics-aggregator.js +56 -56
- package/src/lib/agents/metrics-calculator.js +125 -125
- package/src/lib/agents/output-collector.js +73 -73
- package/src/lib/detectors/claude-config-detector.js +152 -152
- package/src/lib/detectors/design-system-detector.js +231 -231
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/generators/architecture-scanner.js +639 -639
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/index.js +13 -13
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/test-runner.js +81 -81
- package/src/lib/validators/architecture/architecture-validator.js +259 -259
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/packages/package-validator.js +347 -347
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/validation-runner.js +349 -349
- package/src/scripts/setup-infra.js +383 -383
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/banner.js +52 -43
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/skills-installer.js +172 -172
- package/framework/templates/.idea/morph-templates.xml +0 -92
- package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
- package/framework/templates/code/dotnet/backend/repository.cs +0 -141
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// EF CORE MIGRATION TEMPLATE
|
|
3
|
-
// Generated by MORPH Framework
|
|
4
|
-
// ============================================================
|
|
5
|
-
|
|
6
|
-
using Microsoft.EntityFrameworkCore.Migrations;
|
|
7
|
-
|
|
8
|
-
#nullable disable
|
|
9
|
-
|
|
10
|
-
namespace {{NAMESPACE}}.Infrastructure.Data.Migrations;
|
|
11
|
-
|
|
12
|
-
/// <inheritdoc />
|
|
13
|
-
public partial class Add{{pascalCase FEATURE_NAME}} : Migration
|
|
14
|
-
{
|
|
15
|
-
/// <inheritdoc />
|
|
16
|
-
protected override void Up(MigrationBuilder migrationBuilder)
|
|
17
|
-
{
|
|
18
|
-
migrationBuilder.CreateTable(
|
|
19
|
-
name: "{{pascalCase FEATURE_NAME}}s",
|
|
20
|
-
columns: table => new
|
|
21
|
-
{
|
|
22
|
-
Id = table.Column<int>(type: "int", nullable: false)
|
|
23
|
-
.Annotation("SqlServer:Identity", "1, 1"),
|
|
24
|
-
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
|
25
|
-
Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
|
26
|
-
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false,
|
|
27
|
-
defaultValueSql: "GETUTCDATE()"),
|
|
28
|
-
UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
|
|
29
|
-
},
|
|
30
|
-
constraints: table =>
|
|
31
|
-
{
|
|
32
|
-
table.PrimaryKey("PK_{{pascalCase FEATURE_NAME}}s", x => x.Id);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Indexes
|
|
36
|
-
migrationBuilder.CreateIndex(
|
|
37
|
-
name: "IX_{{pascalCase FEATURE_NAME}}s_Name",
|
|
38
|
-
table: "{{pascalCase FEATURE_NAME}}s",
|
|
39
|
-
column: "Name");
|
|
40
|
-
|
|
41
|
-
migrationBuilder.CreateIndex(
|
|
42
|
-
name: "IX_{{pascalCase FEATURE_NAME}}s_Status",
|
|
43
|
-
table: "{{pascalCase FEATURE_NAME}}s",
|
|
44
|
-
column: "Status");
|
|
45
|
-
|
|
46
|
-
migrationBuilder.CreateIndex(
|
|
47
|
-
name: "IX_{{pascalCase FEATURE_NAME}}s_CreatedAt",
|
|
48
|
-
table: "{{pascalCase FEATURE_NAME}}s",
|
|
49
|
-
column: "CreatedAt");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/// <inheritdoc />
|
|
53
|
-
protected override void Down(MigrationBuilder migrationBuilder)
|
|
54
|
-
{
|
|
55
|
-
migrationBuilder.DropTable(
|
|
56
|
-
name: "{{pascalCase FEATURE_NAME}}s");
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ============================================================
|
|
61
|
-
// HOW TO CREATE A MIGRATION
|
|
62
|
-
// ============================================================
|
|
63
|
-
//
|
|
64
|
-
// 1. Add your entity to AppDbContext:
|
|
65
|
-
//
|
|
66
|
-
// public DbSet<{{pascalCase FEATURE_NAME}}> {{pascalCase FEATURE_NAME}}s => Set<{{pascalCase FEATURE_NAME}}>();
|
|
67
|
-
//
|
|
68
|
-
// 2. Add your configuration:
|
|
69
|
-
//
|
|
70
|
-
// protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
71
|
-
// {
|
|
72
|
-
// modelBuilder.ApplyConfiguration(new {{pascalCase FEATURE_NAME}}Configuration());
|
|
73
|
-
// }
|
|
74
|
-
//
|
|
75
|
-
// 3. Run migration command:
|
|
76
|
-
//
|
|
77
|
-
// dotnet ef migrations add Add{{pascalCase FEATURE_NAME}} -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
|
|
78
|
-
//
|
|
79
|
-
// 4. Apply migration:
|
|
80
|
-
//
|
|
81
|
-
// dotnet ef database update -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
|
|
82
|
-
//
|
|
83
|
-
// ============================================================
|
|
1
|
+
// ============================================================
|
|
2
|
+
// EF CORE MIGRATION TEMPLATE
|
|
3
|
+
// Generated by MORPH Framework
|
|
4
|
+
// ============================================================
|
|
5
|
+
|
|
6
|
+
using Microsoft.EntityFrameworkCore.Migrations;
|
|
7
|
+
|
|
8
|
+
#nullable disable
|
|
9
|
+
|
|
10
|
+
namespace {{NAMESPACE}}.Infrastructure.Data.Migrations;
|
|
11
|
+
|
|
12
|
+
/// <inheritdoc />
|
|
13
|
+
public partial class Add{{pascalCase FEATURE_NAME}} : Migration
|
|
14
|
+
{
|
|
15
|
+
/// <inheritdoc />
|
|
16
|
+
protected override void Up(MigrationBuilder migrationBuilder)
|
|
17
|
+
{
|
|
18
|
+
migrationBuilder.CreateTable(
|
|
19
|
+
name: "{{pascalCase FEATURE_NAME}}s",
|
|
20
|
+
columns: table => new
|
|
21
|
+
{
|
|
22
|
+
Id = table.Column<int>(type: "int", nullable: false)
|
|
23
|
+
.Annotation("SqlServer:Identity", "1, 1"),
|
|
24
|
+
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
|
25
|
+
Status = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
|
26
|
+
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false,
|
|
27
|
+
defaultValueSql: "GETUTCDATE()"),
|
|
28
|
+
UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
|
|
29
|
+
},
|
|
30
|
+
constraints: table =>
|
|
31
|
+
{
|
|
32
|
+
table.PrimaryKey("PK_{{pascalCase FEATURE_NAME}}s", x => x.Id);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Indexes
|
|
36
|
+
migrationBuilder.CreateIndex(
|
|
37
|
+
name: "IX_{{pascalCase FEATURE_NAME}}s_Name",
|
|
38
|
+
table: "{{pascalCase FEATURE_NAME}}s",
|
|
39
|
+
column: "Name");
|
|
40
|
+
|
|
41
|
+
migrationBuilder.CreateIndex(
|
|
42
|
+
name: "IX_{{pascalCase FEATURE_NAME}}s_Status",
|
|
43
|
+
table: "{{pascalCase FEATURE_NAME}}s",
|
|
44
|
+
column: "Status");
|
|
45
|
+
|
|
46
|
+
migrationBuilder.CreateIndex(
|
|
47
|
+
name: "IX_{{pascalCase FEATURE_NAME}}s_CreatedAt",
|
|
48
|
+
table: "{{pascalCase FEATURE_NAME}}s",
|
|
49
|
+
column: "CreatedAt");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// <inheritdoc />
|
|
53
|
+
protected override void Down(MigrationBuilder migrationBuilder)
|
|
54
|
+
{
|
|
55
|
+
migrationBuilder.DropTable(
|
|
56
|
+
name: "{{pascalCase FEATURE_NAME}}s");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ============================================================
|
|
61
|
+
// HOW TO CREATE A MIGRATION
|
|
62
|
+
// ============================================================
|
|
63
|
+
//
|
|
64
|
+
// 1. Add your entity to AppDbContext:
|
|
65
|
+
//
|
|
66
|
+
// public DbSet<{{pascalCase FEATURE_NAME}}> {{pascalCase FEATURE_NAME}}s => Set<{{pascalCase FEATURE_NAME}}>();
|
|
67
|
+
//
|
|
68
|
+
// 2. Add your configuration:
|
|
69
|
+
//
|
|
70
|
+
// protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
71
|
+
// {
|
|
72
|
+
// modelBuilder.ApplyConfiguration(new {{pascalCase FEATURE_NAME}}Configuration());
|
|
73
|
+
// }
|
|
74
|
+
//
|
|
75
|
+
// 3. Run migration command:
|
|
76
|
+
//
|
|
77
|
+
// dotnet ef migrations add Add{{pascalCase FEATURE_NAME}} -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
|
|
78
|
+
//
|
|
79
|
+
// 4. Apply migration:
|
|
80
|
+
//
|
|
81
|
+
// dotnet ef database update -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
|
|
82
|
+
//
|
|
83
|
+
// ============================================================
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
using {{pascalCase PROJECT_NAME}}.Abstractions;
|
|
2
|
-
using {{pascalCase PROJECT_NAME}}.Constants;
|
|
3
|
-
using {{pascalCase PROJECT_NAME}}.Extensions;
|
|
4
|
-
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
5
|
-
|
|
6
|
-
internal sealed class {{pascalCase SLICE_NAME}}Endpoint : IApiEndpoint
|
|
7
|
-
{
|
|
8
|
-
public void MapEndpoint(IEndpointRouteBuilder app)
|
|
9
|
-
{
|
|
10
|
-
app.MapPost("{{kebabCase FEATURE_NAME}}s", async (IHandler<{{pascalCase SLICE_NAME}}Request, Result<{{pascalCase SLICE_NAME}}Response>> handler, {{pascalCase SLICE_NAME}}Request command, CancellationToken cancellationToken) =>
|
|
11
|
-
{
|
|
12
|
-
var result = await handler.HandleAsync(command, cancellationToken);
|
|
13
|
-
return result.Match(
|
|
14
|
-
onSuccess: () => Results.Ok(result.Value),
|
|
15
|
-
onFailure: error => Results.BadRequest(error));
|
|
16
|
-
})
|
|
17
|
-
.WithTags(ApiTags.{{pascalCase FEATURE_NAME}}s)
|
|
18
|
-
.Produces<{{pascalCase SLICE_NAME}}Response>(StatusCodes.Status200OK)
|
|
19
|
-
.Produces(StatusCodes.Status400BadRequest);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
1
|
+
using {{pascalCase PROJECT_NAME}}.Abstractions;
|
|
2
|
+
using {{pascalCase PROJECT_NAME}}.Constants;
|
|
3
|
+
using {{pascalCase PROJECT_NAME}}.Extensions;
|
|
4
|
+
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
5
|
+
|
|
6
|
+
internal sealed class {{pascalCase SLICE_NAME}}Endpoint : IApiEndpoint
|
|
7
|
+
{
|
|
8
|
+
public void MapEndpoint(IEndpointRouteBuilder app)
|
|
9
|
+
{
|
|
10
|
+
app.MapPost("{{kebabCase FEATURE_NAME}}s", async (IHandler<{{pascalCase SLICE_NAME}}Request, Result<{{pascalCase SLICE_NAME}}Response>> handler, {{pascalCase SLICE_NAME}}Request command, CancellationToken cancellationToken) =>
|
|
11
|
+
{
|
|
12
|
+
var result = await handler.HandleAsync(command, cancellationToken);
|
|
13
|
+
return result.Match(
|
|
14
|
+
onSuccess: () => Results.Ok(result.Value),
|
|
15
|
+
onFailure: error => Results.BadRequest(error));
|
|
16
|
+
})
|
|
17
|
+
.WithTags(ApiTags.{{pascalCase FEATURE_NAME}}s)
|
|
18
|
+
.Produces<{{pascalCase SLICE_NAME}}Response>(StatusCodes.Status200OK)
|
|
19
|
+
.Produces(StatusCodes.Status400BadRequest);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
2
|
-
|
|
3
|
-
using {{pascalCase PROJECT_NAME}}.Abstractions;
|
|
4
|
-
using {{pascalCase PROJECT_NAME}}.
|
|
5
|
-
using {{pascalCase PROJECT_NAME}}.
|
|
6
|
-
|
|
7
|
-
public sealed class {{pascalCase SLICE_NAME}}Handler(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
await
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
1
|
+
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
2
|
+
|
|
3
|
+
using {{pascalCase PROJECT_NAME}}.Abstractions;
|
|
4
|
+
using {{pascalCase PROJECT_NAME}}.Database;
|
|
5
|
+
using {{pascalCase PROJECT_NAME}}.Entities;
|
|
6
|
+
|
|
7
|
+
public sealed class {{pascalCase SLICE_NAME}}Handler(
|
|
8
|
+
ApplicationDbContext _db) : IHandler<{{pascalCase SLICE_NAME}}Request, Result<{{pascalCase SLICE_NAME}}Response>>
|
|
9
|
+
{
|
|
10
|
+
public async Task<Result<{{pascalCase SLICE_NAME}}Response>> HandleAsync({{pascalCase SLICE_NAME}}Request command, CancellationToken cancellationToken)
|
|
11
|
+
{
|
|
12
|
+
var entity = new {{pascalCase FEATURE_NAME}}
|
|
13
|
+
{
|
|
14
|
+
Id = Guid.CreateVersion7(),
|
|
15
|
+
// TODO: Map command properties to entity
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
19
|
+
await _db.SaveChangesAsync(cancellationToken);
|
|
20
|
+
|
|
21
|
+
return Result.Success(new {{pascalCase SLICE_NAME}}Response(entity.Id));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
2
|
-
|
|
3
|
-
// TODO: Add properties matching the {{pascalCase SLICE_NAME}} command
|
|
4
|
-
public sealed record {{pascalCase SLICE_NAME}}Request();
|
|
1
|
+
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
2
|
+
|
|
3
|
+
// TODO: Add properties matching the {{pascalCase SLICE_NAME}} command
|
|
4
|
+
public sealed record {{pascalCase SLICE_NAME}}Request();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
2
|
-
|
|
3
|
-
// TODO: Add properties matching the {{pascalCase SLICE_NAME}} response
|
|
4
|
-
public sealed record {{pascalCase SLICE_NAME}}Response(Guid Id);
|
|
1
|
+
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
2
|
+
|
|
3
|
+
// TODO: Add properties matching the {{pascalCase SLICE_NAME}} response
|
|
4
|
+
public sealed record {{pascalCase SLICE_NAME}}Response(Guid Id);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
using FluentValidation;
|
|
2
|
-
|
|
3
|
-
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
4
|
-
|
|
5
|
-
public class {{pascalCase SLICE_NAME}}Validator : AbstractValidator<{{pascalCase SLICE_NAME}}Request>
|
|
6
|
-
{
|
|
7
|
-
public {{pascalCase SLICE_NAME}}Validator()
|
|
8
|
-
{
|
|
9
|
-
// TODO: Add validation rules for {{pascalCase SLICE_NAME}}Request properties
|
|
10
|
-
// Example:
|
|
11
|
-
// RuleFor(c => c.Name)
|
|
12
|
-
// .NotEmpty().WithMessage("Name is required")
|
|
13
|
-
// .MaximumLength(200).WithMessage("Name must not exceed 200 characters");
|
|
14
|
-
}
|
|
15
|
-
}
|
|
1
|
+
using FluentValidation;
|
|
2
|
+
|
|
3
|
+
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Feature.{{pascalCase SLICE_NAME}};
|
|
4
|
+
|
|
5
|
+
public class {{pascalCase SLICE_NAME}}Validator : AbstractValidator<{{pascalCase SLICE_NAME}}Request>
|
|
6
|
+
{
|
|
7
|
+
public {{pascalCase SLICE_NAME}}Validator()
|
|
8
|
+
{
|
|
9
|
+
// TODO: Add validation rules for {{pascalCase SLICE_NAME}}Request properties
|
|
10
|
+
// Example:
|
|
11
|
+
// RuleFor(c => c.Name)
|
|
12
|
+
// .NotEmpty().WithMessage("Name is required")
|
|
13
|
+
// .MaximumLength(200).WithMessage("Name must not exceed 200 characters");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// ============================================================
|
|
2
|
-
// HANGFIRE JOB TEMPLATE (VSA Pattern —
|
|
2
|
+
// HANGFIRE JOB TEMPLATE (VSA Pattern — ApplicationDbContext direto)
|
|
3
3
|
// Generated by MORPH Framework
|
|
4
4
|
// ============================================================
|
|
5
5
|
|
|
6
6
|
using Hangfire;
|
|
7
|
+
using Microsoft.EntityFrameworkCore;
|
|
7
8
|
using Microsoft.Extensions.Logging;
|
|
8
|
-
using {{pascalCase PROJECT_NAME}}.
|
|
9
|
+
using {{pascalCase PROJECT_NAME}}.Database;
|
|
9
10
|
|
|
10
11
|
namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}.Jobs;
|
|
11
12
|
|
|
12
13
|
/// <summary>
|
|
13
14
|
/// Background job for processing {{pascalCase FEATURE_NAME}}.
|
|
14
15
|
/// Uses Hangfire for scheduling and retry handling.
|
|
15
|
-
/// Injects
|
|
16
|
+
/// Injects ApplicationDbContext directly (no service layer, no generic repository).
|
|
16
17
|
/// </summary>
|
|
17
18
|
public class {{pascalCase FEATURE_NAME}}ProcessorJob(
|
|
18
|
-
|
|
19
|
-
IUnitOfWork unitOfWork,
|
|
19
|
+
ApplicationDbContext db,
|
|
20
20
|
I{{pascalCase FEATURE_NAME}}AnalyzerAgent analyzer,
|
|
21
21
|
ILogger<{{pascalCase FEATURE_NAME}}ProcessorJob> logger) : I{{pascalCase FEATURE_NAME}}ProcessorJob
|
|
22
22
|
{
|
|
@@ -34,8 +34,8 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
|
|
|
34
34
|
|
|
35
35
|
try
|
|
36
36
|
{
|
|
37
|
-
// Get the entity directly from the
|
|
38
|
-
var entity = await
|
|
37
|
+
// Get the entity directly from the DbSet
|
|
38
|
+
var entity = await db.Set<{{pascalCase FEATURE_NAME}}>().FindAsync(new object[] { id }, cancellationToken);
|
|
39
39
|
if (entity is null)
|
|
40
40
|
{
|
|
41
41
|
logger.LogWarning("{{pascalCase FEATURE_NAME}} with ID {Id} not found, skipping", id);
|
|
@@ -57,10 +57,9 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
|
|
|
57
57
|
"{{pascalCase FEATURE_NAME}} {Id} analyzed. Confidence: {Confidence:P0}",
|
|
58
58
|
id, analysis.ConfidenceScore);
|
|
59
59
|
|
|
60
|
-
// Update entity
|
|
60
|
+
// Update the tracked entity and persist
|
|
61
61
|
entity.MarkAsCompleted(analysis);
|
|
62
|
-
await
|
|
63
|
-
await unitOfWork.CommitAsync(cancellationToken);
|
|
62
|
+
await db.SaveChangesAsync(cancellationToken);
|
|
64
63
|
|
|
65
64
|
logger.LogInformation("Completed {{pascalCase FEATURE_NAME}} processing for ID {Id}", id);
|
|
66
65
|
}
|
|
@@ -104,10 +103,10 @@ public class {{pascalCase FEATURE_NAME}}ProcessorJob(
|
|
|
104
103
|
|
|
105
104
|
/// <summary>
|
|
106
105
|
/// Batch job for processing multiple {{pascalCase FEATURE_NAME}}s.
|
|
107
|
-
/// Queries pending items via
|
|
106
|
+
/// Queries pending items via LINQ on the DbSet and enqueues individual jobs.
|
|
108
107
|
/// </summary>
|
|
109
108
|
public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
|
|
110
|
-
|
|
109
|
+
ApplicationDbContext db,
|
|
111
110
|
ILogger<{{pascalCase FEATURE_NAME}}BatchProcessorJob> logger)
|
|
112
111
|
{
|
|
113
112
|
/// <summary>
|
|
@@ -120,8 +119,9 @@ public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
|
|
|
120
119
|
{
|
|
121
120
|
logger.LogInformation("Starting batch processing for pending {{pascalCase FEATURE_NAME}}s");
|
|
122
121
|
|
|
123
|
-
var
|
|
124
|
-
|
|
122
|
+
var pending = await db.Set<{{pascalCase FEATURE_NAME}}>()
|
|
123
|
+
.Where(x => x.Status == {{pascalCase FEATURE_NAME}}Status.Pending)
|
|
124
|
+
.ToListAsync(cancellationToken);
|
|
125
125
|
|
|
126
126
|
logger.LogInformation("Found {Count} pending {{pascalCase FEATURE_NAME}}s to process", pending.Count);
|
|
127
127
|
|
|
@@ -162,7 +162,7 @@ public class {{pascalCase FEATURE_NAME}}BatchProcessorJob(
|
|
|
162
162
|
// options.WorkerCount = Environment.ProcessorCount * 2;
|
|
163
163
|
// });
|
|
164
164
|
//
|
|
165
|
-
// // Register jobs (
|
|
165
|
+
// // Register jobs (ApplicationDbContext already registered via AddDbContext)
|
|
166
166
|
// builder.Services.AddScoped<I{{pascalCase FEATURE_NAME}}ProcessorJob, {{pascalCase FEATURE_NAME}}ProcessorJob>();
|
|
167
167
|
// builder.Services.AddScoped<{{pascalCase FEATURE_NAME}}BatchProcessorJob>();
|
|
168
168
|
//
|