Skip to content

02 — Infrastructure and Environments

PRD Document · Savoy Signature Hotels — Multi-Site Headless Platform
Version: 1.0 · Date: 2026-03-04
Related docs: 01_General_Architecture.md, A05_Environment_Config.md


This document specifies the infrastructure services, environment topology, CI/CD pipelines, monitoring strategy, and operational procedures for the Savoy Signature multi-site platform.


All services are hosted on Microsoft Azure with Cloudflare as the edge/CDN layer.

Azure — Resource Group: rg-savoy-prod

Cloudflare

Monitoring

Networking

Data

Compute

DNS Management

WAF + Rate Limiting

Edge Cache

App Service: Next.js

App Service: Umbraco

SQL Database

Blob Storage

Virtual Network

Private Endpoints

Application Insights

Log Analytics Workspace

ServiceSKU / TierPurposeNotes
App Service (Next.js)P1v3 or P2v3Next.js SSR applicationAuto-scale based on CPU/memory; Node.js 20.9+ LTS
App Service (Umbraco)P1v3 or P2v3Umbraco 17 CMS (headless).NET 10 LTS runtime; always-on enabled
Azure SQL DatabaseStandard S2 (50 DTU) or General PurposeUmbraco content databaseGeo-redundant backup; auto-tuning
Blob StorageStandard GRS / Hot tierMedia files (images, PDFs, videos)CDN-fronted; lifecycle policies for unused media
Application InsightsPay-as-you-goAPM for both appsDistributed tracing, custom metrics
Log AnalyticsPay-as-you-goCentralized loggingKQL queries, alerts, dashboards
Key VaultStandardSecrets managementConnection strings, API keys, certificates
Virtual NetworkNetwork isolationPrivate endpoints for SQL and Blob

The platform uses 4 environments following a promotion pipeline:

Note: DEV and STAGE are internal WYcreative environments hosted under wycreative.com. STAGE may be shared with the client team during initial phases for testing and validation.

EnvironmentPurposeDomain PatternAzure Resource GroupCloudflareAuto-deploy
DEVActive development, feature testingsavoy-dev-*.wycreative.comrg-savoy-devEnabled (proxied, performance monitoring)PR from developdeploy/dev (CI + 1 approver)
STAGEQA, client review, UATsavoy.stage-*.wycreative.comrg-savoy-stageEnabled (test cache behavior)On PR merge to staging
QAPre-production validation, performance testingqa-*.savoysignature.comrg-savoy-qaEnabled (production-like)Manual promotion
PRODLive production sites*.savoysignature.com / hotelnext.ptrg-savoy-prodEnabled (full caching)Manual promotion with approval
SiteDEV DomainSTAGE Domain
Savoy Signaturesavoy-dev-signature.wycreative.comsavoy-stage-signature.wycreative.com
Savoy Palacesavoy-dev-palace.wycreative.comsavoy-stage-palace.wycreative.com
Royal Savoysavoy-dev-royal.wycreative.comsavoy-stage-royal.wycreative.com
Saccharumsavoy-dev-saccharum.wycreative.comsavoy-stage-saccharum.wycreative.com
The Reservesavoy-dev-reserve.wycreative.comsavoy-stage-reserve.wycreative.com
Calheta Beachsavoy-dev-calheta.wycreative.comsavoy-stage-calheta.wycreative.com
Gardenssavoy-dev-gardens.wycreative.comsavoy-stage-gardens.wycreative.com
Hotel Nextsavoy-dev-next.wycreative.comsavoy-stage-next.wycreative.com
Umbraco CMSsavoy-dev-cms.wycreative.comsavoy-stage-cms.wycreative.com

Note: DEV domains use 1-level subdomains (savoy-dev-* not savoy.dev-*) because Cloudflare Universal SSL only covers *.wycreative.com (one level). All DEV domains are proxied via Cloudflare for performance monitoring (Observatory + GraphQL Analytics).

PR to staging branch

Manual promotion

Approval gate

DEV Environment

STAGE Environment

QA Environment

PROD Environment

