Production Readiness
Production deployment checklist for the WordsToMotion SaaS, video worker, storage, billing, and launch smoke tests.
This checklist is the minimum production handoff for WordsToMotion. It assumes three deployable web apps and one background worker:
apps/saas: authenticated product, API routes, auth callbacks, payment webhooks, and video download routes.apps/marketing: public website.apps/docs: documentation site.video-worker: long-running background process started withpnpm video:worker.
Deployment Topology
Deploy the web apps as separate projects or services with these roots:
| Service | Root | Build command | Start command |
|---|---|---|---|
| SaaS | apps/saas | pnpm build | pnpm start |
| Marketing | apps/marketing | pnpm build | pnpm start |
| Docs | apps/docs | pnpm build | pnpm start |
Deploy the worker as a container from Dockerfile.video-worker, or run it in a
Node 22 environment with ffmpeg available:
pnpm install --frozen-lockfile
pnpm --filter @repo/database generate
pnpm video:workerRun at least one worker in production. Scale workers horizontally only after the
database migration that adds VideoJob.lockExpiresAt, VideoJob.lockedAt,
VideoJob.attempts, and VideoJob.maxAttempts has been deployed.
Required Infrastructure
Use managed infrastructure for the production system:
- PostgreSQL for
DATABASE_URL. - Cloudflare R2 or another S3-compatible storage provider for avatars and video artifacts.
- A worker runtime with persistent process execution and FFmpeg installed.
- Stripe with the configured Pro monthly, Pro yearly, and lifetime price IDs.
- MiniMax and OpenAI API keys for generation.
- A mail provider for auth and product emails.
The local Docker Compose file includes PostgreSQL and MinIO for development only. Do not use the local Compose credentials in production.
Environment Variables
Use .env.production.example as the production inventory. Configure the same
runtime values on apps/saas and video-worker for database, storage, AI, and
video rendering variables.
The web apps must agree on these public URLs:
NEXT_PUBLIC_MARKETING_URL="https://wordstomotion.com"
NEXT_PUBLIC_SAAS_URL="https://app.wordstomotion.com"
NEXT_PUBLIC_DOCS_URL="https://docs.wordstomotion.com"The local ports are intentionally different:
apps/saas 3000
apps/marketing 3001
apps/docs 3002Server-only secrets must stay unprefixed. Only values that are safe for the
browser should use NEXT_PUBLIC_.
Release Order
- Apply the Prisma migration with
pnpm --filter @repo/database migrate:deploy. - Deploy storage buckets and confirm uploads, downloads, and signed URLs work.
- Deploy the SaaS app with production auth, payment, storage, mail, and AI variables.
- Deploy the video worker using the same database and storage variables as SaaS.
- Deploy marketing and docs with the final public URLs.
- Configure Stripe webhook delivery to
POST /api/webhooks/payments. - Run the smoke tests below before opening public traffic.
Production Smoke Test
Run this test once in staging and again after the production deployment:
Start with the automated preflight:
pnpm production:smokeWhen isolating a partial environment, use the skip flags:
pnpm production:smoke -- --skip-http
pnpm production:smoke -- --skip-storage
pnpm production:smoke -- --skip-db
pnpm production:smoke -- --skip-ffmpegThe smoke command checks required environment variables, URL protocols, database
connectivity, the video_job production columns, video artifact bucket
upload/download/signed-url/delete, FFmpeg availability, and the SaaS
/api/health endpoint. It does not call paid AI providers or create Stripe
transactions.
Then run the product path manually:
- Create a new user.
- Confirm the new user receives
FREEplan limits and 30 video credits. - Create a short video project.
- Confirm a queued
VideoJobis created and credits are deducted once. - Start the worker and wait for the job to complete.
- Confirm scene HTML, scene PNGs, narration audio, timeline JSON, and MP4 artifacts are stored in the video artifact bucket.
- Download the generated MP4 from the SaaS app.
- Confirm direct HTML artifact downloads are attachments and do not execute scripts on the SaaS origin.
- Create a second job while the first is running and confirm Free concurrency is limited.
- Force a job failure in staging and confirm credits are refunded.
- Complete a Stripe Pro checkout and confirm the user moves to
PROwith 300 video credits. - Cancel or expire the Pro subscription in Stripe test mode and confirm the user returns to
FREE.
Voice cloning is intentionally paused until explicit user consent, retention policy, and provider-transfer wording are implemented. Existing cloned voices can be deleted through the API and provider deletion path.
Pre-Launch Gates
Run these commands before every production release:
pnpm format:check
pnpm lint
pnpm type-check
pnpm test
pnpm build
pnpm --filter saas e2e:ci
pnpm --filter marketing e2e:ci
pnpm audit --prod --audit-level high
pnpm audit --audit-level highThe audit gate is considered passing when both audit commands exit with status
0. Low and moderate vulnerabilities should still be tracked, but high severity
production issues block launch.