Welcome to the Jose Madrid Salsa developer docs — explore features, APIs, and deployment guides.
Jose Madrid SalsaJMS Docs

Monorepo Deployment

How each app in the Turborepo monorepo maps to its own Vercel project, and how to add another one.

Monorepo Deployment

Every deployable app lives in one GitHub repository and deploys to its own Vercel project. Vercel supports this natively: each project points at a different Root Directory inside the same repo, has its own environment variables, its own domain, and its own build. A commit that only touches one app rebuilds only that app.

What is in the repo

WorkspacePathPort (dev)Deploys to Vercel
@jose-madrid/storefrontapps/storefront3000Yes — production site
@jose-madrid/docsapps/docs3002Yes — this documentation site
@jose-madrid/fundraisingapps/fundraising3001Not yet linked
@jose-madrid/adminapps/admin3003Not yet linked
@jose-madrid/agentapps/agentNo (local tooling; excluded from npm run build)
@jose-madrid/shared-typespackages/shared-typesNo (library)
@jose-madrid/shared-utilspackages/shared-utilsNo (library)

apps/macos-admin is a Swift package, not an npm workspace, and is built with build-app.sh rather than deployed. See macOS Admin App.

There is no apps/backend. API routes live in apps/storefront/app/api and deploy with the storefront. Older notes describing a separate backend deployment boundary are out of date.

Storefront

Vercel project: josemadridsalsa · Root Directory: apps/storefront · Production: https://www.josemadrid.net

Configured by apps/storefront/vercel.json:

  • Build command touches the various .env* files (so Next does not fail on a missing file), generates the game-icon manifest, then runs npm run vercel-build.
  • vercel-build runs prisma migrate deploy, prisma generate, the permission seed, and finally next build.
  • git.deploymentEnabled allows main only — pushes to any other branch do not create a deployment.
  • crons declares the ten scheduled jobs below.

Both the migrate step and the permission seed are wrapped in || echo 'WARN: ...'. A failed migration therefore produces a green build with a warning buried in the log. After deploying a schema change, confirm the migration actually applied rather than trusting the build status — see Database (Production).

Scheduled jobs

Crons run on Vercel (the account is on the Pro plan, so sub-daily schedules are allowed) and hit routes under apps/storefront/app/api/cron, each guarded by CRON_SECRET.

PathSchedule
/api/cron/email-automationevery 5 minutes
/api/cron/email-campaignsevery 5 minutes
/api/cron/social-publishevery 5 minutes
/api/cron/abandoned-carthourly
/api/cron/quickbooks-synchourly at :15
/api/cron/operations-sweepevery 2 hours
/api/cron/expire-pending-ordersevery 2 hours at :20
/api/cron/processor-feesevery 2 hours at :30
/api/cron/review-requestsdaily at 10:00 UTC
/api/cron/fundraiser-lifecycledaily at 13:00 UTC

Documentation site

Root Directory: apps/docs · Framework preset: Next.js

The docs site used to be a standalone repository (salsadocs) deployed from its own Git remote. It now lives in this monorepo so a feature change and the page describing it ship together — but it still deploys as a separate Vercel project, so it keeps its own domain and its own deployment history.

apps/docs/vercel.json keeps that separation safe:

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "git": {
    "deploymentEnabled": {
      "main": true,
      "*": false
    }
  },
  "ignoreCommand": "npx --yes turbo-ignore @jose-madrid/docs"
}
  • deploymentEnabled matches the storefront: main only, no preview deployments from feature branches.
  • ignoreCommand runs turbo-ignore, which compares the commit against the previous successful docs deployment and exits 0 — skipping the build — when nothing @jose-madrid/docs depends on has changed. Storefront-only commits therefore cost no docs build, and vice versa.

Because apps/docs declares no workspace dependencies, Vercel's default install and build (npm install at the repo root, next build in apps/docs) are correct; no custom build command is needed.

Adding another app as a Vercel project

  1. Link the directory.
    cd apps/<app>
    npx vercel link      # choose "create new project"
  2. Set Root Directory to apps/<app> in Project Settings → General. Leave "Include files outside the root directory" enabled so the monorepo lockfile and packages/* are available.
  3. Add a vercel.json in the app directory with the main-only git guard and a turbo-ignore ignore command, as above. Without the git guard every push to any branch creates a preview deployment for that project.
  4. Set environment variables in Project Settings → Environment Variables. They are per-project; nothing is inherited from the storefront project. vercel env pull from the storefront project is a convenient starting point, but re-point every URL and use a distinct NEXTAUTH_SECRET.
  5. If the app depends on a workspace package, set the build command to cd ../.. && npx turbo run build --filter=@jose-madrid/<app> so Turborepo builds the dependency first.
  6. Add the domain in Project Settings → Domains and create the DNS record Vercel shows you.

Root package.json carries the overrides block that pins transitive dependencies. npm only honours overrides from the root of a workspace, so installs must run from the repo root — which is what Vercel does when "include files outside the root directory" is on. Do not add a per-app lockfile.

Continuous integration

.github/workflows/ci.yml runs one pipeline for the whole repo on push and pull request: lint → type-check → tests → Prisma generate → build → shipping E2E → Playwright. Coverage and Playwright results are reported but do not gate the merge; lint, type-check, tests and build do.

Three Node versions are in play and they do not agree: .nvmrc pins 20, CI runs 22, and on Vercel the storefront project is set to 22 while the docs project is set to 20. Nothing is broken by this today, but check a project's Settings → General → Node.js Version before blaming a build failure on code — a version mismatch between local, CI and the deployed project is the cheapest explanation and the easiest to miss.

Rollback

Vercel keeps every deployment. To roll back, open the project → Deployments → pick the last good one → Promote to Production. This takes seconds and does not rebuild. It rolls back code only — a database migration that already ran stays applied, so a schema change needs a forward fix or a restore rather than a promotion.

How is this guide?

Edit on GitHub

Last updated on

On this page