@polymorphism-tech/morph-spec 1.0.4 → 2.0.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 +1381 -0
- package/LICENSE +72 -0
- package/README.md +89 -6
- package/bin/detect-agents.js +225 -0
- package/bin/morph-spec.js +120 -0
- package/bin/render-template.js +302 -0
- package/bin/semantic-detect-agents.js +246 -0
- package/bin/validate-agents-skills.js +239 -0
- package/bin/validate-agents.js +69 -0
- package/bin/validate-phase.js +263 -0
- package/content/.azure/README.md +293 -0
- package/content/.azure/docs/azure-devops-setup.md +454 -0
- package/content/.azure/docs/branch-strategy.md +398 -0
- package/content/.azure/docs/local-development.md +515 -0
- package/content/.azure/pipelines/pipeline-variables.yml +34 -0
- package/content/.azure/pipelines/prod-pipeline.yml +319 -0
- package/content/.azure/pipelines/staging-pipeline.yml +234 -0
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -0
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -0
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -0
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -0
- package/content/.claude/commands/morph-apply.md +118 -26
- package/content/.claude/commands/morph-archive.md +9 -9
- package/content/.claude/commands/morph-clarify.md +184 -0
- package/content/.claude/commands/morph-design.md +275 -0
- package/content/.claude/commands/morph-proposal.md +56 -15
- package/content/.claude/commands/morph-setup.md +100 -0
- package/content/.claude/commands/morph-status.md +47 -32
- package/content/.claude/commands/morph-tasks.md +319 -0
- package/content/.claude/commands/morph-uiux.md +211 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +604 -0
- package/content/.claude/skills/specialists/ms-agent-expert.md +143 -89
- package/content/.claude/skills/specialists/ui-ux-designer.md +744 -9
- package/content/.claude/skills/stacks/dotnet-blazor.md +244 -8
- package/content/.claude/skills/stacks/dotnet-nextjs.md +2 -2
- package/content/.morph/.morphversion +5 -0
- package/content/.morph/config/agents.json +101 -8
- package/content/.morph/config/azure-pricing.json +70 -0
- package/content/.morph/config/azure-pricing.schema.json +50 -0
- package/content/.morph/config/config.template.json +15 -3
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -0
- package/content/.morph/hooks/README.md +239 -0
- package/content/.morph/hooks/pre-commit-agents.sh +24 -0
- package/content/.morph/hooks/pre-commit-all.sh +48 -0
- package/content/.morph/hooks/pre-commit-costs.sh +91 -0
- package/content/.morph/hooks/pre-commit-specs.sh +49 -0
- package/content/.morph/hooks/pre-commit-tests.sh +60 -0
- package/content/.morph/project.md +5 -4
- package/content/.morph/schemas/agent.schema.json +296 -0
- package/content/.morph/standards/agent-framework-setup.md +453 -0
- package/content/.morph/standards/architecture.md +142 -7
- package/content/.morph/standards/azure.md +218 -23
- package/content/.morph/standards/coding.md +47 -12
- package/content/.morph/standards/dotnet10-migration.md +494 -0
- package/content/.morph/standards/fluent-ui-setup.md +590 -0
- package/content/.morph/standards/migration-guide.md +514 -0
- package/content/.morph/standards/passkeys-auth.md +423 -0
- package/content/.morph/standards/vector-search-rag.md +536 -0
- package/content/.morph/state.json +18 -0
- package/content/.morph/templates/FluentDesignTheme.cs +149 -0
- package/content/.morph/templates/MudTheme.cs +281 -0
- package/content/.morph/templates/contracts.cs +55 -55
- package/content/.morph/templates/decisions.md +4 -4
- package/content/.morph/templates/design-system.css +226 -0
- package/content/.morph/templates/infra/.dockerignore.example +89 -0
- package/content/.morph/templates/infra/Dockerfile.example +82 -0
- package/content/.morph/templates/infra/README.md +286 -0
- package/content/.morph/templates/infra/app-service.bicep +164 -0
- package/content/.morph/templates/infra/deploy.ps1 +229 -0
- package/content/.morph/templates/infra/deploy.sh +208 -0
- package/content/.morph/templates/infra/main.bicep +41 -7
- package/content/.morph/templates/infra/parameters.dev.json +6 -0
- package/content/.morph/templates/infra/parameters.prod.json +6 -0
- package/content/.morph/templates/infra/parameters.staging.json +29 -0
- package/content/.morph/templates/proposal.md +3 -3
- package/content/.morph/templates/recap.md +3 -3
- package/content/.morph/templates/spec.md +9 -8
- package/content/.morph/templates/sprint-status.yaml +68 -0
- package/content/.morph/templates/state.template.json +222 -0
- package/content/.morph/templates/story.md +143 -0
- package/content/.morph/templates/tasks.md +1 -1
- package/content/.morph/templates/ui-components.md +276 -0
- package/content/.morph/templates/ui-design-system.md +286 -0
- package/content/.morph/templates/ui-flows.md +336 -0
- package/content/.morph/templates/ui-mockups.md +133 -0
- package/content/.morph/test-infra/example.bicep +59 -0
- package/content/CLAUDE.md +124 -0
- package/content/README.md +79 -0
- package/detectors/config-detector.js +223 -0
- package/detectors/conversation-analyzer.js +163 -0
- package/detectors/index.js +84 -0
- package/detectors/standards-generator.js +275 -0
- package/detectors/structure-detector.js +221 -0
- package/docs/README.md +149 -0
- package/docs/api/cost-calculator.js.html +513 -0
- package/docs/api/design-system-generator.js.html +382 -0
- 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 +978 -0
- 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 +1049 -0
- 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/global.html +5263 -0
- package/docs/api/index.html +96 -0
- package/docs/api/scripts/collapse.js +39 -0
- package/docs/api/scripts/commonNav.js +28 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/nav.js +12 -0
- package/docs/api/scripts/polyfill.js +4 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/scripts/search.js +99 -0
- package/docs/api/state-manager.js.html +423 -0
- package/docs/api/styles/jsdoc.css +776 -0
- package/docs/api/styles/prettify.css +80 -0
- package/docs/examples.md +328 -0
- package/docs/getting-started.md +302 -0
- package/docs/installation.md +361 -0
- package/docs/templates.md +418 -0
- package/docs/validation-checklist.md +266 -0
- package/package.json +39 -12
- package/src/commands/cost.js +181 -0
- package/src/commands/create-story.js +283 -0
- package/src/commands/detect.js +104 -0
- package/src/commands/doctor.js +67 -0
- package/src/commands/generate.js +149 -0
- package/src/commands/init.js +69 -45
- package/src/commands/shard-spec.js +224 -0
- package/src/commands/sprint-status.js +250 -0
- package/src/commands/state.js +333 -0
- package/src/commands/sync.js +167 -0
- package/src/commands/update-pricing.js +206 -0
- package/src/commands/update.js +88 -13
- package/src/lib/complexity-analyzer.js +292 -0
- package/src/lib/cost-calculator.js +429 -0
- package/src/lib/design-system-generator.js +298 -0
- package/src/lib/state-manager.js +340 -0
- package/src/utils/file-copier.js +59 -0
- package/src/utils/version-checker.js +175 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
using MudBlazor;
|
|
2
|
+
|
|
3
|
+
namespace {Namespace}.Themes;
|
|
4
|
+
|
|
5
|
+
/// <summary>
|
|
6
|
+
/// MudBlazor Theme customizado para {Project Name}.
|
|
7
|
+
/// Gerado automaticamente baseado em ui-design-system.md
|
|
8
|
+
/// </summary>
|
|
9
|
+
/// <remarks>
|
|
10
|
+
/// Template MORPH-SPEC v2.1.1 by Polymorphism Tech
|
|
11
|
+
/// </remarks>
|
|
12
|
+
public static class AppTheme
|
|
13
|
+
{
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// Tema Light Mode
|
|
16
|
+
/// </summary>
|
|
17
|
+
public static MudTheme LightTheme => new()
|
|
18
|
+
{
|
|
19
|
+
Palette = new PaletteLight
|
|
20
|
+
{
|
|
21
|
+
// Cores Principais
|
|
22
|
+
Primary = "#{hex da cor primária}", // Ex: #3b82f6
|
|
23
|
+
Secondary = "#{hex da cor secundária}", // Ex: #6b7280
|
|
24
|
+
Tertiary = "#{hex da cor terciária}", // Opcional
|
|
25
|
+
|
|
26
|
+
// Cores de Estado
|
|
27
|
+
Success = "#{hex}", // Ex: #10b981
|
|
28
|
+
Error = "#{hex}", // Ex: #ef4444
|
|
29
|
+
Warning = "#{hex}", // Ex: #f59e0b
|
|
30
|
+
Info = "#{hex}", // Ex: #06b6d4
|
|
31
|
+
|
|
32
|
+
// Background e Superfícies
|
|
33
|
+
Background = "#ffffff",
|
|
34
|
+
BackgroundGrey = "#{hex do gray-50}", // Ex: #f9fafb
|
|
35
|
+
Surface = "#ffffff",
|
|
36
|
+
|
|
37
|
+
// Text Colors
|
|
38
|
+
TextPrimary = "#{hex do gray-900}", // Texto principal
|
|
39
|
+
TextSecondary = "#{hex do gray-600}", // Texto secundário
|
|
40
|
+
TextDisabled = "#{hex do gray-400}", // Texto desabilitado
|
|
41
|
+
|
|
42
|
+
// Borders
|
|
43
|
+
Divider = "#{hex do gray-200}", // Divisores
|
|
44
|
+
DividerLight = "#{hex do gray-100}", // Divisores mais claros
|
|
45
|
+
Lines = "#{hex do gray-300}", // Linhas de borda
|
|
46
|
+
|
|
47
|
+
// Action colors (usados em botões, links, etc)
|
|
48
|
+
ActionDefault = "#{hex do gray-500}",
|
|
49
|
+
ActionDisabled = "#{hex do gray-300}",
|
|
50
|
+
ActionDisabledBackground = "#{hex do gray-100}",
|
|
51
|
+
|
|
52
|
+
// Outros
|
|
53
|
+
Dark = "#{hex do gray-800}",
|
|
54
|
+
DarkLighten = "#{hex do gray-700}",
|
|
55
|
+
DarkDarken = "#{hex do gray-900}",
|
|
56
|
+
|
|
57
|
+
// Overlay (usado em modais, dropdowns)
|
|
58
|
+
OverlayLight = "rgba(255, 255, 255, 0.95)",
|
|
59
|
+
OverlayDark = "rgba(33, 33, 33, 0.95)",
|
|
60
|
+
|
|
61
|
+
// Hover effects
|
|
62
|
+
HoverOpacity = 0.06, // Opacidade do hover (6%)
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
Typography = new Typography
|
|
66
|
+
{
|
|
67
|
+
// Font Families
|
|
68
|
+
Default = new Default
|
|
69
|
+
{
|
|
70
|
+
FontFamily = new[] { "{Font Name}", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "sans-serif" },
|
|
71
|
+
FontSize = "1rem", // 16px
|
|
72
|
+
FontWeight = 400, // Regular
|
|
73
|
+
LineHeight = 1.5,
|
|
74
|
+
LetterSpacing = "normal",
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
H1 = new H1
|
|
78
|
+
{
|
|
79
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
80
|
+
FontSize = "2.25rem", // 36px
|
|
81
|
+
FontWeight = 700, // Bold
|
|
82
|
+
LineHeight = 1.2,
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
H2 = new H2
|
|
86
|
+
{
|
|
87
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
88
|
+
FontSize = "1.875rem", // 30px
|
|
89
|
+
FontWeight = 700,
|
|
90
|
+
LineHeight = 1.3,
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
H3 = new H3
|
|
94
|
+
{
|
|
95
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
96
|
+
FontSize = "1.5rem", // 24px
|
|
97
|
+
FontWeight = 600,
|
|
98
|
+
LineHeight = 1.4,
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
H4 = new H4
|
|
102
|
+
{
|
|
103
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
104
|
+
FontSize = "1.25rem", // 20px
|
|
105
|
+
FontWeight = 600,
|
|
106
|
+
LineHeight = 1.4,
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
H5 = new H5
|
|
110
|
+
{
|
|
111
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
112
|
+
FontSize = "1.125rem", // 18px
|
|
113
|
+
FontWeight = 600,
|
|
114
|
+
LineHeight = 1.5,
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
H6 = new H6
|
|
118
|
+
{
|
|
119
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
120
|
+
FontSize = "1rem", // 16px
|
|
121
|
+
FontWeight = 600,
|
|
122
|
+
LineHeight = 1.5,
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
Body1 = new Body1
|
|
126
|
+
{
|
|
127
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
128
|
+
FontSize = "1rem", // 16px
|
|
129
|
+
FontWeight = 400,
|
|
130
|
+
LineHeight = 1.5,
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
Body2 = new Body2
|
|
134
|
+
{
|
|
135
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
136
|
+
FontSize = "0.875rem", // 14px
|
|
137
|
+
FontWeight = 400,
|
|
138
|
+
LineHeight = 1.43,
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
Button = new Button
|
|
142
|
+
{
|
|
143
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
144
|
+
FontSize = "0.875rem", // 14px
|
|
145
|
+
FontWeight = 600, // Semibold
|
|
146
|
+
LineHeight = 1.75,
|
|
147
|
+
TextTransform = "none", // Ou "uppercase" se preferir
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
Caption = new Caption
|
|
151
|
+
{
|
|
152
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
153
|
+
FontSize = "0.75rem", // 12px
|
|
154
|
+
FontWeight = 400,
|
|
155
|
+
LineHeight = 1.66,
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
Subtitle1 = new Subtitle1
|
|
159
|
+
{
|
|
160
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
161
|
+
FontSize = "1rem",
|
|
162
|
+
FontWeight = 500, // Medium
|
|
163
|
+
LineHeight = 1.75,
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
Subtitle2 = new Subtitle2
|
|
167
|
+
{
|
|
168
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
169
|
+
FontSize = "0.875rem",
|
|
170
|
+
FontWeight = 500,
|
|
171
|
+
LineHeight = 1.57,
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
Overline = new Overline
|
|
175
|
+
{
|
|
176
|
+
FontFamily = new[] { "{Font Name}", "sans-serif" },
|
|
177
|
+
FontSize = "0.75rem",
|
|
178
|
+
FontWeight = 600,
|
|
179
|
+
LineHeight = 2.66,
|
|
180
|
+
LetterSpacing = "0.08em",
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
Shadows = new Shadow
|
|
185
|
+
{
|
|
186
|
+
Elevation = new[]
|
|
187
|
+
{
|
|
188
|
+
"none", // 0
|
|
189
|
+
"0 1px 2px 0 rgba(0, 0, 0, 0.05)", // 1
|
|
190
|
+
"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", // 2
|
|
191
|
+
"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)", // 3
|
|
192
|
+
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)", // 4
|
|
193
|
+
"0 25px 50px -12px rgba(0, 0, 0, 0.25)", // 5
|
|
194
|
+
// Adicione mais elevações conforme necessário
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
LayoutProperties = new LayoutProperties
|
|
199
|
+
{
|
|
200
|
+
// Border Radius
|
|
201
|
+
DefaultBorderRadius = "6px", // md
|
|
202
|
+
|
|
203
|
+
// Drawer
|
|
204
|
+
DrawerWidthLeft = "240px",
|
|
205
|
+
DrawerWidthRight = "240px",
|
|
206
|
+
|
|
207
|
+
// AppBar
|
|
208
|
+
AppbarHeight = "64px",
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
ZIndex = new ZIndex
|
|
212
|
+
{
|
|
213
|
+
Drawer = 1200,
|
|
214
|
+
AppBar = 1100,
|
|
215
|
+
Dialog = 1300,
|
|
216
|
+
Popover = 1400,
|
|
217
|
+
Snackbar = 1500,
|
|
218
|
+
Tooltip = 1600,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/// <summary>
|
|
223
|
+
/// Tema Dark Mode (opcional - ajustar cores)
|
|
224
|
+
/// </summary>
|
|
225
|
+
public static MudTheme DarkTheme => new()
|
|
226
|
+
{
|
|
227
|
+
Palette = new PaletteDark
|
|
228
|
+
{
|
|
229
|
+
// Cores Principais (ajustar para dark mode)
|
|
230
|
+
Primary = "#{hex}",
|
|
231
|
+
Secondary = "#{hex}",
|
|
232
|
+
|
|
233
|
+
// Cores de Estado
|
|
234
|
+
Success = "#{hex}",
|
|
235
|
+
Error = "#{hex}",
|
|
236
|
+
Warning = "#{hex}",
|
|
237
|
+
Info = "#{hex}",
|
|
238
|
+
|
|
239
|
+
// Background e Superfícies (tons escuros)
|
|
240
|
+
Background = "#{hex do gray-900}",
|
|
241
|
+
BackgroundGrey = "#{hex do gray-800}",
|
|
242
|
+
Surface = "#{hex do gray-800}",
|
|
243
|
+
|
|
244
|
+
// Text Colors (invertidos)
|
|
245
|
+
TextPrimary = "#{hex do gray-50}",
|
|
246
|
+
TextSecondary = "#{hex do gray-400}",
|
|
247
|
+
TextDisabled = "#{hex do gray-600}",
|
|
248
|
+
|
|
249
|
+
// Etc... (ajustar conforme design system dark mode)
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
// Compartilhar Typography e outras configurações do LightTheme
|
|
253
|
+
Typography = LightTheme.Typography,
|
|
254
|
+
Shadows = LightTheme.Shadows,
|
|
255
|
+
LayoutProperties = LightTheme.LayoutProperties,
|
|
256
|
+
ZIndex = LightTheme.ZIndex,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/// <summary>
|
|
261
|
+
/// EXEMPLO DE USO:
|
|
262
|
+
///
|
|
263
|
+
/// // Program.cs
|
|
264
|
+
/// builder.Services.AddMudServices(config =>
|
|
265
|
+
/// {
|
|
266
|
+
/// config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomRight;
|
|
267
|
+
/// });
|
|
268
|
+
///
|
|
269
|
+
/// // App.razor ou MainLayout.razor
|
|
270
|
+
/// <MudThemeProvider Theme="@AppTheme.LightTheme" />
|
|
271
|
+
/// <MudDialogProvider />
|
|
272
|
+
/// <MudSnackbarProvider />
|
|
273
|
+
///
|
|
274
|
+
/// // Para suportar dark mode dinâmico:
|
|
275
|
+
/// <MudThemeProvider @bind-IsDarkMode="@_isDarkMode"
|
|
276
|
+
/// Theme="@(_isDarkMode ? AppTheme.DarkTheme : AppTheme.LightTheme)" />
|
|
277
|
+
///
|
|
278
|
+
/// @code {
|
|
279
|
+
/// private bool _isDarkMode;
|
|
280
|
+
/// }
|
|
281
|
+
/// </summary>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ============================================================
|
|
2
|
-
// CONTRACTS: {
|
|
2
|
+
// CONTRACTS: {{FEATURE_NAME_TITLE}}
|
|
3
3
|
// Generated by MORPH Framework
|
|
4
|
-
// Date: {
|
|
4
|
+
// Date: {{DATE}}
|
|
5
5
|
// ============================================================
|
|
6
6
|
|
|
7
7
|
#region Usings
|
|
@@ -13,37 +13,37 @@ using System.Threading.Tasks;
|
|
|
13
13
|
|
|
14
14
|
#endregion
|
|
15
15
|
|
|
16
|
-
namespace
|
|
16
|
+
namespace {{NAMESPACE}}.Application.Features.{{FEATURE_NAME_PASCAL}};
|
|
17
17
|
|
|
18
18
|
#region Service Interfaces
|
|
19
19
|
|
|
20
20
|
/// <summary>
|
|
21
|
-
/// Service for managing {
|
|
21
|
+
/// Service for managing {{FEATURE_NAME_PASCAL}} operations.
|
|
22
22
|
/// </summary>
|
|
23
|
-
public interface I{
|
|
23
|
+
public interface I{{FEATURE_NAME_PASCAL}}Service
|
|
24
24
|
{
|
|
25
25
|
/// <summary>
|
|
26
|
-
/// Gets a {
|
|
26
|
+
/// Gets a {{FEATURE_NAME_LOWER_SNAKE}} by its identifier.
|
|
27
27
|
/// </summary>
|
|
28
|
-
Task<{
|
|
28
|
+
Task<{{FEATURE_NAME_PASCAL}}Dto?> GetByIdAsync(int id, CancellationToken cancellationToken = default);
|
|
29
29
|
|
|
30
30
|
/// <summary>
|
|
31
|
-
/// Gets all {
|
|
31
|
+
/// Gets all {{FEATURE_NAME_LOWER_SNAKE}}s.
|
|
32
32
|
/// </summary>
|
|
33
|
-
Task<List<{
|
|
33
|
+
Task<List<{{FEATURE_NAME_PASCAL}}Dto>> GetAllAsync(CancellationToken cancellationToken = default);
|
|
34
34
|
|
|
35
35
|
/// <summary>
|
|
36
|
-
/// Creates a new {
|
|
36
|
+
/// Creates a new {{FEATURE_NAME_LOWER_SNAKE}}.
|
|
37
37
|
/// </summary>
|
|
38
|
-
Task<{
|
|
38
|
+
Task<{{FEATURE_NAME_PASCAL}}Dto> CreateAsync(Create{{FEATURE_NAME_PASCAL}}Request request, CancellationToken cancellationToken = default);
|
|
39
39
|
|
|
40
40
|
/// <summary>
|
|
41
|
-
/// Updates an existing {
|
|
41
|
+
/// Updates an existing {{FEATURE_NAME_LOWER_SNAKE}}.
|
|
42
42
|
/// </summary>
|
|
43
|
-
Task UpdateAsync(int id, Update{
|
|
43
|
+
Task UpdateAsync(int id, Update{{FEATURE_NAME_PASCAL}}Request request, CancellationToken cancellationToken = default);
|
|
44
44
|
|
|
45
45
|
/// <summary>
|
|
46
|
-
/// Deletes a {
|
|
46
|
+
/// Deletes a {{FEATURE_NAME_LOWER_SNAKE}}.
|
|
47
47
|
/// </summary>
|
|
48
48
|
Task DeleteAsync(int id, CancellationToken cancellationToken = default);
|
|
49
49
|
}
|
|
@@ -53,28 +53,28 @@ public interface I{Feature}Service
|
|
|
53
53
|
#region DTOs
|
|
54
54
|
|
|
55
55
|
/// <summary>
|
|
56
|
-
/// Data transfer object for {
|
|
56
|
+
/// Data transfer object for {{FEATURE_NAME_PASCAL}}.
|
|
57
57
|
/// </summary>
|
|
58
|
-
public record {
|
|
58
|
+
public record {{FEATURE_NAME_PASCAL}}Dto(
|
|
59
59
|
int Id,
|
|
60
60
|
string Name,
|
|
61
|
-
{
|
|
61
|
+
{{FEATURE_NAME_PASCAL}}Status Status,
|
|
62
62
|
DateTime CreatedAt,
|
|
63
63
|
DateTime? UpdatedAt
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
/// <summary>
|
|
67
|
-
/// Request to create a new {
|
|
67
|
+
/// Request to create a new {{FEATURE_NAME_PASCAL}}.
|
|
68
68
|
/// </summary>
|
|
69
|
-
public record Create{
|
|
69
|
+
public record Create{{FEATURE_NAME_PASCAL}}Request(
|
|
70
70
|
string Name
|
|
71
71
|
// Add other required fields
|
|
72
72
|
);
|
|
73
73
|
|
|
74
74
|
/// <summary>
|
|
75
|
-
/// Request to update an existing {
|
|
75
|
+
/// Request to update an existing {{FEATURE_NAME_PASCAL}}.
|
|
76
76
|
/// </summary>
|
|
77
|
-
public record Update{
|
|
77
|
+
public record Update{{FEATURE_NAME_PASCAL}}Request(
|
|
78
78
|
string Name
|
|
79
79
|
// Add other updatable fields
|
|
80
80
|
);
|
|
@@ -84,9 +84,9 @@ public record Update{Feature}Request(
|
|
|
84
84
|
#region Enums
|
|
85
85
|
|
|
86
86
|
/// <summary>
|
|
87
|
-
/// Status of a {
|
|
87
|
+
/// Status of a {{FEATURE_NAME_PASCAL}}.
|
|
88
88
|
/// </summary>
|
|
89
|
-
public enum {
|
|
89
|
+
public enum {{FEATURE_NAME_PASCAL}}Status
|
|
90
90
|
{
|
|
91
91
|
Pending = 0,
|
|
92
92
|
Active = 1,
|
|
@@ -99,15 +99,15 @@ public enum {Feature}Status
|
|
|
99
99
|
#region Repository Interfaces
|
|
100
100
|
|
|
101
101
|
/// <summary>
|
|
102
|
-
/// Repository for {
|
|
102
|
+
/// Repository for {{FEATURE_NAME_PASCAL}} data access.
|
|
103
103
|
/// </summary>
|
|
104
|
-
public interface I{
|
|
104
|
+
public interface I{{FEATURE_NAME_PASCAL}}Repository
|
|
105
105
|
{
|
|
106
|
-
Task<{
|
|
107
|
-
Task<List<{
|
|
108
|
-
Task AddAsync({
|
|
109
|
-
void Update({
|
|
110
|
-
void Remove({
|
|
106
|
+
Task<{{FEATURE_NAME_PASCAL}}?> GetByIdAsync(int id, CancellationToken cancellationToken = default);
|
|
107
|
+
Task<List<{{FEATURE_NAME_PASCAL}}>> GetAllAsync(CancellationToken cancellationToken = default);
|
|
108
|
+
Task AddAsync({{FEATURE_NAME_PASCAL}} entity, CancellationToken cancellationToken = default);
|
|
109
|
+
void Update({{FEATURE_NAME_PASCAL}} entity);
|
|
110
|
+
void Remove({{FEATURE_NAME_PASCAL}} entity);
|
|
111
111
|
Task SaveChangesAsync(CancellationToken cancellationToken = default);
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -117,38 +117,38 @@ public interface I{Feature}Repository
|
|
|
117
117
|
|
|
118
118
|
/*
|
|
119
119
|
/// <summary>
|
|
120
|
-
/// {
|
|
121
|
-
/// Implement in Domain/Entities/{
|
|
120
|
+
/// {{FEATURE_NAME_PASCAL}} domain entity.
|
|
121
|
+
/// Implement in Domain/Entities/{{FEATURE_NAME_PASCAL}}.cs
|
|
122
122
|
/// </summary>
|
|
123
|
-
public class {
|
|
123
|
+
public class {{FEATURE_NAME_PASCAL}}
|
|
124
124
|
{
|
|
125
125
|
public int Id { get; private set; }
|
|
126
126
|
public string Name { get; private set; } = string.Empty;
|
|
127
|
-
public {
|
|
127
|
+
public {{FEATURE_NAME_PASCAL}}Status Status { get; private set; }
|
|
128
128
|
public DateTime CreatedAt { get; private set; }
|
|
129
129
|
public DateTime? UpdatedAt { get; private set; }
|
|
130
130
|
|
|
131
|
-
private {
|
|
131
|
+
private {{FEATURE_NAME_PASCAL}}() { } // EF Constructor
|
|
132
132
|
|
|
133
|
-
public static {
|
|
133
|
+
public static {{FEATURE_NAME_PASCAL}} Create(string name)
|
|
134
134
|
{
|
|
135
|
-
return new {
|
|
135
|
+
return new {{FEATURE_NAME_PASCAL}}
|
|
136
136
|
{
|
|
137
137
|
Name = name,
|
|
138
|
-
Status = {
|
|
138
|
+
Status = {{FEATURE_NAME_PASCAL}}Status.Pending,
|
|
139
139
|
CreatedAt = DateTime.UtcNow
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
public void Activate()
|
|
144
144
|
{
|
|
145
|
-
Status = {
|
|
145
|
+
Status = {{FEATURE_NAME_PASCAL}}Status.Active;
|
|
146
146
|
UpdatedAt = DateTime.UtcNow;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
public void Complete()
|
|
150
150
|
{
|
|
151
|
-
Status = {
|
|
151
|
+
Status = {{FEATURE_NAME_PASCAL}}Status.Completed;
|
|
152
152
|
UpdatedAt = DateTime.UtcNow;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -159,24 +159,24 @@ public class {Feature}
|
|
|
159
159
|
#region AI Agent Interfaces (if applicable)
|
|
160
160
|
|
|
161
161
|
/// <summary>
|
|
162
|
-
/// AI Agent for {
|
|
162
|
+
/// AI Agent for {{FEATURE_NAME_PASCAL}} analysis.
|
|
163
163
|
/// </summary>
|
|
164
|
-
public interface I{
|
|
164
|
+
public interface I{{FEATURE_NAME_PASCAL}}AnalyzerAgent
|
|
165
165
|
{
|
|
166
166
|
/// <summary>
|
|
167
|
-
/// Analyzes {
|
|
167
|
+
/// Analyzes {{FEATURE_NAME_LOWER_SNAKE}} data using AI.
|
|
168
168
|
/// </summary>
|
|
169
|
-
Task<{
|
|
170
|
-
{
|
|
169
|
+
Task<{{FEATURE_NAME_PASCAL}}AnalysisResult> AnalyzeAsync(
|
|
170
|
+
{{FEATURE_NAME_PASCAL}}Data data,
|
|
171
171
|
CancellationToken cancellationToken = default);
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
public record {
|
|
174
|
+
public record {{FEATURE_NAME_PASCAL}}Data(
|
|
175
175
|
// Input data for analysis
|
|
176
176
|
string Content
|
|
177
177
|
);
|
|
178
178
|
|
|
179
|
-
public record {
|
|
179
|
+
public record {{FEATURE_NAME_PASCAL}}AnalysisResult(
|
|
180
180
|
string Summary,
|
|
181
181
|
List<string> Insights,
|
|
182
182
|
List<string> Recommendations,
|
|
@@ -188,12 +188,12 @@ public record {Feature}AnalysisResult(
|
|
|
188
188
|
#region Hangfire Job Interfaces (if applicable)
|
|
189
189
|
|
|
190
190
|
/// <summary>
|
|
191
|
-
/// Background job for processing {
|
|
191
|
+
/// Background job for processing {{FEATURE_NAME_PASCAL}}.
|
|
192
192
|
/// </summary>
|
|
193
|
-
public interface I{
|
|
193
|
+
public interface I{{FEATURE_NAME_PASCAL}}ProcessorJob
|
|
194
194
|
{
|
|
195
195
|
/// <summary>
|
|
196
|
-
/// Executes the {
|
|
196
|
+
/// Executes the {{FEATURE_NAME_LOWER_SNAKE}} processing job.
|
|
197
197
|
/// </summary>
|
|
198
198
|
Task ExecuteAsync(int id, CancellationToken cancellationToken = default);
|
|
199
199
|
}
|
|
@@ -202,15 +202,15 @@ public interface I{Feature}ProcessorJob
|
|
|
202
202
|
|
|
203
203
|
#region Exceptions
|
|
204
204
|
|
|
205
|
-
public class {
|
|
205
|
+
public class {{FEATURE_NAME_PASCAL}}NotFoundException : Exception
|
|
206
206
|
{
|
|
207
|
-
public {
|
|
208
|
-
: base($"{
|
|
207
|
+
public {{FEATURE_NAME_PASCAL}}NotFoundException(int id)
|
|
208
|
+
: base($"{{FEATURE_NAME_PASCAL}} with ID {id} was not found.") { }
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
public class {
|
|
211
|
+
public class {{FEATURE_NAME_PASCAL}}ProcessingException : Exception
|
|
212
212
|
{
|
|
213
|
-
public {
|
|
213
|
+
public {{FEATURE_NAME_PASCAL}}ProcessingException(string message, Exception? innerException = null)
|
|
214
214
|
: base(message, innerException) { }
|
|
215
215
|
}
|
|
216
216
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Architecture Decision Records - {
|
|
1
|
+
# Architecture Decision Records - {{FEATURE_NAME_TITLE}}
|
|
2
2
|
|
|
3
3
|
## ADR-001: {Decision Title}
|
|
4
4
|
|
|
5
|
-
**Date:** {
|
|
5
|
+
**Date:** {{DATE}}
|
|
6
6
|
**Status:** Proposed | Accepted | Deprecated | Superseded
|
|
7
7
|
**Deciders:** MORPH Agents, Developer
|
|
8
8
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
## ADR-002: Database Model
|
|
44
44
|
|
|
45
|
-
**Date:** {
|
|
45
|
+
**Date:** {{DATE}}
|
|
46
46
|
**Status:** Accepted
|
|
47
47
|
|
|
48
48
|
### Context
|
|
@@ -65,7 +65,7 @@ Use Azure SQL with the following model:
|
|
|
65
65
|
|
|
66
66
|
## ADR-003: AI Integration
|
|
67
67
|
|
|
68
|
-
**Date:** {
|
|
68
|
+
**Date:** {{DATE}}
|
|
69
69
|
**Status:** Accepted
|
|
70
70
|
|
|
71
71
|
### Context
|