VariableDEVSTAGEQAPROD
UMBRACO_API_URLhttps://savoy-dev-cms.wycreative.comhttps://savoy.stage-cms.wycreative.comhttps://qa-cms.savoysignature.comhttps://cms.savoysignature.com
CLOUDFLARE_ZONE_IDZone IDZone IDZone IDZone ID
CLOUDFLARE_API_TOKENTokenTokenTokenToken
GATE_ENABLEDtruetruetruefalse
GATE_SECRETSecretSecretSecret
GATE_COOKIE_DOMAIN.wycreative.com.wycreative.com
NODE_ENVdevelopmentstagingproductionproduction
REVALIDATE_SECRETdev-secretstage-secretqa-secretprod-secret
NEXT_PUBLIC_GA_IDG-XXXXXXXXXX
APPINSIGHTS_KEYKeyKeyKeyKey

Full configuration reference in A05_Environment_Config.md


main (PROD)
├── staging (STAGE / QA)
│ └── develop (DEV)
│ ├── feature/SAVOY-123-hero-module
│ ├── feature/SAVOY-456-booking-bar
│ └── fix/SAVOY-789-cache-headers
BranchEnvironmentTriggerProtection
feature/*, fix/*Local / Preview
developIntegrationPR merge (no CI, merge freely)
deploy/devDEVPR from develop1 approval, CI pass, squash merge
stagingSTAGE → QAPR merge from develop2 approvals, CI pass
mainPRODPR merge from staging2 approvals, QA sign-off, CI pass

The pipeline includes a unique AI QA Agent step between CI and CD. This agent runs on a local Mac using openClaw (Agentic AI) and performs comprehensive automated quality assurance before any deployment.

CD — On Merge (if AI QA passes)

AI QA — openClaw Agent on Local Mac

CI — On Every PR

All OK

All OK

All OK

Lint + Type Check

Unit Tests

Build Next.js

Build Storybook

Pick up PR

Performance Tests

Accessibility Audit

Visual Regression (Pixel Perfect)

UI/UX Validation

Post Comments (PR + Zoho Project)

Deploy Next.js

Deploy Umbraco

Deploy Storybook

Purge Cloudflare

Smoke Tests

The openClaw AI QA Agent runs on a dedicated local Mac and acts as an automated quality gate between CI and CD:

StepDescriptionTools / Metrics
PR PickupMonitors the Git repository for new PRs targeting develop, staging, or mainGitHub/Azure DevOps API
Performance TestsRuns Lighthouse CI on all changed pages, checks Core Web Vitals thresholdsLighthouse CI (LCP < 2.5s, FID < 100ms, CLS < 0.1)
Accessibility AuditFull WCAG 2.1 AA audit on all changed components and pagesaxe-core, Playwright accessibility testing
Visual RegressionPixel-perfect comparison against Figma designs and baseline screenshotsChromatic / Percy / custom screenshot diffing
UI/UX ValidationValidates responsive behavior, interaction states, navigation flowsPlaywright E2E tests across viewports
Comment & ReportPosts detailed review comments on the PR (GitHub/Azure DevOps) and updates the corresponding task in Zoho ProjectAPI integrations
Gate DecisionIf all checks pass → PR is approved for merge → CD proceeds. If any check fails → PR is blocked with detailed feedbackAutomated approval/rejection

Important: The AI QA Agent does NOT replace human code review. It runs in parallel with human review, providing automated quality assurance feedback. The PR still requires human approval per branch protection rules.

Full testing strategy and AI QA Agent specification in 18_QA_and_Testing.md

# Pseudo-pipeline definition (Azure DevOps / GitHub Actions)
name: CI Pipeline
on:
pull_request:
branches: [develop, staging, main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
test:
runs-on: ubuntu-latest
needs: lint
steps:
- run: pnpm test --coverage
- run: pnpm test:e2e # Playwright
build:
runs-on: ubuntu-latest
needs: test
steps:
- run: pnpm build
- run: pnpm build:storybook
# AI QA Agent (openClaw) picks up the PR after CI passes
# Runs on local Mac — not part of the cloud CI/CD pipeline
# See section 4.3 for details
deploy:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && ai_qa_approved == true
steps:
- run: # Deploy to target environment
- run: # Purge Cloudflare cache (STAGE/PROD only)
- run: # Run smoke tests

Umbraco deployments are separate from frontend deployments:

AspectApproach
Schema ChangesUmbraco Deploy or manual migration scripts
ContentNot deployed — lives in database, managed by editors
Code Changes.NET build + deploy to App Service via CI/CD
Database MigrationsEF Core migrations, run automatically on startup

ToolPurposeScope
Azure Application InsightsAPM, request tracing, exceptions, custom metricsNext.js + Umbraco
Azure Log AnalyticsCentralized log aggregation, KQL queriesAll Azure resources
Cloudflare AnalyticsEdge traffic, cache hit rate, WAF eventsCDN layer
Azure Monitor AlertsProactive alerting on thresholdsAll services
Uptime Robot / Azure Availability TestsUptime monitoring for all 8 sitesExternal
MetricThresholdAlert
Response Time (P95)> 2sWarning
Response Time (P95)> 5sCritical
Error Rate (5xx)> 1%Critical
Cache Hit Rate< 80%Warning
CPU Usage (App Service)> 85% for 5minWarning
Memory Usage> 90%Critical
SQL DTU Usage> 80%Warning
Blob Storage Size> 80% capacityWarning
SSL Certificate Expiry< 30 daysWarning
LayerLog DestinationRetention
Next.jsApplication Insights + stdout90 days
UmbracoApplication Insights + Umbraco logs90 days
CloudflareCloudflare Logs (Pro — via Logpush or API)30 days
Azure SQLAzure Diagnostics30 days
CI/CDPipeline logs90 days

ComponentStrategy
Next.jsAzure App Service auto-scale: min 2, max 6 instances based on CPU > 70%
UmbracoSingle instance (headless API, low traffic — most requests served from edge cache)
SQLElastic pool or scale up DTUs as needed
ScenarioAction
Sustained CPU > 85%Upgrade App Service plan tier
Frequent SQL timeoutsUpgrade SQL tier or add read replica
Blob throughput limitsEnable CDN for blob, premium tier

AspectStrategyRTORPO
DatabaseAzure SQL geo-replication + point-in-time restore1h5min
Blob StorageGRS (Geo-Redundant Storage) — automatic failover1h0
App ServicesDeploy from CI/CD to secondary region2h0 (code in Git)
CloudflareGlobal anycast — inherent redundancy
ConfigurationKey Vault with backup enabled1h0
ResourceFrequencyRetention
Azure SQLContinuous (PITR)35 days
Blob StorageGRS replicationContinuous
App Service ConfigKey Vault snapshots90 days
Git RepositoryGitHub / Azure DevOpsIndefinite

MeasureImplementation
Network IsolationVNet integration for App Services; private endpoints for SQL and Blob
SecretsAzure Key Vault for all secrets; no secrets in source code (local dev uses .env.local, CI uses GitHub Actions Secrets, Azure uses Key Vault)
SSL/TLSCloudflare Full (Strict); TLS 1.2 minimum
Backoffice AccessIP whitelist + Azure AD / MFA
WAFCloudflare managed rules + custom rules for bot protection
DDoSCloudflare DDoS protection (included)

Full security specification in 15_Security.md


ServiceMonthly Estimate (EUR)Notes
App Service (Next.js) × 4 envs~€200–400P1v3 for PROD, B1 for DEV/STAGE
App Service (Umbraco) × 4 envs~€200–400P1v3 for PROD, B1 for DEV/STAGE
Azure SQL × 4 envs~€150–300S2 for PROD, Basic for DEV
Blob Storage~€20–50Depends on media volume
Application Insights~€50–100Based on data ingestion
Key Vault~€5Minimal
Cloudflare~€0–200Pro or Business plan
Total~€625–1,450/moVaries by tier selection

These are estimates. Actual costs depend on traffic, media volume, and scaling.


  • All 4 environments (DEV/STAGE/QA/PROD) are provisioned and accessible
  • CI/CD pipeline deploys successfully to DEV on develop branch merge
  • Cloudflare is configured with DNS, SSL, and cache rules for all domains
  • Application Insights captures telemetry from both Next.js and Umbraco
  • Alerts fire correctly when thresholds are breached
  • Key Vault stores all secrets; no secrets in application config
  • Database backup/restore tested successfully
  • Auto-scaling triggers verified under load

Next document: 03_MultiSite_and_Domains.md