# Flash sale system — environment variable contract. # Canonical spellings are FROZEN by .claude/contracts/phase-0.md §11. # Copy to `.env` for local (non-compose) `pnpm dev` runs. Never commit `.env`. # In-network (docker compose) values differ for DATABASE_URL/REDIS_URL/CORS_ORIGIN/ # VITE_API_BASE_URL — those are set explicitly in infra/docker-compose.yml, not read from here. # runtime NODE_ENV=development LOG_LEVEL=info # ports API_HOST=0.0.0.0 API_PORT=3000 WORKER_HEALTH_PORT=3001 WEB_PORT=5173 # datastores # Production must explicitly provide CORS_ORIGIN, DATABASE_URL, REDIS_URL, and SALE_ID. CORS_ORIGIN=http://localhost:5173 VITE_API_BASE_URL=http://localhost:3000/api DATABASE_URL=postgresql://flash:flash@localhost:5433/flash REDIS_URL=redis://localhost:6380 # sale SALE_ID=flash-2026 SALE_NAME=Aurora — Founders Edition SALE_STARTS_AT=2026-07-22T12:00:00.000Z SALE_ENDS_AT=2026-07-22T13:00:00.000Z SALE_TOTAL_STOCK=500 # rate limiting RATE_LIMIT_MAX=20 RATE_LIMIT_WINDOW_MS=1000 RATE_LIMIT_USER_MAX=5 RATE_LIMIT_USER_WINDOW_MS=1000 # queue ORDERS_QUEUE_NAME=orders WORKER_CONCURRENCY=16 WORKER_MAX_ATTEMPTS=5 # Worker PG pool: integer 2-100; one slot is retained by the reconciliation fence. WORKER_PG_POOL_MAX=10 WORKER_PG_STATEMENT_TIMEOUT_MS=2000 WORKER_RECONCILE_INTERVAL_MS=2000 WORKER_RECONCILE_SCAN_COUNT=200 WORKER_DLQ_SWEEP_INTERVAL_MS=1000 WORKER_DLQ_SCAN_COUNT=100 # api hardening (Phase 2 — contract §3.1) TRUST_PROXY=false REQUEST_BODY_LIMIT_BYTES=16384 CLOCK_SYNC_INTERVAL_MS=5000 CLOCK_MAX_STALENESS_MS=15000 CLOCK_GUARD_SKEW_MS=250 ENQUEUE_TIMEOUT_MS=500 PG_POOL_MAX=10 PG_STATEMENT_TIMEOUT_MS=2000 # compose only (used by the postgres service in infra/docker-compose.yml) POSTGRES_USER=flash POSTGRES_PASSWORD=flash POSTGRES_DB=flash # test # optional; when unset the redis package's unit tests start a throwaway container via testcontainers. REDIS_TEST_URL= # optional; when unset apps/api's integration suite starts a throwaway container via testcontainers. POSTGRES_TEST_URL= # stress (Phase 5 local isolated stack) STRESS_RUN_ID= STRESS_REPETITIONS=3 STRESS_API_PORT=3300 STRESS_WORKER_PORT=3301 STRESS_POSTGRES_PORT=5543 STRESS_REDIS_PORT=6680 STRESS_CONVERGENCE_TIMEOUT_MS=120000