@polymorphism-tech/morph-spec 4.7.0 → 4.7.2

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 (232) hide show
  1. package/.morph/.morphversion +5 -0
  2. package/.morph/analytics/threads-log.jsonl +5 -0
  3. package/.morph/config/config.json +8 -0
  4. package/.morph/framework/agents.json +1815 -0
  5. package/.morph/framework/hooks/README.md +205 -0
  6. package/.morph/framework/hooks/claude-code/notification/approval-reminder.js +54 -0
  7. package/.morph/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
  8. package/.morph/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
  9. package/.morph/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
  10. package/.morph/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
  11. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
  12. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
  13. package/.morph/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
  14. package/.morph/framework/hooks/claude-code/statusline.py +538 -0
  15. package/.morph/framework/hooks/claude-code/statusline.sh +7 -0
  16. package/.morph/framework/hooks/claude-code/stop/validate-completion.js +88 -0
  17. package/.morph/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
  18. package/.morph/framework/hooks/git/commit-msg/conventional-commits.sh +33 -0
  19. package/.morph/framework/hooks/git/pre-commit/agents.sh +25 -0
  20. package/.morph/framework/hooks/git/pre-commit/orchestrator.sh +64 -0
  21. package/.morph/framework/hooks/git/pre-commit/specs.sh +50 -0
  22. package/.morph/framework/hooks/git/pre-push/run-tests.sh +44 -0
  23. package/.morph/framework/hooks/shared/hook-response.js +45 -0
  24. package/.morph/framework/hooks/shared/phase-utils.js +129 -0
  25. package/.morph/framework/hooks/shared/state-reader.js +138 -0
  26. package/.morph/framework/hooks/shared/stdin-reader.js +26 -0
  27. package/.morph/framework/standards/STANDARDS.json +933 -0
  28. package/.morph/framework/standards/ai-agents/blazor-ui.md +364 -0
  29. package/.morph/framework/standards/ai-agents/production.md +415 -0
  30. package/.morph/framework/standards/ai-agents/setup.md +418 -0
  31. package/.morph/framework/standards/ai-agents/team-orchestration.md +479 -0
  32. package/.morph/framework/standards/ai-agents/workflows.md +354 -0
  33. package/.morph/framework/standards/architecture/ddd/aggregates.md +120 -0
  34. package/.morph/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
  35. package/.morph/framework/standards/architecture/ddd/complexity-levels.md +108 -0
  36. package/.morph/framework/standards/architecture/ddd/entities.md +99 -0
  37. package/.morph/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
  38. package/.morph/framework/standards/architecture/ddd/value-objects.md +124 -0
  39. package/.morph/framework/standards/backend/api/minimal-api.md +494 -0
  40. package/.morph/framework/standards/backend/api/rest.md +492 -0
  41. package/.morph/framework/standards/backend/api/validation.md +88 -0
  42. package/.morph/framework/standards/backend/authentication/passkeys.md +428 -0
  43. package/.morph/framework/standards/backend/database/ef-core.md +199 -0
  44. package/.morph/framework/standards/backend/database/migrations.md +393 -0
  45. package/.morph/framework/standards/backend/database/postgresql/database.md +352 -0
  46. package/.morph/framework/standards/backend/database/repository-patterns.md +528 -0
  47. package/.morph/framework/standards/backend/database/vector-search-rag.md +541 -0
  48. package/.morph/framework/standards/backend/dotnet/async.md +366 -0
  49. package/.morph/framework/standards/backend/dotnet/core.md +117 -0
  50. package/.morph/framework/standards/backend/dotnet/di.md +439 -0
  51. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +92 -0
  52. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +216 -0
  53. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +290 -0
  54. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +350 -0
  55. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +385 -0
  56. package/.morph/framework/standards/context/analytics.md +96 -0
  57. package/.morph/framework/standards/context/bundles.md +110 -0
  58. package/.morph/framework/standards/context/priming.md +78 -0
  59. package/.morph/framework/standards/core/architecture.md +185 -0
  60. package/.morph/framework/standards/core/coding.md +214 -0
  61. package/.morph/framework/standards/core/git-branching-strategy.md +403 -0
  62. package/.morph/framework/standards/core/git.md +185 -0
  63. package/.morph/framework/standards/core/testing.md +295 -0
  64. package/.morph/framework/standards/data/nosql/blob-storage.md +102 -0
  65. package/.morph/framework/standards/data/nosql/cache/redis.md +97 -0
  66. package/.morph/framework/standards/data/nosql/cosmos-db.md +118 -0
  67. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +121 -0
  68. package/.morph/framework/standards/data/vector-search/rag-chunking.md +104 -0
  69. package/.morph/framework/standards/frontend/blazor/design-checklist.md +222 -0
  70. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +595 -0
  71. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +137 -0
  72. package/.morph/framework/standards/frontend/blazor/html-conversion.md +184 -0
  73. package/.morph/framework/standards/frontend/blazor/lifecycle.md +195 -0
  74. package/.morph/framework/standards/frontend/blazor/pitfalls.md +198 -0
  75. package/.morph/framework/standards/frontend/blazor/state.md +191 -0
  76. package/.morph/framework/standards/frontend/design-system/animations.md +151 -0
  77. package/.morph/framework/standards/frontend/design-system/naming.md +64 -0
  78. package/.morph/framework/standards/frontend/nextjs/app-router.md +123 -0
  79. package/.morph/framework/standards/frontend/nextjs/components.md +132 -0
  80. package/.morph/framework/standards/frontend/nextjs/data-fetching.md +126 -0
  81. package/.morph/framework/standards/frontend/nextjs/forms.md +128 -0
  82. package/.morph/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
  83. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +215 -0
  84. package/.morph/framework/standards/frontend/nextjs/project-structure.md +102 -0
  85. package/.morph/framework/standards/frontend/nextjs/state-management.md +72 -0
  86. package/.morph/framework/standards/frontend/nextjs/testing.md +111 -0
  87. package/.morph/framework/standards/infrastructure/azure/azure.md +624 -0
  88. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +422 -0
  89. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +516 -0
  90. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +520 -0
  91. package/.morph/framework/standards/infrastructure/azure/services/functions.md +486 -0
  92. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +459 -0
  93. package/.morph/framework/standards/infrastructure/azure/services/storage.md +407 -0
  94. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -0
  95. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +252 -0
  96. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +176 -0
  97. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +169 -0
  98. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +184 -0
  99. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +153 -0
  100. package/.morph/framework/standards/integration/api/graphql.md +91 -0
  101. package/.morph/framework/standards/integration/api/grpc.md +114 -0
  102. package/.morph/framework/standards/integration/api/rest-design.md +95 -0
  103. package/.morph/framework/standards/integration/event-driven/cqrs.md +101 -0
  104. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +124 -0
  105. package/.morph/framework/standards/integration/event-driven/service-bus.md +95 -0
  106. package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
  107. package/.morph/framework/standards/observability/logging.md +131 -0
  108. package/.morph/framework/standards/observability/metrics.md +121 -0
  109. package/.morph/framework/standards/observability/monitoring.md +114 -0
  110. package/.morph/framework/standards/observability/tracing.md +132 -0
  111. package/.morph/framework/standards/workflows/parallel-execution.md +112 -0
  112. package/.morph/framework/standards/workflows/thread-management.md +113 -0
  113. package/.morph/framework/templates/.idea/morph-templates.xml +92 -0
  114. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  115. package/.morph/framework/templates/IDE-SNIPPETS.md +266 -0
  116. package/.morph/framework/templates/README.md +814 -0
  117. package/.morph/framework/templates/REGISTRY.json +1888 -0
  118. package/.morph/framework/templates/code/dotnet/backend/repository.cs +141 -0
  119. package/.morph/framework/templates/code/dotnet/backend/service.cs +139 -0
  120. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +74 -0
  121. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +25 -0
  122. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +74 -0
  123. package/.morph/framework/templates/code/dotnet/contracts/README.md +74 -0
  124. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -0
  125. package/.morph/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
  126. package/.morph/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
  127. package/.morph/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
  128. package/.morph/framework/templates/code/dotnet/database/migration.cs +83 -0
  129. package/.morph/framework/templates/code/dotnet/frontend/component.razor +239 -0
  130. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +163 -0
  131. package/.morph/framework/templates/code/dotnet/jobs/job.cs +171 -0
  132. package/.morph/framework/templates/code/dotnet/test.cs +239 -0
  133. package/.morph/framework/templates/code/sql/rls-policy.sql +57 -0
  134. package/.morph/framework/templates/code/sql/supabase-migration.sql +100 -0
  135. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +113 -0
  136. package/.morph/framework/templates/code/typescript/contracts.ts +168 -0
  137. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +276 -0
  138. package/.morph/framework/templates/context/CONTEXT.md +181 -0
  139. package/.morph/framework/templates/docs/clarifications.md +253 -0
  140. package/.morph/framework/templates/docs/onboarding.md +123 -0
  141. package/.morph/framework/templates/docs/proposal.md +182 -0
  142. package/.morph/framework/templates/docs/schema-analysis.md +119 -0
  143. package/.morph/framework/templates/docs/spec.md +198 -0
  144. package/.morph/framework/templates/docs/ui-components.md +124 -0
  145. package/.morph/framework/templates/docs/ui-design-system.md +76 -0
  146. package/.morph/framework/templates/docs/ui-flows.md +167 -0
  147. package/.morph/framework/templates/docs/ui-mockups.md +98 -0
  148. package/.morph/framework/templates/docs/user-stories.md +34 -0
  149. package/.morph/framework/templates/examples/design-system-examples.md +357 -0
  150. package/.morph/framework/templates/examples/spec-examples.md +90 -0
  151. package/.morph/framework/templates/feature/decisions.md +187 -0
  152. package/.morph/framework/templates/feature/recap.md +146 -0
  153. package/.morph/framework/templates/feature/tasks.md +199 -0
  154. package/.morph/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
  155. package/.morph/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
  156. package/.morph/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
  157. package/.morph/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
  158. package/.morph/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
  159. package/.morph/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
  160. package/.morph/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
  161. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +82 -0
  162. package/.morph/framework/templates/infrastructure/azure/README.md +286 -0
  163. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +63 -0
  164. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +164 -0
  165. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +49 -0
  166. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +156 -0
  167. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +426 -0
  168. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +229 -0
  169. package/.morph/framework/templates/infrastructure/azure/deploy.sh +208 -0
  170. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +91 -0
  171. package/.morph/framework/templates/infrastructure/azure/main.bicep +189 -0
  172. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +29 -0
  173. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +29 -0
  174. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +29 -0
  175. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +103 -0
  176. package/.morph/framework/templates/infrastructure/azure/storage.bicep +106 -0
  177. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +58 -0
  178. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -0
  179. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -0
  180. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -0
  181. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +54 -0
  182. package/.morph/framework/templates/infrastructure/github/README.md +593 -0
  183. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +22 -0
  184. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -0
  185. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -0
  186. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +61 -0
  187. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +31 -0
  188. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -0
  189. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -0
  190. package/.morph/framework/templates/integrations/asaas-client.cs +387 -0
  191. package/.morph/framework/templates/integrations/asaas-webhook.cs +351 -0
  192. package/.morph/framework/templates/integrations/azure-identity-config.cs +288 -0
  193. package/.morph/framework/templates/integrations/clerk-config.cs +258 -0
  194. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -0
  195. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -0
  196. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +78 -0
  197. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +97 -0
  198. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +36 -0
  199. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +113 -0
  200. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -0
  201. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -0
  202. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +126 -0
  203. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +43 -0
  204. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -0
  205. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -0
  206. package/.morph/framework/templates/project-structure/dotnet-ddd.md +70 -0
  207. package/.morph/framework/templates/saas/subscription.cs +347 -0
  208. package/.morph/framework/templates/saas/tenant.cs +338 -0
  209. package/.morph/framework/templates/state.template.json +17 -0
  210. package/.morph/framework/templates/ui/FluentDesignTheme.cs +149 -0
  211. package/.morph/framework/templates/ui/MudTheme.cs +281 -0
  212. package/.morph/framework/templates/ui/design-system.css +226 -0
  213. package/.morph/logs/tool-failures.log +17 -0
  214. package/.morph/memory/pre-compact-2026-02-24T17-43-30-049Z.json +16 -0
  215. package/.morph/plans/eager-watching-bunny.md +105 -0
  216. package/.morph/plans/temporal-seeking-nebula.md +45 -0
  217. package/.morph/state.json +48 -0
  218. package/CLAUDE.md +1 -1
  219. package/README.md +119 -99
  220. package/bin/morph-spec.js +0 -9
  221. package/framework/CLAUDE.md +1 -1
  222. package/framework/hooks/README.md +10 -6
  223. package/framework/hooks/claude-code/notification/approval-reminder.js +2 -0
  224. package/framework/hooks/claude-code/post-tool-use/dispatch.js +1 -1
  225. package/framework/hooks/claude-code/stop/validate-completion.js +1 -1
  226. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +1 -1
  227. package/package.json +1 -1
  228. package/src/commands/project/init.js +15 -42
  229. package/src/commands/project/update.js +22 -37
  230. package/src/lib/installers/mcp-installer.js +18 -3
  231. package/src/utils/hooks-installer.js +5 -15
  232. package/src/commands/project/detect.js +0 -114
