Skip to main content
Royal Glow has four application contracts: apps/web, apps/admin, apps/cms, and apps/invoicing. The web and admin apps run on AWS Lambda + CloudFront through SST, the CMS stays on Render, and invoicing stays on Google Cloud Run. Cloudflare remains the authoritative DNS provider and R2 storage provider; it does not host application compute.
No single table is the complete environment contract. Use each app’s validator or configuration file as the source of truth. Web and admin use @t3-oss/env-nextjs; invoicing parses process.env with Zod at startup; Payload, Sentry configuration, SST, and workflows also own variables outside those two Next.js validators.
Optional integrations degrade gracefully only where their implementation explicitly guards missing configuration. For example, optional Sentry DSNs disable Sentry and optional invoice-service caller settings produce an invoice email without a PDF attachment. Never assume every missing integration variable is safe.

Quick Start

1

Create app-local files

apps/web/.env.example does not exist. The root .env.example is the starting template for the customer app.
2

Reconcile with authoritative contracts

Check the relevant source before filling values:
  • apps/web/src/env.ts
  • apps/admin/src/env.ts
  • apps/cms/src/payload.config.ts
  • apps/invoicing/src/env.ts
  • sst.config.ts
  • active workflows under .github/workflows/
3

Generate VAPID keys if push is enabled

4

Validate the affected app

Required values are validated when their owning module loads. Builds and cold starts can therefore fail when a required value is absent or malformed.

Source-of-Truth Files

Some framework bootstrap files intentionally read process.env directly. Current examples include the Sentry config files, which must initialize before app modules can import typed env helpers. Do not copy that exception into ordinary application code.

Core Ownership

Database

Migrations use the direct Neon endpoint. Never substitute the pgBouncer/pooled URL for DDL.

Authentication

BETTER_AUTH_SECRET, BETTER_AUTH_URL, GOOGLE_OAUTH_CLIENT_ID, and GOOGLE_OAUTH_CLIENT_SECRET are owned by both Next.js apps. BETTER_AUTH_SECRET must be byte-identical across web and admin within one environment so the .theroyalglow.in session cookie remains valid.

Invoice PDF Service

The caller intentionally falls back to sending the invoice email without a PDF attachment when the URL or shared HMAC secret is absent.

Sentry

Cloudflare Boundary

Cloudflare variables remain for two active capabilities only: The DNS token must have only the zone permissions SST needs. Do not inject DNS credentials into either Next.js app. Workers, Pages, Wrangler, and KV compute contracts are retired.

Other Integration Contracts

Web and admin validators currently own required auth, Ably, Upstash Redis, and QStash values. Web additionally owns required Resend, R2 access, VAPID, PostHog, and customer-facing public values. Optional web values include Meta CAPI, report destinations, heartbeat URLs, and invoice-service caller settings. Admin additionally owns optional invoice-service caller settings and its optional Sentry DSN. Exact requiredness can change. Check the current Zod schema rather than copying a static list from this page.

Platform Injection

Production platforms inject values; committed .env files are not used in production.

Secret Safety

  • Never commit .env.local, .dev.vars, credentials, tokens, or private keys.
  • Keep public identifiers separate from secrets; NEXT_PUBLIC_* values are embedded in browser bundles.
  • Use different Neon URLs per dev, test, pprd, and prod.
  • Rotate a credential immediately if it appears in logs, terminal output, screenshots, or chat context.
  • Preserve .dev.vars ignore rules even though Wrangler is retired; they protect plaintext secrets.

Inventory Maintenance

Do not maintain a hand-counted total. Validators, guarded bootstrap reads, SST resources, and workflow-only variables evolve independently. When a contract changes, update its source file, relevant template, deployment wiring, and this ownership guide in the same change.
Last modified on September 1, 2026