@polymorphism-tech/morph-spec 4.10.9 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +3 -3
- package/LICENSE +71 -71
- package/README.md +5 -11
- package/bin/morph-spec.js +23 -1
- package/bin/task-manager.js +5 -5
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +2 -8
- package/framework/agents/README.md +14 -14
- package/framework/agents/architecture/standards-architect.md +159 -159
- package/framework/agents/frontend/css-specialist.md +1 -1
- package/framework/agents/infrastructure/azure-architect.md +149 -149
- package/framework/agents/infrastructure/azure-deploy-specialist.md +4 -4
- package/framework/agents/infrastructure/infra-architect.md +48 -48
- package/framework/commands/morph-apply.md +18 -18
- package/framework/commands/morph-preflight.md +3 -3
- package/framework/commands/morph-proposal.md +15 -15
- package/framework/commands/morph-status.md +3 -3
- package/framework/commands/morph-troubleshoot.md +1 -1
- package/framework/hooks/README.md +204 -204
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +2 -2
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +1 -1
- package/framework/hooks/claude-code/teammate-idle/teammate-idle.js +3 -3
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +2 -2
- package/framework/hooks/git/pre-commit/agents.sh +1 -1
- package/framework/hooks/shared/phase-utils.js +139 -139
- package/framework/rules/csharp-standards.md +13 -13
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/infrastructure-standards.md +16 -16
- package/framework/rules/testing-standards.md +14 -14
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +8 -8
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +3 -3
- package/framework/skills/level-0-meta/morph-code-review-nextjs/references/review-example-nextjs.md +254 -254
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +11 -11
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +3 -3
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +1 -1
- package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +4 -4
- package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +25 -25
- package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +8 -8
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +7 -7
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +4 -4
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +23 -23
- package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +38 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +29 -29
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -4
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +9 -9
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +17 -17
- package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +14 -0
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +12 -12
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +16 -16
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +5 -5
- package/framework/standards/STANDARDS.json +2338 -2041
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -17
- package/framework/standards/infrastructure/supabase/supabase-custom-jwt.md +206 -0
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/README.md +814 -814
- package/framework/templates/code/dotnet/contracts/Commands.cs +74 -74
- package/framework/templates/code/dotnet/contracts/Entities.cs +25 -25
- package/framework/templates/code/dotnet/contracts/Queries.cs +74 -74
- package/framework/templates/code/dotnet/contracts/README.md +74 -74
- package/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -173
- package/framework/templates/code/dotnet/frontend/component.razor +239 -239
- package/framework/templates/code/dotnet/jobs/agent.cs +163 -163
- package/framework/templates/code/dotnet/jobs/job.cs +171 -171
- package/framework/templates/code/dotnet/test.cs +239 -239
- package/framework/templates/code/sql/rls-policy.sql +57 -57
- package/framework/templates/code/sql/supabase-migration.sql +100 -100
- package/framework/templates/code/sql/supabase-migration.template.sql +113 -113
- package/framework/templates/code/typescript/contracts.ts +168 -168
- package/framework/templates/context/CONTEXT.md +181 -181
- package/framework/templates/docs/proposal.md +182 -182
- package/framework/templates/docs/user-stories.md +34 -34
- package/framework/templates/examples/design-system-examples.md +357 -357
- package/framework/templates/examples/spec-examples.md +90 -90
- package/framework/templates/feature/decisions.md +187 -187
- package/framework/templates/feature/recap.md +146 -146
- package/framework/templates/feature/tasks.md +199 -199
- package/framework/templates/infrastructure/azure/README.md +286 -286
- package/framework/templates/infrastructure/azure/deploy-checklist.md +426 -426
- package/framework/templates/infrastructure/azure/parameters.dev.json +29 -29
- package/framework/templates/infrastructure/azure/parameters.prod.json +29 -29
- package/framework/templates/infrastructure/azure/parameters.staging.json +29 -29
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -67
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/docker/easypanel.template.json +54 -54
- package/framework/workflows/README.md +18 -18
- package/framework/workflows/docs/enforcement-pipeline.md +1 -1
- package/framework/workflows/docs/full-morph.md +2 -2
- package/package.json +1 -1
- package/src/commands/agents/dispatch-agents.js +17 -0
- package/src/commands/agents/index.js +13 -13
- package/src/commands/agents/project-metrics.js +74 -0
- package/src/commands/project/doctor.js +3 -4
- package/src/commands/project/install-plugin-cmd.js +28 -28
- package/src/commands/project/setup-infra-cmd.js +12 -12
- package/src/commands/project/status.js +8 -1
- package/src/commands/scope/escalate.js +5 -3
- package/src/commands/standards/context-budget.js +89 -0
- package/src/commands/tasks/index.js +4 -4
- package/src/commands/templates/index.js +5 -5
- package/src/commands/utils/index.js +3 -3
- package/src/commands/validation/index.js +4 -4
- package/src/commands/validation/validate-feature.js +32 -3
- package/src/core/state/phase-state-machine.js +217 -217
- package/src/lib/agents/metrics-aggregator.js +56 -0
- package/src/lib/generators/design-system-generator.js +298 -298
- package/src/lib/generators/index.js +10 -10
- package/src/lib/generators/metadata-extractor.js +387 -387
- package/src/lib/stack-filter.js +65 -65
- package/src/lib/standards/digest-builder.js +57 -3
- package/src/lib/standards/index.js +7 -7
- package/src/lib/standards/standards-context-injector.js +302 -302
- package/src/lib/validators/architecture/architecture-validator.js +387 -387
- package/src/lib/validators/architecture/index.js +7 -7
- package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +316 -316
- package/src/lib/validators/blazor/blazor-state-validator.js +279 -279
- package/src/lib/validators/blazor/blazor-validator.js +369 -369
- package/src/lib/validators/blazor/index.js +9 -9
- package/src/lib/validators/content/content-validator.js +287 -287
- package/src/lib/validators/content/index.js +7 -7
- package/src/lib/validators/contracts/index.js +7 -7
- package/src/lib/validators/css/css-validator.js +352 -352
- package/src/lib/validators/css/index.js +7 -7
- package/src/lib/validators/design-system/design-system-validator.js +231 -231
- package/src/lib/validators/design-system/index.js +7 -7
- package/src/lib/validators/nextjs/index.js +6 -6
- package/src/lib/validators/nextjs/next-component-validator.js +183 -183
- package/src/lib/validators/packages/index.js +7 -7
- package/src/lib/validators/packages/package-validator.js +360 -360
- package/src/lib/validators/shared/index.js +12 -12
- package/src/lib/validators/shared/issue-counter.js +18 -18
- package/src/lib/validators/shared/result-formatter.js +124 -124
- package/src/lib/validators/ui/index.js +7 -7
- package/src/lib/validators/ui/ui-contrast-validator.js +422 -422
- package/src/scripts/global-install.js +112 -58
- package/src/scripts/install-plugin.js +126 -126
- package/src/utils/claude-md-injector.js +90 -90
- package/src/utils/file-copier.js +200 -200
- package/src/utils/logger.js +32 -32
- package/src/utils/skills-installer.js +178 -178
- package/src/utils/version-checker.js +169 -175
|
@@ -1,173 +1,173 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// CONTRACTS: {{titleCase FEATURE_NAME}}
|
|
3
|
-
// Stack: Next.js + Supabase + .NET API
|
|
4
|
-
// Generated by MORPH Framework
|
|
5
|
-
// Date: {{DATE}}
|
|
6
|
-
// ============================================================
|
|
7
|
-
|
|
8
|
-
#region Usings
|
|
9
|
-
|
|
10
|
-
using System;
|
|
11
|
-
using System.Collections.Generic;
|
|
12
|
-
using System.Threading;
|
|
13
|
-
using System.Threading.Tasks;
|
|
14
|
-
|
|
15
|
-
#endregion
|
|
16
|
-
|
|
17
|
-
namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}};
|
|
18
|
-
|
|
19
|
-
#region Configuration
|
|
20
|
-
|
|
21
|
-
/// <summary>
|
|
22
|
-
/// Supabase configuration options.
|
|
23
|
-
/// Bind from appsettings.json "Supabase" section.
|
|
24
|
-
/// </summary>
|
|
25
|
-
public sealed record SupabaseConfig
|
|
26
|
-
{
|
|
27
|
-
public required string Url { get; init; }
|
|
28
|
-
public required string AnonKey { get; init; }
|
|
29
|
-
public required string ServiceRoleKey { get; init; }
|
|
30
|
-
public required string JwtSecret { get; init; }
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#endregion
|
|
34
|
-
|
|
35
|
-
#region Pagination
|
|
36
|
-
|
|
37
|
-
/// <summary>
|
|
38
|
-
/// Pagination query parameters. Use with [AsParameters] in Minimal API.
|
|
39
|
-
/// </summary>
|
|
40
|
-
public sealed record PaginationQuery(
|
|
41
|
-
int Page = 1,
|
|
42
|
-
int PageSize = 20)
|
|
43
|
-
{
|
|
44
|
-
public int Offset => (Page - 1) * PageSize;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/// <summary>
|
|
48
|
-
/// Paginated result wrapper.
|
|
49
|
-
/// </summary>
|
|
50
|
-
public sealed record PagedResult<T>(
|
|
51
|
-
List<T> Items,
|
|
52
|
-
int TotalCount,
|
|
53
|
-
int Page,
|
|
54
|
-
int PageSize)
|
|
55
|
-
{
|
|
56
|
-
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
|
|
57
|
-
public bool HasNext => Page < TotalPages;
|
|
58
|
-
public bool HasPrevious => Page > 1;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#endregion
|
|
62
|
-
|
|
63
|
-
#region Repository Interfaces
|
|
64
|
-
|
|
65
|
-
/// <summary>
|
|
66
|
-
/// Generic repository interface for Supabase/PostgreSQL data access via Dapper.
|
|
67
|
-
/// </summary>
|
|
68
|
-
public interface IRepository<T, TId>
|
|
69
|
-
{
|
|
70
|
-
Task<T?> GetByIdAsync(TId id, CancellationToken cancellationToken = default);
|
|
71
|
-
Task<List<T>> GetAllAsync(CancellationToken cancellationToken = default);
|
|
72
|
-
Task<PagedResult<T>> GetPagedAsync(PaginationQuery query, CancellationToken cancellationToken = default);
|
|
73
|
-
Task<TId> CreateAsync(T entity, CancellationToken cancellationToken = default);
|
|
74
|
-
Task UpdateAsync(T entity, CancellationToken cancellationToken = default);
|
|
75
|
-
Task DeleteAsync(TId id, CancellationToken cancellationToken = default);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
#endregion
|
|
79
|
-
|
|
80
|
-
#region Service Interfaces
|
|
81
|
-
|
|
82
|
-
/// <summary>
|
|
83
|
-
/// Service for managing {{pascalCase FEATURE_NAME}} operations.
|
|
84
|
-
/// </summary>
|
|
85
|
-
public interface I{{pascalCase FEATURE_NAME}}Service
|
|
86
|
-
{
|
|
87
|
-
/// <summary>
|
|
88
|
-
/// Gets a {{pascalCase FEATURE_NAME}} by its identifier.
|
|
89
|
-
/// </summary>
|
|
90
|
-
Task<{{pascalCase FEATURE_NAME}}Dto?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);
|
|
91
|
-
|
|
92
|
-
/// <summary>
|
|
93
|
-
/// Gets paginated list of {{pascalCase FEATURE_NAME}} items.
|
|
94
|
-
/// </summary>
|
|
95
|
-
Task<PagedResult<{{pascalCase FEATURE_NAME}}Dto>> GetPagedAsync(PaginationQuery query, Guid userId, CancellationToken cancellationToken = default);
|
|
96
|
-
|
|
97
|
-
/// <summary>
|
|
98
|
-
/// Creates a new {{pascalCase FEATURE_NAME}}.
|
|
99
|
-
/// </summary>
|
|
100
|
-
Task<{{pascalCase FEATURE_NAME}}Dto> CreateAsync(Create{{pascalCase FEATURE_NAME}}Request request, Guid userId, CancellationToken cancellationToken = default);
|
|
101
|
-
|
|
102
|
-
/// <summary>
|
|
103
|
-
/// Updates an existing {{pascalCase FEATURE_NAME}}.
|
|
104
|
-
/// </summary>
|
|
105
|
-
Task UpdateAsync(Guid id, Update{{pascalCase FEATURE_NAME}}Request request, Guid userId, CancellationToken cancellationToken = default);
|
|
106
|
-
|
|
107
|
-
/// <summary>
|
|
108
|
-
/// Deletes a {{pascalCase FEATURE_NAME}}.
|
|
109
|
-
/// </summary>
|
|
110
|
-
Task DeleteAsync(Guid id, Guid userId, CancellationToken cancellationToken = default);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
#endregion
|
|
114
|
-
|
|
115
|
-
#region DTOs
|
|
116
|
-
|
|
117
|
-
/// <summary>
|
|
118
|
-
/// Data transfer object for {{pascalCase FEATURE_NAME}}.
|
|
119
|
-
/// </summary>
|
|
120
|
-
public sealed record {{pascalCase FEATURE_NAME}}Dto(
|
|
121
|
-
Guid Id,
|
|
122
|
-
string Name,
|
|
123
|
-
Guid UserId,
|
|
124
|
-
{{pascalCase FEATURE_NAME}}Status Status,
|
|
125
|
-
DateTime CreatedAt,
|
|
126
|
-
DateTime? UpdatedAt
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
/// <summary>
|
|
130
|
-
/// Request to create a new {{pascalCase FEATURE_NAME}}.
|
|
131
|
-
/// </summary>
|
|
132
|
-
public sealed record Create{{pascalCase FEATURE_NAME}}Request(
|
|
133
|
-
string Name
|
|
134
|
-
// Add other required fields
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
/// <summary>
|
|
138
|
-
/// Request to update an existing {{pascalCase FEATURE_NAME}}.
|
|
139
|
-
/// </summary>
|
|
140
|
-
public sealed record Update{{pascalCase FEATURE_NAME}}Request(
|
|
141
|
-
string Name
|
|
142
|
-
// Add other updatable fields
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
#endregion
|
|
146
|
-
|
|
147
|
-
#region Enums
|
|
148
|
-
|
|
149
|
-
/// <summary>
|
|
150
|
-
/// Status of a {{pascalCase FEATURE_NAME}}.
|
|
151
|
-
/// </summary>
|
|
152
|
-
public enum {{pascalCase FEATURE_NAME}}Status
|
|
153
|
-
{
|
|
154
|
-
Draft = 0,
|
|
155
|
-
Active = 1,
|
|
156
|
-
Completed = 2,
|
|
157
|
-
Archived = 3,
|
|
158
|
-
// Error states
|
|
159
|
-
Failed = 100,
|
|
160
|
-
Cancelled = 101
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
#endregion
|
|
164
|
-
|
|
165
|
-
#region Exceptions
|
|
166
|
-
|
|
167
|
-
public sealed class {{pascalCase FEATURE_NAME}}NotFoundException(Guid id)
|
|
168
|
-
: Exception($"{{pascalCase FEATURE_NAME}} with ID {id} was not found.");
|
|
169
|
-
|
|
170
|
-
public sealed class {{pascalCase FEATURE_NAME}}AccessDeniedException(Guid id, Guid userId)
|
|
171
|
-
: Exception($"User {userId} does not have access to {{pascalCase FEATURE_NAME}} {id}.");
|
|
172
|
-
|
|
173
|
-
#endregion
|
|
1
|
+
// ============================================================
|
|
2
|
+
// CONTRACTS: {{titleCase FEATURE_NAME}}
|
|
3
|
+
// Stack: Next.js + Supabase + .NET API
|
|
4
|
+
// Generated by MORPH Framework
|
|
5
|
+
// Date: {{DATE}}
|
|
6
|
+
// ============================================================
|
|
7
|
+
|
|
8
|
+
#region Usings
|
|
9
|
+
|
|
10
|
+
using System;
|
|
11
|
+
using System.Collections.Generic;
|
|
12
|
+
using System.Threading;
|
|
13
|
+
using System.Threading.Tasks;
|
|
14
|
+
|
|
15
|
+
#endregion
|
|
16
|
+
|
|
17
|
+
namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}};
|
|
18
|
+
|
|
19
|
+
#region Configuration
|
|
20
|
+
|
|
21
|
+
/// <summary>
|
|
22
|
+
/// Supabase configuration options.
|
|
23
|
+
/// Bind from appsettings.json "Supabase" section.
|
|
24
|
+
/// </summary>
|
|
25
|
+
public sealed record SupabaseConfig
|
|
26
|
+
{
|
|
27
|
+
public required string Url { get; init; }
|
|
28
|
+
public required string AnonKey { get; init; }
|
|
29
|
+
public required string ServiceRoleKey { get; init; }
|
|
30
|
+
public required string JwtSecret { get; init; }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#endregion
|
|
34
|
+
|
|
35
|
+
#region Pagination
|
|
36
|
+
|
|
37
|
+
/// <summary>
|
|
38
|
+
/// Pagination query parameters. Use with [AsParameters] in Minimal API.
|
|
39
|
+
/// </summary>
|
|
40
|
+
public sealed record PaginationQuery(
|
|
41
|
+
int Page = 1,
|
|
42
|
+
int PageSize = 20)
|
|
43
|
+
{
|
|
44
|
+
public int Offset => (Page - 1) * PageSize;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// <summary>
|
|
48
|
+
/// Paginated result wrapper.
|
|
49
|
+
/// </summary>
|
|
50
|
+
public sealed record PagedResult<T>(
|
|
51
|
+
List<T> Items,
|
|
52
|
+
int TotalCount,
|
|
53
|
+
int Page,
|
|
54
|
+
int PageSize)
|
|
55
|
+
{
|
|
56
|
+
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
|
|
57
|
+
public bool HasNext => Page < TotalPages;
|
|
58
|
+
public bool HasPrevious => Page > 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#endregion
|
|
62
|
+
|
|
63
|
+
#region Repository Interfaces
|
|
64
|
+
|
|
65
|
+
/// <summary>
|
|
66
|
+
/// Generic repository interface for Supabase/PostgreSQL data access via Dapper.
|
|
67
|
+
/// </summary>
|
|
68
|
+
public interface IRepository<T, TId>
|
|
69
|
+
{
|
|
70
|
+
Task<T?> GetByIdAsync(TId id, CancellationToken cancellationToken = default);
|
|
71
|
+
Task<List<T>> GetAllAsync(CancellationToken cancellationToken = default);
|
|
72
|
+
Task<PagedResult<T>> GetPagedAsync(PaginationQuery query, CancellationToken cancellationToken = default);
|
|
73
|
+
Task<TId> CreateAsync(T entity, CancellationToken cancellationToken = default);
|
|
74
|
+
Task UpdateAsync(T entity, CancellationToken cancellationToken = default);
|
|
75
|
+
Task DeleteAsync(TId id, CancellationToken cancellationToken = default);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#endregion
|
|
79
|
+
|
|
80
|
+
#region Service Interfaces
|
|
81
|
+
|
|
82
|
+
/// <summary>
|
|
83
|
+
/// Service for managing {{pascalCase FEATURE_NAME}} operations.
|
|
84
|
+
/// </summary>
|
|
85
|
+
public interface I{{pascalCase FEATURE_NAME}}Service
|
|
86
|
+
{
|
|
87
|
+
/// <summary>
|
|
88
|
+
/// Gets a {{pascalCase FEATURE_NAME}} by its identifier.
|
|
89
|
+
/// </summary>
|
|
90
|
+
Task<{{pascalCase FEATURE_NAME}}Dto?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);
|
|
91
|
+
|
|
92
|
+
/// <summary>
|
|
93
|
+
/// Gets paginated list of {{pascalCase FEATURE_NAME}} items.
|
|
94
|
+
/// </summary>
|
|
95
|
+
Task<PagedResult<{{pascalCase FEATURE_NAME}}Dto>> GetPagedAsync(PaginationQuery query, Guid userId, CancellationToken cancellationToken = default);
|
|
96
|
+
|
|
97
|
+
/// <summary>
|
|
98
|
+
/// Creates a new {{pascalCase FEATURE_NAME}}.
|
|
99
|
+
/// </summary>
|
|
100
|
+
Task<{{pascalCase FEATURE_NAME}}Dto> CreateAsync(Create{{pascalCase FEATURE_NAME}}Request request, Guid userId, CancellationToken cancellationToken = default);
|
|
101
|
+
|
|
102
|
+
/// <summary>
|
|
103
|
+
/// Updates an existing {{pascalCase FEATURE_NAME}}.
|
|
104
|
+
/// </summary>
|
|
105
|
+
Task UpdateAsync(Guid id, Update{{pascalCase FEATURE_NAME}}Request request, Guid userId, CancellationToken cancellationToken = default);
|
|
106
|
+
|
|
107
|
+
/// <summary>
|
|
108
|
+
/// Deletes a {{pascalCase FEATURE_NAME}}.
|
|
109
|
+
/// </summary>
|
|
110
|
+
Task DeleteAsync(Guid id, Guid userId, CancellationToken cancellationToken = default);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
#endregion
|
|
114
|
+
|
|
115
|
+
#region DTOs
|
|
116
|
+
|
|
117
|
+
/// <summary>
|
|
118
|
+
/// Data transfer object for {{pascalCase FEATURE_NAME}}.
|
|
119
|
+
/// </summary>
|
|
120
|
+
public sealed record {{pascalCase FEATURE_NAME}}Dto(
|
|
121
|
+
Guid Id,
|
|
122
|
+
string Name,
|
|
123
|
+
Guid UserId,
|
|
124
|
+
{{pascalCase FEATURE_NAME}}Status Status,
|
|
125
|
+
DateTime CreatedAt,
|
|
126
|
+
DateTime? UpdatedAt
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
/// <summary>
|
|
130
|
+
/// Request to create a new {{pascalCase FEATURE_NAME}}.
|
|
131
|
+
/// </summary>
|
|
132
|
+
public sealed record Create{{pascalCase FEATURE_NAME}}Request(
|
|
133
|
+
string Name
|
|
134
|
+
// Add other required fields
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
/// <summary>
|
|
138
|
+
/// Request to update an existing {{pascalCase FEATURE_NAME}}.
|
|
139
|
+
/// </summary>
|
|
140
|
+
public sealed record Update{{pascalCase FEATURE_NAME}}Request(
|
|
141
|
+
string Name
|
|
142
|
+
// Add other updatable fields
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
#endregion
|
|
146
|
+
|
|
147
|
+
#region Enums
|
|
148
|
+
|
|
149
|
+
/// <summary>
|
|
150
|
+
/// Status of a {{pascalCase FEATURE_NAME}}.
|
|
151
|
+
/// </summary>
|
|
152
|
+
public enum {{pascalCase FEATURE_NAME}}Status
|
|
153
|
+
{
|
|
154
|
+
Draft = 0,
|
|
155
|
+
Active = 1,
|
|
156
|
+
Completed = 2,
|
|
157
|
+
Archived = 3,
|
|
158
|
+
// Error states
|
|
159
|
+
Failed = 100,
|
|
160
|
+
Cancelled = 101
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#endregion
|
|
164
|
+
|
|
165
|
+
#region Exceptions
|
|
166
|
+
|
|
167
|
+
public sealed class {{pascalCase FEATURE_NAME}}NotFoundException(Guid id)
|
|
168
|
+
: Exception($"{{pascalCase FEATURE_NAME}} with ID {id} was not found.");
|
|
169
|
+
|
|
170
|
+
public sealed class {{pascalCase FEATURE_NAME}}AccessDeniedException(Guid id, Guid userId)
|
|
171
|
+
: Exception($"User {userId} does not have access to {{pascalCase FEATURE_NAME}} {id}.");
|
|
172
|
+
|
|
173
|
+
#endregion
|