@@ -0,0 +1,164 @@
1
+ // ==============================================================================
2
+ // MORPH-SPEC - App Service
3
+ // Azure App Service with Free F1 tier support
4
+ // ==============================================================================
5
+
6
+ @description('App Service name')
7
+ param name string
8
+
9
+ @description('Location')
10
+ param location string
11
+
12
+ @description('Tags')
13
+ param tags object = {}
14
+
15
+ @description('App Service Plan SKU (F1, B1, S1, P1v2)')
16
+ @allowed(['F1', 'B1', 'S1', 'P1v2', 'P2v2'])
17
+ param sku string = 'F1'
18
+
19
+ @description('App Insights connection string')
20
+ param appInsightsConnectionString string = ''
21
+
22
+ @description('.NET version')
23
+ @allowed(['v6.0', 'v7.0', 'v8.0'])
24
+ param dotnetVersion string = 'v8.0'
25
+
26
+ @description('Always On (not available on Free tier)')
27
+ param alwaysOn bool = false
28
+
29
+ @description('Environment variables')
30
+ param envVars object = {}
31
+
32
+ // ==============================================================================
33
+ // VARIABLES
34
+ // ==============================================================================
35
+
36
+ var skuTiers = {
37
+ F1: 'Free'
38
+ B1: 'Basic'
39
+ S1: 'Standard'
40
+ P1v2: 'PremiumV2'
41
+ P2v2: 'PremiumV2'
42
+ }
43
+
44
+ var planName = 'plan-${name}'
45
+
46
+ // Merge default env vars with custom ones
47
+ var defaultEnvVars = {
48
+ ASPNETCORE_ENVIRONMENT: 'Production'
49
+ APPLICATIONINSIGHTS_CONNECTION_STRING: appInsightsConnectionString
50
+ }
51
+
52
+ var mergedEnvVars = union(defaultEnvVars, envVars)
53
+
54
+ // ==============================================================================
55
+ // APP SERVICE PLAN
56
+ // ==============================================================================
57
+
58
+ resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = {
59
+ name: planName
60
+ location: location
61
+ tags: tags
62
+ sku: {
63
+ name: sku
64
+ tier: skuTiers[sku]
65
+ }
66
+ kind: 'linux'
67
+ properties: {
68
+ reserved: true // Required for Linux
69
+ }
70
+ }
71
+
72
+ // ==============================================================================
73
+ // APP SERVICE
74
+ // ==============================================================================
75
+
76
+ resource appService 'Microsoft.Web/sites@2022-09-01' = {
77
+ name: name
78
+ location: location
79
+ tags: tags
80
+ kind: 'app,linux'
81
+ identity: {
82
+ type: 'SystemAssigned'
83
+ }
84
+ properties: {
85
+ serverFarmId: appServicePlan.id
86
+ httpsOnly: true
87
+ siteConfig: {
88
+ linuxFxVersion: 'DOTNETCORE|${dotnetVersion}'
89
+ alwaysOn: alwaysOn
90
+ minTlsVersion: '1.2'
91
+ ftpsState: 'Disabled'
92
+ http20Enabled: true
93
+ healthCheckPath: '/health'
94
+ appSettings: [for key in objectKeys(mergedEnvVars): {
95
+ name: key
96
+ value: mergedEnvVars[key]
97
+ }]
98
+ cors: {
99
+ allowedOrigins: [
100
+ 'https://portal.azure.com'
101
+ ]
102
+ supportCredentials: false
103
+ }
104
+ }
105
+ clientAffinityEnabled: false // Recommended for stateless apps
106
+ }
107
+ }
108
+
109
+ // ==============================================================================
110
+ // DEPLOYMENT SLOT (Only for non-Free tiers)
111
+ // ==============================================================================
112
+
113
+ resource stagingSlot 'Microsoft.Web/sites/slots@2022-09-01' = if (sku != 'F1') {
114
+ name: 'staging'
115
+ parent: appService
116
+ location: location
117
+ tags: tags
118
+ kind: 'app,linux'
119
+ identity: {
120
+ type: 'SystemAssigned'
121
+ }
122
+ properties: {
123
+ serverFarmId: appServicePlan.id
124
+ httpsOnly: true
125
+ siteConfig: {
126
+ linuxFxVersion: 'DOTNETCORE|${dotnetVersion}'
127
+ alwaysOn: alwaysOn
128
+ minTlsVersion: '1.2'
129
+ ftpsState: 'Disabled'
130
+ http20Enabled: true
131
+ healthCheckPath: '/health'
132
+ appSettings: [for key in objectKeys(mergedEnvVars): {
133
+ name: key
134
+ value: mergedEnvVars[key]
135
+ }]
136
+ }
137
+ clientAffinityEnabled: false
138
+ }
139
+ }
140
+
141
+ // ==============================================================================
142
+ // OUTPUTS
143
+ // ==============================================================================
144
+
145
+ @description('App Service ID')
146
+ output id string = appService.id
147
+
148
+ @description('App Service name')
149
+ output name string = appService.name
150
+
151
+ @description('App Service URL')
152
+ output url string = 'https://${appService.properties.defaultHostName}'
153
+
154
+ @description('App Service default hostname')
155
+ output defaultHostName string = appService.properties.defaultHostName
156
+
157
+ @description('App Service Plan ID')
158
+ output planId string = appServicePlan.id
159
+
160
+ @description('App Service Managed Identity Principal ID')
161
+ output principalId string = appService.identity.principalId
162
+
163
+ @description('Staging slot URL (if available)')
164
+ output stagingUrl string = sku != 'F1' ? 'https://${stagingSlot.properties.defaultHostName}' : ''
@@ -0,0 +1,49 @@
1
+ // ==============================================================================
2
+ // MORPH-SPEC - Container Apps Environment
3
+ // Azure Container Apps managed environment
4
+ // ==============================================================================
5
+
6
+ @description('Environment name')
7
+ param name string
8
+
9
+ @description('Location')
10
+ param location string
11
+
12
+ @description('Tags')
13
+ param tags object = {}
14
+
15
+ @description('Log Analytics Workspace ID')
16
+ param logAnalyticsWorkspaceId string
17
+
18
+ // ==============================================================================
19
+ // CONTAINER APPS ENVIRONMENT
20
+ // ==============================================================================
21
+
22
+ resource containerAppEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
23
+ name: name
24
+ location: location
25
+ tags: tags
26
+ properties: {
27
+ appLogsConfiguration: {
28
+ destination: 'log-analytics'
29
+ logAnalyticsConfiguration: {
30
+ customerId: reference(logAnalyticsWorkspaceId, '2022-10-01').customerId
31
+ sharedKey: listKeys(logAnalyticsWorkspaceId, '2022-10-01').primarySharedKey
32
+ }
33
+ }
34
+ zoneRedundant: false
35
+ }
36
+ }
37
+
38
+ // ==============================================================================
39
+ // OUTPUTS
40
+ // ==============================================================================
41
+
42
+ @description('Container Apps Environment ID')
43
+ output id string = containerAppEnv.id
44
+
45
+ @description('Container Apps Environment name')
46
+ output name string = containerAppEnv.name
47
+
48
+ @description('Default domain')
49
+ output defaultDomain string = containerAppEnv.properties.defaultDomain
@@ -0,0 +1,156 @@
1
+ // ==============================================================================
2
+ // MORPH-SPEC - Container App
3
+ // Azure Container Apps with ingress and auto-scaling
4
+ // ==============================================================================
5
+
6
+ @description('App name')
7
+ param name string
8
+
9
+ @description('Location')
10
+ param location string
11
+
12
+ @description('Tags')
13
+ param tags object = {}
14
+
15
+ @description('Container App Environment ID')
16
+ param environmentId string
17
+
18
+ @description('Container image')
19
+ param containerImage string
20
+
21
+ @description('App Insights connection string')
22
+ param appInsightsConnectionString string = ''
23
+
24
+ @description('CPU cores (0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0)')
25
+ param cpu string = '0.25'
26
+
27
+ @description('Memory (0.5Gi, 1Gi, 1.5Gi, 2Gi, 3Gi, 4Gi)')
28
+ param memory string = '0.5Gi'
29
+
30
+ @description('Minimum replicas (0 = scale to zero)')
31
+ param minReplicas int = 0
32
+
33
+ @description('Maximum replicas')
34
+ param maxReplicas int = 3
35
+
36
+ @description('Target port')
37
+ param targetPort int = 8080
38
+
39
+ @description('Environment variables')
40
+ param envVars array = []
41
+
42
+ // ==============================================================================
43
+ // CONTAINER APP
44
+ // ==============================================================================
45
+
46
+ var secrets = appInsightsConnectionString != '' ? [
47
+ {
48
+ name: 'appinsights-connection-string'
49
+ value: appInsightsConnectionString
50
+ }
51
+ ] : []
52
+
53
+ var defaultEnvVars = appInsightsConnectionString != '' ? [
54
+ {
55
+ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
56
+ secretRef: 'appinsights-connection-string'
57
+ }
58
+ {
59
+ name: 'ASPNETCORE_ENVIRONMENT'
60
+ value: 'Production'
61
+ }
62
+ ] : [
63
+ {
64
+ name: 'ASPNETCORE_ENVIRONMENT'
65
+ value: 'Production'
66
+ }
67
+ ]
68
+
69
+ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
70
+ name: name
71
+ location: location
72
+ tags: tags
73
+ properties: {
74
+ managedEnvironmentId: environmentId
75
+ configuration: {
76
+ ingress: {
77
+ external: true
78
+ targetPort: targetPort
79
+ transport: 'http'
80
+ allowInsecure: false
81
+ traffic: [
82
+ {
83
+ latestRevision: true
84
+ weight: 100
85
+ }
86
+ ]
87
+ }
88
+ secrets: secrets
89
+ }
90
+ template: {
91
+ containers: [
92
+ {
93
+ name: name
94
+ image: containerImage
95
+ resources: {
96
+ cpu: json(cpu)
97
+ memory: memory
98
+ }
99
+ env: concat(defaultEnvVars, envVars)
100
+ probes: [
101
+ {
102
+ type: 'Liveness'
103
+ httpGet: {
104
+ path: '/health'
105
+ port: targetPort
106
+ }
107
+ initialDelaySeconds: 10
108
+ periodSeconds: 30
109
+ failureThreshold: 3
110
+ }
111
+ {
112
+ type: 'Readiness'
113
+ httpGet: {
114
+ path: '/health/ready'
115
+ port: targetPort
116
+ }
117
+ initialDelaySeconds: 5
118
+ periodSeconds: 10
119
+ failureThreshold: 3
120
+ }
121
+ ]
122
+ }
123
+ ]
124
+ scale: {
125
+ minReplicas: minReplicas
126
+ maxReplicas: maxReplicas
127
+ rules: [
128
+ {
129
+ name: 'http-scale'
130
+ http: {
131
+ metadata: {
132
+ concurrentRequests: '100'
133
+ }
134
+ }
135
+ }
136
+ ]
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ // ==============================================================================
143
+ // OUTPUTS
144
+ // ==============================================================================
145
+
146
+ @description('Container App ID')
147
+ output id string = containerApp.id
148
+
149
+ @description('Container App name')
150
+ output name string = containerApp.name
151
+
152
+ @description('Container App URL')
153
+ output url string = 'https://${containerApp.properties.configuration.ingress.fqdn}'
154
+
155
+ @description('Container App FQDN')
156
+ output fqdn string = containerApp.properties.configuration.ingress.fqdn