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.
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.tsapps/admin/src/env.tsapps/cms/src/payload.config.tsapps/invoicing/src/env.tssst.config.ts- active workflows under
.github/workflows/
3
Generate VAPID keys if push is enabled
4
Validate the affected app
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, andprod. - Rotate a credential immediately if it appears in logs, terminal output, screenshots, or chat context.
- Preserve
.dev.varsignore rules even though Wrangler is retired; they protect plaintext secrets.
