Pre-launch ops checklist (Phase 1 → production)
The last Phase-1 box. Every feature is built; this is the operational pass that turns a green codebase into a live deployment. Work top-to-bottom; nothing here is code-writing — it's gates, config, data, and manual QA.
Legend: [auto] = runnable via scripts/pre-launch-checks.sh · [manual] = human action · [operator] = do only when explicitly ready (not part of a dry run).
1. Code gates [auto]
Run bash scripts/pre-launch-checks.sh (or the commands below). All must pass.
- [ ] Typecheck —
npx tsc -p apps/api/tsconfig.json --noEmitand the webtsc(part ofnpm --workspace=apps/web run build). - [ ] Unit/integration tests —
npm test(all workspaces). API + web suites green. - [ ] Coverage thresholds —
npm --workspace=apps/api run test:coverageandnpm --workspace=apps/web run test:coveragemeet 80/80/80/70 (lines/functions/statements/branches per CLAUDE.md). Document any pre-existing flake (e.g.search.routes.test) as out-of-scope, not a new regression. - [ ] Production builds —
npm run build(web + admin). The bundle is what users get, not the dev server. - [ ] Dependency audit —
npm audit --audit-level=highclean, OR every finding triaged (the knownfirebase-admintransitive advisory is pre-existing; no NEW high/critical introduced).
2. Secrets + config (Railway env) [manual]
Nothing below lives in git. Verify each is set in the target environment.
- [ ]
DATABASE_URL(Supabase, pooler),JWT_SECRET(≥64 random chars),JWT_*_EXPIRES_IN. - [ ]
FRONTEND_URLset to the exact web origin (CORS is not*); admin origin too. - [ ] MSG91 —
MSG91_API_KEYis a LIVE key;MSG91_SENDER_IDset. Register every template in the MSG91 dashboard and set itsMSG91_TEMPLATE_ID_*(full list in.env.example). Until a template ID is set, that event's SMS is silently skipped (in-app still fires). Mandatory ones boot-fail in production (validateSmsTemplateEnv): OFFER_ACCEPTED, BID_ACCEPTED, OFFER/BID_AUTO_REJECTED_LEAD_EXPIRED. - [ ] Redis —
REDIS_URLset (Railway private endpoint), reachable. The SMS worker + scheduled workers won't run without it (in-app notifications still write; SMS + sweeps don't). - [ ] R2 —
R2_*set; bucket public-read, directory-listing OFF, CORS to our domain only. - [ ] Firebase —
FIREBASE_*(OTP).OPENWEATHERMAP_API_KEY(nice-to-have). - [ ] Sentry —
SENTRY_DSN(api) +VITE_SENTRY_DSN(web/admin) +SENTRY_ENVIRONMENT+SENTRY_RELEASE(git SHA). Empty DSN = quiet (fine for dev, NOT for prod).
3. Feature flags [manual]
- [ ]
EMANDI_TILED_REDESIGN_ENABLED— flip ON in production once smoke-tested (the tiled/sell/buyhubs + browse boards depend on it).
4. Data — DB wipe + reseed [operator] ⚠ DO NOT run during testing
The product owner triggers this only when production testing is finished — do NOT run it as part of a dry run.
- [ ] Taxonomy wipe + reseed:
npm run db:wipe-taxonomy(interactive — typesDELETE EVERYTHING; refuses in production unlessALLOW_PRODUCTION=true). Recomputes trust scores after. - [ ] If keeping any pre-wipe batches:
npm --workspace=apps/api run db:backfill-batch-sale-price(idempotent). N/A after a full wipe. - [ ] Confirm all CHG migrations are applied (pooler-safe
prisma db execute+migrate resolveflow per the CHG notes).
5. Manual QA [manual]
- [ ] Viewport sweep — 320 / 375 / 768 / 1024 / 1440 / 1920px on the key pages (Dashboard, Sell/Buy hubs + browse, product drawer, Reports, Profile, a deal detail). No horizontal scroll, no clipped tap targets, no empty-column imbalance.
- [ ] Keyboard a11y — Tab/Enter/Space/Arrows/Escape through the board tables + overlays (unplug the mouse).
- [ ] Core flow smoke (staging): signup→OTP→complete profile; post a sell + buy lead; offer/bid → accept → dispatch → buyer confirm-receipt (stock deducts on receipt, both batches reconcile); Buy Now; Reports page renders + CSV/XLS/PDF download; instant-push notification toast arrives.
6. Observability + monitoring [manual]
- [ ] Staging Sentry receiving events (throw a test error) before prod deploy.
- [ ] Better Uptime monitors:
GET /api/v1/health(1-min) + web root (5-min); alert channel set. - [ ] Bull Board reachable at
/admin/queues(admin auth) — SMS + scheduled queues visible. - [ ]
/api/v1/healthreturns 200 withdatabase: ok+redis: okin prod.
7. Security final pass [manual] (CLAUDE.md §14)
- [ ]
npm audit --audit-level=highclean (or triaged). - [ ] No secrets in git history; all secrets in Railway only.
- [ ] helmet headers present on API responses; HSTS on.
- [ ] File-upload endpoints reject non-images (magic-byte check) with 400.
- [ ] Rate limits verified on OTP + login.
- [ ] No
console.logof phone numbers / tokens.
8. Deploy [operator]
- [ ] Staging deploy → run §5 smoke → product-owner sign-off (screenshots).
- [ ] Production deploy (Railway). Tag the release SHA into
SENTRY_RELEASE. - [ ] Post-deploy: re-check
/api/v1/health, watch Sentry error rate for the first hour.
Order of operations on the real launch day: §1–§3 + §6–§7 first (safe, repeatable) → staging smoke (§5) → product-owner sign-off → then the §4 DB wipe → production deploy (§8). The wipe is last because it's destructive and the owner gates it.
