Skip to Content
DocsDeploymentProduction Checklist

Production Checklist

Use this checklist before deploying to production or after major infrastructure changes.


Environment Variables

  • NEXT_PUBLIC_SUPABASE_URL set to production Supabase URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY set to production anon key
  • SUPABASE_SERVICE_ROLE_KEY set to production service role key
  • PLATFORM_ADMIN_EMAILS configured with at least 2 admin emails
  • UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN configured
  • TEMPORAL_ADDRESS pointing to Temporal Cloud (not localhost)
  • TEMPORAL_NAMESPACE set to production namespace
  • TEMPORAL_API_KEY set for Temporal Cloud authentication
  • AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY configured
  • BRAKET_S3_BUCKET and BRAKET_S3_PREFIX set
  • RESEND_API_KEY configured with production API key
  • RESEND_FROM_EMAIL set to verified production domain (not resend.dev)
  • NEXT_PUBLIC_APP_URL set to production URL (e.g., https://app.marqov.ai)
  • WORKER_URL pointing to production worker endpoint
  • PLAYGROUND_API_KEY set

Database

  • All migrations applied through migration 059
  • RLS policies verified on all tables
  • Backends table seeded with production backends and pricing
  • handle_new_user() trigger active on auth.users
  • update_updated_at_column() triggers active on all tables with updated_at
  • Cost tracking RPC functions deployed (get_team_spend_by_provider, get_team_spend_by_backend, get_team_daily_spend, get_team_total_spend)
  • upsert_team_secret function deployed for encrypted secret storage
  • validate_invitation_code function deployed

Worker

  • Docker image built with --platform linux/amd64
  • Image pushed to ECR: 123456789012.dkr.ecr.us-east-1.amazonaws.com/marqov/platform-worker
  • ECS service marqov-worker in cluster marqov-production updated
  • Health check passing on GET /health (port 8080)
  • Worker successfully polling Supabase for pending jobs
  • Worker connected to Temporal Cloud

Temporal

  • Temporal Cloud namespace created and accessible
  • Worker registered on marqov-workflows task queue
  • Workflow execution verified (submit a test job with execution_mode: "temporal")
  • Temporal UI accessible for debugging

Security

  • CORS headers configured for production domain only
  • CSP headers active (see buildCsp() in src/proxy.ts)
  • unsafe-eval scoped to /run route only (for Emscripten WASM)
  • wasm-eval enabled for all routes
  • COOP/COEP headers set for SharedArrayBuffer support
  • Rate limiting operational on all write endpoints
  • Team suspension guard active on write endpoints
  • Script upload validation (AST parsing) functional
  • Requirements validation blocking dangerous packages
  • Invitation code system functional
  • Secret values encrypted at rest in database

Monitoring

  • Sentry configured for platform (Next.js) errors
  • Sentry configured for worker (Python) errors
  • Source maps uploaded to Sentry
  • Structured logging active (request IDs, user IDs, team IDs)
  • Budget exceeded events logged
  • Rate limit events logged

Cost Controls

  • Per-job cost limit: $100
  • Per-suite cost limit: $500
  • Default daily team budget: $100
  • Default monthly team budget: $1,000
  • Team daily quota: 100 jobs/day
  • Budget check active before job creation
  • Cost calculation using database pricing (calculateJobCost)

Browser Simulator

  • quantum-circuit adapter loading correctly
  • qulacs-wasm adapter loading correctly (non-Safari)
  • Safari fallback to quantum-circuit working
  • COEP credentialless header not breaking Sentry
  • Simulation telemetry recording to simulation_events table
  • Qubit limits enforced (soft warning 17-20, hard block 21+)

Verification

  • Submit a job via API and verify it completes
  • Submit a playground run and verify results
  • Create a team invitation and verify email delivery
  • Create and seal a capsule
  • Verify budget check blocks over-budget jobs (402 response)
  • Verify rate limiting returns 429 with Retry-After header
  • Verify suspended team cannot create jobs (403 response)
Last updated on