> ## Documentation Index
> Fetch the complete documentation index at: https://docs.theroyalglow.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployment

> Branch strategy, hosting, CI/CD workflows, feature-flag releases, rollback tiers, and backups for Royal Glow.

# Deployment

Royal Glow ships through a four-stage Git pipeline with progressively stricter
gates, deploys to Cloudflare's edge, and decouples **deploy** from **release**
using PostHog feature flags. The whole platform runs at **₹0/month** on free
tiers at launch.

<Info>
  **Deploy ≠ release.** Code goes live on the edge on every merge to `prod`;
  a feature only becomes visible when its PostHog flag is turned on. A bug means
  flipping a flag off — no rollback required.
</Info>

## 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`**.

| Branch | Environment    | Neon branch | Protection / gates                              |
| ------ | -------------- | ----------- | ----------------------------------------------- |
| `dev`  | Development    | `dev`       | Lint + type check + unit tests                  |
| `test` | QA / CI        | `test`      | + integration + Playwright E2E + Lighthouse CI  |
| `pprd` | Pre-production | `pprd`      | + k6 load test + smoke suite + dependency audit |
| `prod` | Production     | `prod`      | + manual approval → deploy + health check       |

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

* **Edge:** Cloudflare Workers (via the OpenNext adapter, `@opennextjs/cloudflare`) serve the customer site (`rgss-web`, `theroyalglow.in`) and the admin portal (`rgss-admin`, `admin.theroyalglow.in`) globally — deployed near India (Mumbai / Singapore). **Not** Cloudflare Pages, **not** `next-on-pages`.
* **CMS:** Render (Singapore, free tier) hosts Payload CMS (`rgss-cms`, `cms.theroyalglow.in`).
* **PDF render:** Cloud Run hosts the invoice PDF service (`@rgss/invoicing`).
* **Database:** a single Neon PostgreSQL 16 project with four branches.
* **Media:** Cloudflare R2 (S3-compatible, zero egress). **Cache + queue:** Upstash Redis + QStash. **Realtime:** Ably.

## GitHub Actions workflows

These workflows enforce the gates above and handle production deploys.

| Workflow          | File              | Triggers on                                                 | Does                                                                                                                                                                      |
| ----------------- | ----------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CI                | `ci.yml`          | PRs to all branches + push to `dev`                         | Lint + typecheck, unit tests, build, Trivy + Socket.dev audit                                                                                                             |
| Integration & E2E | `integration.yml` | PRs to `test`/`pprd`/`prod`                                 | Integration tests, Playwright E2E, Lighthouse CI                                                                                                                          |
| Load & Security   | `load-test.yml`   | PRs to `pprd`/`prod`                                        | k6 load test, Trivy fs scan, OWASP ZAP baseline                                                                                                                           |
| Deploy AWS        | `deploy-aws.yml`  | Push to `prod` (web/admin/packages paths) + manual dispatch | GitHub OIDC → `bunx sst deploy --stage production` (Lambda + CloudFront for `apps/web` and `apps/admin`) → health check. Manual dispatch accepts a `git_ref` for rollback |
| Migrations        | `migrate.yml`     | Manual dispatch (per branch)                                | Applies committed Drizzle migrations over the unpooled connection                                                                                                         |

Web, admin and CMS deploy from git on **Render** today; `deploy-aws.yml` is the AWS path
described in `M2AWS.md`. The earlier Cloudflare workflows (`deploy-prod.yml`,
`deploy-admin-prod.yml`) were retired along with the Workers adapter.

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.

<Steps>
  <Step title="Deploy with the flag OFF">
    Code goes live on the edge, invisible to everyone.
  </Step>

  <Step title="Flag ON for role = developer">
    Self-test directly in production.
  </Step>

  <Step title="Flag ON for role = owner | manager">
    Stakeholder preview.
  </Step>

  <Step title="Flag ON for 10% of customers">
    Watch Sentry for new errors.
  </Step>

  <Step title="Flag ON for 100%">
    Full release to all customers.
  </Step>

  <Step title="Remove flag + dead code">
    After 2 weeks stable, clean up the flag and dead code.
  </Step>
</Steps>

## Rollback tiers

When something goes wrong, escalate from the cheapest, fastest lever upward.

<AccordionGroup>
  <Accordion title="Flag — UI bug after deploy · < 10 sec">
    Turn the PostHog flag OFF. No deploy, no rollback — the feature simply disappears.
  </Accordion>

  <Accordion title="Tier 1 — App crash / 500s · < 30 sec">
    Cloudflare Workers rollback to the previous deployment via `wrangler rollback`
    (or the Workers & Pages → Deployments view). Cloudflare keeps every Worker
    deployment as an immutable version, and the post-deploy job auto-rolls back if
    the health check fails.
  </Accordion>

  <Accordion title="Tier 2 — Bad migration, data corrupted · < 5 min">
    Neon PITR to a pre-migration point-in-time branch.
  </Accordion>

  <Accordion title="Tier 3 — Neon outage · < 30 min">
    Emergency DB restored from the weekly R2 backup.
  </Accordion>
</AccordionGroup>

## 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

| Type                  | Frequency       | Retention | Storage               | RPO                 |
| --------------------- | --------------- | --------- | --------------------- | ------------------- |
| Neon PITR (automatic) | Continuous WAL  | 7 days    | Neon infrastructure   | \~0 sec             |
| Weekly `pg_dump`      | Sun 7:30 AM IST | 8 weeks   | Cloudflare R2         | ≤ 7 days            |
| Monthly restore test  | 1st of month    | —         | Temporary Neon branch | Validates integrity |

## Related pages

<Columns cols={2}>
  <Card title="Architecture" href="/docs/architecture">
    Hosting topology and observability layers
  </Card>

  <Card title="Background Jobs" href="/docs/background-jobs">
    Scheduled work and heartbeat monitoring
  </Card>

  <Card title="Data Model" href="/docs/data-model">
    What the migrations and backups protect
  </Card>
</Columns>


## Related topics

- [Git Workflow](/content/docs/git-workflow.md)
- [FAQ](/content/docs/faq.md)
- [Operations](/content/docs/operations.md)
- [Background Jobs](/content/docs/background-jobs.md)
- [Analytics](/content/docs/analytics.md)
