Skip to main content

Production Checklist

Run through this list before serving production traffic.

Infrastructure

  • Neon database created in the right region; pooled + unpooled URLs in env.
  • Supabase project + bucket created in the matching region.
  • NEXTAUTH_URL matches the public hostname Vercel routes to.
  • NEXTAUTH_SECRET is unique to this deployment (not reused from dev).
  • CRON_SECRET set; verify a cron handler returns 401 without it via curl -i .../api/cron/scheduled-publish.
  • Custom domain attached in Vercel; HTTPS certificate issued.

Database

  • pnpm db:push (or pnpm db:deploy with migrations) completed cleanly.
  • pnpm db:seed ran once to provision the admin user.
  • Initial admin password rotated immediately after first login.

Security

  • Settings → Security tab → IP allowlist configured if your management API access should be restricted.
  • Settings → API keys — preview / management keys created with expiresAt set; no long-lived keys.
  • CORS origins configured per project for the management API (see Settings → CORS).
  • KRIOS_TENANT_DB_KEY set if you use V3 physical isolation.
  • Ensure your host sets HSTS (Strict-Transport-Security) — the app does not set this header itself; verify with curl -I.

Performance

  • Edge cache headers verified: curl -I .../api/delivery/projects/.../entries/... shows Cache-Control: public, max-age=60.
  • Surrogate-Key header present.
  • Cron handlers running hourly (0 * * * *) (Vercel dashboard → Crons).
  • Webhook subscribers configured for cache invalidation on the consuming frontend.
  • Default Postgres search works for project content.
  • If using Meilisearch: SEARCH_PROVIDER=meilisearch, MEILI_HOST, MEILI_API_KEY set (functional names read by the search provider; also set MEILISEARCH_URL / MEILISEARCH_API_KEY if you want the health check to report Meilisearch); krios search reindex --project <slug> ran.

Observability

  • Vercel logs forwarded to your log aggregator (Datadog, Logtail, etc.).
  • Audit log queryable from the admin UI's Audit tab.
  • Reports → Governance run once, no high-severity issues.

Frontend integration

  • Delivery key created with siteId scope (and expiresAt if appropriate).
  • Frontend uses KriosClient.resolveRoute() for path resolution (handles redirects + 404 correctly).
  • Frontend webhook handler verifies HMAC signatures via verifyKriosSignature.
  • Preview key created; KriosPreviewOverlay wired into the layout under a feature flag.

Operational

  • Backup strategy documented and verified (Neon PITR + bucket replication).
  • Incident response: who gets paged on database-down? Vercel SSO setup for the on-call team?
  • First Krios upgrade tested on a staging deployment before production.
  • Custom field type registrations point at HTTPS-only origins.

Rollback plan

If a deploy goes bad:

  1. Vercel Deployments → previous → Promote to production.
  2. If a schema migration broke something, use Neon's PITR to roll the database back to before the migration ran.
  3. Check the audit log for any user-visible mutations that landed under the bad deploy; remediate (restore versions, unpublish, etc.).

Post-launch

  • Browser: confirm the admin UI loads; sign in as the bootstrap admin.
  • Browser: navigate to Reports and run Re-run analysis on Governance.
  • CLI: krios types list --project demo returns the seeded types.
  • CLI: krios entries list --project demo --limit 1 returns at least one row.
  • curl: GET against the delivery API for a known entry returns 200 with the right body.