Skip to main content
Royal Glow ships through a four-stage Git pipeline with progressively stricter gates, deploys apps/web and apps/admin to AWS Lambda + CloudFront through SST, and decouples deploy from release using PostHog feature flags.
Deploy ≠ release. Code reaches production on Lambda + CloudFront after a successful prod deployment; a feature only becomes visible when its PostHog flag is turned on. A bug may be contained by flipping a flag off without a deployment rollback.

Branch strategy

Four persistent branches, each mapped to an environment and a Neon DB branch. Work flows in one direction: dev → test → pprd → prod. There are no direct pushes to prod. The pprd branch is reset from prod every 24h via the Neon Branch Reset API (a near-instant copy-on-write operation), then a PII-anonymisation script scrubs names, phones, and emails so UAT has realistic data without real customer PII. QStash scheduled jobs target prod only.

Hosting topology

  • Web + admin: apps/web and apps/admin run on AWS Lambda (ARM64) behind separate CloudFront distributions in ap-southeast-1. SST declares both with sst.aws.Nextjs; AWS packaging uses OpenNext.
  • DNS: Cloudflare remains authoritative DNS only. SST uses the Cloudflare provider for ACM validation and the web/admin aliases; application compute is on AWS.
  • CMS: Render (Singapore) continues to host Payload CMS (rgss-cms, cms.theroyalglow.in).
  • PDF render: Cloud Run continues to host the invoice PDF service (@rgss/invoicing).
  • Database: one Neon PostgreSQL 16 project with four branches.
  • Media: Cloudflare R2 remains the S3-compatible object store. Rate limiting + queue: Upstash Redis + QStash. Realtime: Ably.

GitHub Actions workflows

These workflows enforce the gates above and handle production deploys. apps/web and apps/admin are live on AWS through deploy-aws.yml. Payload CMS remains on Render and the invoicing service remains on Cloud Run. Cloudflare hosts authoritative DNS and R2 storage only; earlier Worker deployment workflows and adapters are retired. Lighthouse gates require performance ≥ 95 and accessibility, best-practices, and SEO = 100.

Feature-flag release strategy

Every feature ships to prod behind a PostHog flag and is exposed gradually.
1

Deploy with the flag OFF

A successful prod deployment places code on Lambda + CloudFront, invisible to everyone.
2

Flag ON for role = developer

Self-test directly in production.
3

Flag ON for role = owner | manager

Stakeholder preview.
4

Flag ON for 10% of customers

Watch Sentry for new errors.
5

Flag ON for 100%

Full release to all customers.
6

Remove flag + dead code

After 2 weeks stable, clean up the flag and dead code.

Rollback tiers

When something goes wrong, escalate from the cheapest, fastest lever upward.
Turn the PostHog flag OFF. No deploy, no rollback — the feature simply disappears.
Run the Deploy AWS workflow with git_ref set to the last known-good tag or SHA. SST redeploys both sst.aws.Nextjs applications to Lambda + CloudFront. If an SST/Pulumi update fails, inspect the deployment logs and stack state, verify both health endpoints, and redeploy the known-good ref when resources are unhealthy or partially updated.
Neon PITR to a pre-migration point-in-time branch.
Emergency DB restored from the weekly R2 backup.

Health check

GET /api/health probes the database, Redis, and R2 in parallel and returns a HealthStatus contract: healthy / degraded / unhealthy. It responds 200 for healthy or degraded and 503 for unhealthy, always with Cache-Control: no-store. BetterStack polls it every ~3 minutes and opens an incident on status.theroyalglow.in if it fails.

Backups

Architecture

Hosting topology and observability layers

Background Jobs

Scheduled work and heartbeat monitoring

Data Model

What the migrations and backups protect
Last modified on September 1, 2026