Skip to main content

Deployment and Environments

Deployment Topology​

AppPlatformNotes
APIRenderStaging web service from render.yaml; production web service from render.production.yaml. Both use the $7 instance (0.5c-512mb).
WebCloudflare PagesPublished by .github/workflows/deploy.yml
WorkersNot deployedScaffolded for future background processing

The repository still contains apps/web/vercel.json, but it is not the active deployment path.

API Deployment​

render.yaml deploys staging salesarc-api. render.production.yaml deploys production salesarc-api-production. Each blueprint also defines that environment's cron service. The web services use:

  • Node 20
  • pnpm install --frozen-lockfile --prod=false
  • pnpm turbo run build --filter=@salesarc/api...
  • pnpm --filter @salesarc/api start
  • health check on /health

Important runtime env vars include:

  • DATABASE_URL
  • SUPABASE_URL
  • SUPABASE_SERVICE_ROLE_KEY
  • API_BASE_URL
  • FRONTEND_URL
  • ENCRYPTION_KEY
  • Square and Clover credentials
  • RESEND_API_KEY
  • CRON_SECRET

Web Deployment​

The web deploy workflow builds apps/web and publishes apps/web/dist to Cloudflare Pages.

The current workflow is triggered on pushes to main.

Environment Validation​

apps/api/src/lib/env.ts validates the backend environment on process start.

Key rules:

  • DATABASE_URL, SUPABASE_URL, and SUPABASE_SERVICE_ROLE_KEY are required.
  • If Square or Clover credentials are present, ENCRYPTION_KEY must be 64 hex characters.
  • Production POS deployments require API_BASE_URL and FRONTEND_URL.
  • CRON_SECRET must be present for internal scheduled routes.

Cron and Polling​

The API exposes these secret-protected internal routes:

  • POST /api/v1/internal/cron/square-poll-payments
  • POST /api/v1/internal/cron/clover-poll-payments
  • POST /api/v1/internal/cron/process-pending-webhooks
  • POST /api/v1/internal/cron/process-campaigns

Each environment's Render cron service calls them with X-Cron-Secret every 5 minutes. Staging and production do not share a cron service or a cron secret.

Local Development​

  • API dev server: pnpm --filter @salesarc/api dev
  • Web dev server: pnpm --filter @salesarc/web dev
  • Shared workspace scripts live at the repo root

Deployment Constraints​

  • Staging and production API instances are the $7 plan (0.5c-512mb) and do not spin down.
  • Render cron jobs have no free plan. Each environment's cron uses 0.5c-512mb and is billed for the seconds it runs, with a $1 monthly minimum.
  • Square, Clover, webhook, and campaign jobs run from the cron service in that environment's blueprint.
  • Accepted webhooks are stored in webhook_jobs and ingested immediately. POST /api/v1/internal/cron/process-pending-webhooks retries jobs that did not finish.
  • apps/workers is not the webhook consumer. The Render cron calls the API.
Written byDhruv Doshi