WordsToMotion
Deployment

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 with pnpm video:worker.

Deployment Topology

Deploy the web apps as separate projects or services with these roots:

ServiceRootBuild commandStart command
SaaSapps/saaspnpm buildpnpm start
Marketingapps/marketingpnpm buildpnpm start
Docsapps/docspnpm buildpnpm 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:worker

Run 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       3002

Server-only secrets must stay unprefixed. Only values that are safe for the browser should use NEXT_PUBLIC_.

Release Order

  1. Apply the Prisma migration with pnpm --filter @repo/database migrate:deploy.
  2. Deploy storage buckets and confirm uploads, downloads, and signed URLs work.
  3. Deploy the SaaS app with production auth, payment, storage, mail, and AI variables.
  4. Deploy the video worker using the same database and storage variables as SaaS.
  5. Deploy marketing and docs with the final public URLs.
  6. Configure Stripe webhook delivery to POST /api/webhooks/payments.
  7. 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:smoke

When 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-ffmpeg

The 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:

  1. Create a new user.
  2. Confirm the new user receives FREE plan limits and 30 video credits.
  3. Create a short video project.
  4. Confirm a queued VideoJob is created and credits are deducted once.
  5. Start the worker and wait for the job to complete.
  6. Confirm scene HTML, scene PNGs, narration audio, timeline JSON, and MP4 artifacts are stored in the video artifact bucket.
  7. Download the generated MP4 from the SaaS app.
  8. Confirm direct HTML artifact downloads are attachments and do not execute scripts on the SaaS origin.
  9. Create a second job while the first is running and confirm Free concurrency is limited.
  10. Force a job failure in staging and confirm credits are refunded.
  11. Complete a Stripe Pro checkout and confirm the user moves to PRO with 300 video credits.
  12. 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 high

The 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.

On this page