@polymorphism-tech/morph-spec 4.6.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +394 -700
  2. package/docs/ARCHITECTURE.md +331 -0
  3. package/docs/CHEATSHEET.md +221 -0
  4. package/docs/COMMAND-FLOWS.md +368 -0
  5. package/docs/QUICKSTART.md +212 -0
  6. package/docs/examples/order-management/contracts.cs +84 -0
  7. package/docs/examples/order-management/proposal.md +24 -0
  8. package/docs/examples/order-management/spec.md +162 -0
  9. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +1153 -0
  10. package/docs/plans/2026-02-23-ddd-nextsteps.md +682 -0
  11. package/docs/plans/2026-02-23-infra-architect-refactor.md +437 -0
  12. package/docs/plans/2026-02-23-nextjs-code-review-design.md +156 -0
  13. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +1254 -0
  14. package/docs/plans/2026-02-23-nextjs-standards-design.md +149 -0
  15. package/docs/plans/2026-02-23-nextjs-standards-impl.md +1846 -0
  16. package/framework/agents/README.md +14 -14
  17. package/framework/agents/architecture/standards-architect.md +159 -159
  18. package/framework/agents/frontend/nextjs-expert.md +87 -127
  19. package/framework/agents/infrastructure/azure-architect.md +147 -147
  20. package/framework/agents/infrastructure/infra-architect.md +45 -0
  21. package/framework/agents.json +1145 -278
  22. package/framework/rules/frontend-standards.md +0 -3
  23. package/framework/rules/nextjs-standards.md +17 -0
  24. package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +147 -0
  25. package/framework/skills/level-0-meta/code-review-nextjs/references/review-example-nextjs.md +254 -0
  26. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +3 -3
  27. package/framework/skills/level-1-workflows/phase-design/SKILL.md +45 -9
  28. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +38 -0
  29. package/framework/standards/STANDARDS.json +121 -0
  30. package/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
  31. package/framework/standards/architecture/ddd/complexity-levels.md +108 -0
  32. package/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
  33. package/framework/standards/frontend/nextjs/app-router.md +123 -0
  34. package/framework/standards/frontend/nextjs/components.md +132 -0
  35. package/framework/standards/frontend/nextjs/data-fetching.md +126 -0
  36. package/framework/standards/frontend/nextjs/forms.md +128 -0
  37. package/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
  38. package/framework/standards/frontend/nextjs/project-structure.md +102 -0
  39. package/framework/standards/frontend/nextjs/state-management.md +72 -0
  40. package/framework/standards/frontend/nextjs/testing.md +111 -0
  41. package/framework/templates/REGISTRY.json +538 -142
  42. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
  43. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
  44. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
  45. package/framework/templates/docs/spec.md +49 -0
  46. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
  47. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
  48. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
  49. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
  50. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
  51. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
  52. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
  53. package/framework/templates/project-structure/dotnet-ddd.md +70 -0
  54. package/framework/workflows/docs/enforcement-pipeline.md +2 -1
  55. package/package.json +1 -1
  56. package/scripts/scan-nextjs.mjs +169 -0
  57. package/src/commands/project/doctor.js +52 -1
  58. package/src/commands/project/init.js +15 -1
  59. package/src/commands/project/update.js +6 -1
  60. package/src/lib/standards/standards-context-injector.js +5 -0
  61. package/src/lib/validators/nextjs/index.js +6 -0
  62. package/src/lib/validators/nextjs/next-component-validator.js +181 -0
  63. package/src/lib/validators/validation-runner.js +5 -0
  64. package/src/utils/agents-installer.js +14 -2
  65. package/.morph/.morphversion +0 -5
  66. package/.morph/analytics/threads-log.jsonl +0 -6
  67. package/.morph/config/config.json +0 -8
  68. package/.morph/framework/agents.json +0 -948
  69. package/.morph/framework/standards/STANDARDS.json +0 -812
  70. package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
  71. package/.morph/framework/standards/ai-agents/production.md +0 -415
  72. package/.morph/framework/standards/ai-agents/setup.md +0 -418
  73. package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
  74. package/.morph/framework/standards/ai-agents/workflows.md +0 -354
  75. package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
  76. package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
  77. package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
  78. package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
  79. package/.morph/framework/standards/backend/api/rest.md +0 -492
  80. package/.morph/framework/standards/backend/api/validation.md +0 -88
  81. package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
  82. package/.morph/framework/standards/backend/database/ef-core.md +0 -199
  83. package/.morph/framework/standards/backend/database/migrations.md +0 -393
  84. package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
  85. package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
  86. package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
  87. package/.morph/framework/standards/backend/dotnet/async.md +0 -366
  88. package/.morph/framework/standards/backend/dotnet/core.md +0 -117
  89. package/.morph/framework/standards/backend/dotnet/di.md +0 -439
  90. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  91. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
  92. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
  93. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
  94. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
  95. package/.morph/framework/standards/context/analytics.md +0 -96
  96. package/.morph/framework/standards/context/bundles.md +0 -110
  97. package/.morph/framework/standards/context/priming.md +0 -78
  98. package/.morph/framework/standards/core/architecture.md +0 -185
  99. package/.morph/framework/standards/core/coding.md +0 -214
  100. package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
  101. package/.morph/framework/standards/core/git.md +0 -185
  102. package/.morph/framework/standards/core/testing.md +0 -295
  103. package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
  104. package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
  105. package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
  106. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  107. package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
  108. package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
  109. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  110. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  111. package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
  112. package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
  113. package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
  114. package/.morph/framework/standards/frontend/blazor/state.md +0 -191
  115. package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
  116. package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
  117. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -215
  118. package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
  119. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  120. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  121. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  122. package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
  123. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  124. package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
  125. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
  126. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
  127. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  128. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  129. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  130. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
  131. package/.morph/framework/standards/integration/api/graphql.md +0 -91
  132. package/.morph/framework/standards/integration/api/grpc.md +0 -114
  133. package/.morph/framework/standards/integration/api/rest-design.md +0 -95
  134. package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
  135. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  136. package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
  137. package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
  138. package/.morph/framework/standards/observability/logging.md +0 -131
  139. package/.morph/framework/standards/observability/metrics.md +0 -121
  140. package/.morph/framework/standards/observability/monitoring.md +0 -114
  141. package/.morph/framework/standards/observability/tracing.md +0 -132
  142. package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
  143. package/.morph/framework/standards/workflows/thread-management.md +0 -113
  144. package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
  145. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  146. package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
  147. package/.morph/framework/templates/README.md +0 -814
  148. package/.morph/framework/templates/REGISTRY.json +0 -1492
  149. package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
  150. package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
  151. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  152. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  153. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  154. package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
  155. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  156. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
  157. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
  158. package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
  159. package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
  160. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
  161. package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
  162. package/.morph/framework/templates/code/dotnet/test.cs +0 -239
  163. package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
  164. package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
  165. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
  166. package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
  167. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
  168. package/.morph/framework/templates/context/CONTEXT.md +0 -181
  169. package/.morph/framework/templates/docs/clarifications.md +0 -253
  170. package/.morph/framework/templates/docs/onboarding.md +0 -123
  171. package/.morph/framework/templates/docs/proposal.md +0 -182
  172. package/.morph/framework/templates/docs/schema-analysis.md +0 -119
  173. package/.morph/framework/templates/docs/spec.md +0 -149
  174. package/.morph/framework/templates/docs/ui-components.md +0 -124
  175. package/.morph/framework/templates/docs/ui-design-system.md +0 -76
  176. package/.morph/framework/templates/docs/ui-flows.md +0 -167
  177. package/.morph/framework/templates/docs/ui-mockups.md +0 -98
  178. package/.morph/framework/templates/docs/user-stories.md +0 -34
  179. package/.morph/framework/templates/examples/design-system-examples.md +0 -357
  180. package/.morph/framework/templates/examples/spec-examples.md +0 -90
  181. package/.morph/framework/templates/feature/decisions.md +0 -187
  182. package/.morph/framework/templates/feature/recap.md +0 -146
  183. package/.morph/framework/templates/feature/tasks.md +0 -199
  184. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  185. package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
  186. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  187. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  188. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  189. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  190. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  191. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  192. package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
  193. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  194. package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
  195. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  196. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  197. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  198. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  199. package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
  200. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
  201. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
  202. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
  203. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
  204. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
  205. package/.morph/framework/templates/infrastructure/github/README.md +0 -593
  206. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  207. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
  208. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
  209. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  210. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
  211. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
  212. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
  213. package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
  214. package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
  215. package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
  216. package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
  217. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
  218. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
  219. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  220. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  221. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  222. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  223. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  224. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
  225. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
  226. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
  227. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
  228. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
  229. package/.morph/framework/templates/saas/subscription.cs +0 -347
  230. package/.morph/framework/templates/saas/tenant.cs +0 -338
  231. package/.morph/framework/templates/state.template.json +0 -17
  232. package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
  233. package/.morph/framework/templates/ui/MudTheme.cs +0 -281
  234. package/.morph/framework/templates/ui/design-system.css +0 -226
  235. package/.morph/logs/tool-failures.log +0 -7
  236. package/.morph/memory/pre-compact-2026-02-23T15-43-03-521Z.json +0 -16
  237. package/.morph/state.json +0 -48
  238. package/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
  239. package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
@@ -1,239 +0,0 @@
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
- }
@@ -1,163 +0,0 @@
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
- // ============================================================
@@ -1,171 +0,0 @@
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
- // ============================================================