@polymorphism-tech/morph-spec 2.4.0 → 3.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 +158 -26
- package/LICENSE +72 -72
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +8 -0
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-deploy.md +529 -0
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -227
- package/content/.claude/commands/morph-troubleshoot.md +122 -122
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/infra/azure-deploy-specialist.md +699 -0
- package/content/.claude/skills/level-0-meta/README.md +7 -0
- package/content/.claude/skills/{checklists → level-0-meta}/morph-checklist.md +117 -117
- package/content/.claude/skills/level-1-workflows/README.md +7 -0
- package/content/.claude/skills/{workflows → level-1-workflows}/morph-replicate.md +213 -213
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-clarify.md +131 -131
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-design.md +213 -205
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-setup.md +106 -92
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-tasks.md +164 -164
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-uiux.md +169 -138
- package/content/.claude/skills/level-2-domains/README.md +14 -0
- package/content/.claude/skills/{specialists → level-2-domains/quality}/testing-specialist.md +126 -126
- package/content/.claude/skills/level-3-technologies/README.md +7 -0
- package/content/.claude/skills/level-4-patterns/README.md +7 -0
- package/content/.claude/skills/specialists/prompt-engineer.md +189 -0
- package/content/.claude/skills/specialists/seo-growth-hacker.md +320 -0
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +742 -358
- package/content/.morph/config/config.template.json +33 -0
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/enforcement-pipeline.md +668 -0
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/scheduled-reports/decisions.md +158 -158
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -95
- package/content/.morph/examples/scheduled-reports/spec.md +267 -267
- package/content/.morph/examples/state-v3.json +188 -188
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +158 -0
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/hooks/task-completed.js +73 -0
- package/content/.morph/hooks/teammate-idle.js +68 -0
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -220
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-teams-workflow.md +474 -0
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/CONTEXT-FEATURE.md +276 -0
- package/content/.morph/templates/CONTEXT.md +170 -0
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/clarify-questions.md +159 -159
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -74
- package/content/.morph/templates/contracts/Entities.cs +25 -25
- package/content/.morph/templates/contracts/Queries.cs +74 -74
- package/content/.morph/templates/contracts/README.md +74 -74
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/azure-pipelines-deploy.yml +480 -0
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -426
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/templates.md +418 -418
- package/package.json +1 -1
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +83 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -193
- package/src/commands/create-story.js +351 -351
- package/src/commands/deploy.js +780 -0
- package/src/commands/detect-agents.js +34 -6
- package/src/commands/detect.js +104 -104
- package/src/commands/generate-context.js +40 -0
- package/src/commands/generate.js +149 -149
- package/src/commands/lint-fluent.js +352 -352
- package/src/commands/rollback-phase.js +185 -185
- package/src/commands/session-summary.js +291 -291
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/troubleshoot.js +222 -222
- package/src/commands/validate-blazor-state.js +210 -210
- package/src/commands/validate-blazor.js +156 -156
- package/src/commands/validate-css.js +84 -84
- package/src/commands/validate-phase.js +221 -221
- package/src/lib/blazor-concurrency-analyzer.js +288 -288
- package/src/lib/blazor-state-validator.js +291 -291
- package/src/lib/blazor-validator.js +374 -374
- package/src/lib/context-generator.js +513 -0
- package/src/lib/css-validator.js +352 -352
- package/src/lib/design-system-detector.js +187 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/design-system-scaffolder.js +299 -0
- package/src/lib/hook-executor.js +256 -0
- package/src/lib/learning-system.js +520 -520
- package/src/lib/mockup-generator.js +366 -366
- package/src/lib/spec-validator.js +258 -0
- package/src/lib/standards-context-injector.js +287 -0
- package/src/lib/team-orchestrator.js +322 -0
- package/src/lib/troubleshoot-grep.js +194 -194
- package/src/lib/troubleshoot-index.js +144 -144
- package/src/lib/ui-detector.js +350 -350
- package/src/lib/validation-runner.js +65 -13
- package/src/lib/validators/architecture-validator.js +387 -387
- package/src/lib/validators/design-system-validator.js +231 -0
- package/src/lib/validators/package-validator.js +360 -360
- package/src/lib/validators/ui-contrast-validator.js +422 -422
- package/src/utils/file-copier.js +9 -1
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- /package/content/.claude/skills/{checklists → level-0-meta}/code-review.md +0 -0
- /package/content/.claude/skills/{checklists → level-0-meta}/simulation-checklist.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/ai-agents}/ai-system-architect.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/architecture}/po-pm-advisor.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/architecture}/standards-architect.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/dotnet-senior.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/ef-modeler.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/hangfire-orchestrator.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/ms-agent-expert.md +0 -0
- /package/content/.claude/skills/{stacks/dotnet-blazor.md → level-2-domains/frontend/blazor-builder.md} +0 -0
- /package/content/.claude/skills/{stacks/dotnet-nextjs.md → level-2-domains/frontend/nextjs-expert.md} +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/frontend}/ui-ux-designer.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/infrastructure}/azure-architect.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/bicep-architect.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/container-specialist.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/devops-engineer.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/asaas-financial.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/azure-identity.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/clerk-auth.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/resend-email.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/quality}/code-analyzer.md +0 -0
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
// ==============================================================================
|
|
2
|
-
// MORPH-SPEC - Application Insights
|
|
3
|
-
// Azure Application Insights for monitoring and telemetry
|
|
4
|
-
// ==============================================================================
|
|
5
|
-
|
|
6
|
-
@description('Application Insights 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
|
-
@description('Application type')
|
|
19
|
-
@allowed(['web', 'other'])
|
|
20
|
-
param applicationType string = 'web'
|
|
21
|
-
|
|
22
|
-
@description('Retention in days')
|
|
23
|
-
@minValue(30)
|
|
24
|
-
@maxValue(730)
|
|
25
|
-
param retentionInDays int = 90
|
|
26
|
-
|
|
27
|
-
// ==============================================================================
|
|
28
|
-
// APPLICATION INSIGHTS
|
|
29
|
-
// ==============================================================================
|
|
30
|
-
|
|
31
|
-
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
|
|
32
|
-
name: name
|
|
33
|
-
location: location
|
|
34
|
-
tags: tags
|
|
35
|
-
kind: applicationType
|
|
36
|
-
properties: {
|
|
37
|
-
Application_Type: applicationType
|
|
38
|
-
WorkspaceResourceId: logAnalyticsWorkspaceId
|
|
39
|
-
IngestionMode: 'LogAnalytics'
|
|
40
|
-
publicNetworkAccessForIngestion: 'Enabled'
|
|
41
|
-
publicNetworkAccessForQuery: 'Enabled'
|
|
42
|
-
RetentionInDays: retentionInDays
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ==============================================================================
|
|
47
|
-
// OUTPUTS
|
|
48
|
-
// ==============================================================================
|
|
49
|
-
|
|
50
|
-
@description('Application Insights ID')
|
|
51
|
-
output id string = appInsights.id
|
|
52
|
-
|
|
53
|
-
@description('Application Insights name')
|
|
54
|
-
output name string = appInsights.name
|
|
55
|
-
|
|
56
|
-
@description('Instrumentation Key')
|
|
57
|
-
output instrumentationKey string = appInsights.properties.InstrumentationKey
|
|
58
|
-
|
|
59
|
-
@description('Connection String')
|
|
60
|
-
output connectionString string = appInsights.properties.ConnectionString
|
|
61
|
-
|
|
62
|
-
@description('App ID')
|
|
63
|
-
output appId string = appInsights.properties.AppId
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// MORPH-SPEC - Application Insights
|
|
3
|
+
// Azure Application Insights for monitoring and telemetry
|
|
4
|
+
// ==============================================================================
|
|
5
|
+
|
|
6
|
+
@description('Application Insights 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
|
+
@description('Application type')
|
|
19
|
+
@allowed(['web', 'other'])
|
|
20
|
+
param applicationType string = 'web'
|
|
21
|
+
|
|
22
|
+
@description('Retention in days')
|
|
23
|
+
@minValue(30)
|
|
24
|
+
@maxValue(730)
|
|
25
|
+
param retentionInDays int = 90
|
|
26
|
+
|
|
27
|
+
// ==============================================================================
|
|
28
|
+
// APPLICATION INSIGHTS
|
|
29
|
+
// ==============================================================================
|
|
30
|
+
|
|
31
|
+
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
|
|
32
|
+
name: name
|
|
33
|
+
location: location
|
|
34
|
+
tags: tags
|
|
35
|
+
kind: applicationType
|
|
36
|
+
properties: {
|
|
37
|
+
Application_Type: applicationType
|
|
38
|
+
WorkspaceResourceId: logAnalyticsWorkspaceId
|
|
39
|
+
IngestionMode: 'LogAnalytics'
|
|
40
|
+
publicNetworkAccessForIngestion: 'Enabled'
|
|
41
|
+
publicNetworkAccessForQuery: 'Enabled'
|
|
42
|
+
RetentionInDays: retentionInDays
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ==============================================================================
|
|
47
|
+
// OUTPUTS
|
|
48
|
+
// ==============================================================================
|
|
49
|
+
|
|
50
|
+
@description('Application Insights ID')
|
|
51
|
+
output id string = appInsights.id
|
|
52
|
+
|
|
53
|
+
@description('Application Insights name')
|
|
54
|
+
output name string = appInsights.name
|
|
55
|
+
|
|
56
|
+
@description('Instrumentation Key')
|
|
57
|
+
output instrumentationKey string = appInsights.properties.InstrumentationKey
|
|
58
|
+
|
|
59
|
+
@description('Connection String')
|
|
60
|
+
output connectionString string = appInsights.properties.ConnectionString
|
|
61
|
+
|
|
62
|
+
@description('App ID')
|
|
63
|
+
output appId string = appInsights.properties.AppId
|
|
@@ -1,164 +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}' : ''
|
|
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}' : ''
|