Skip to main content

Deployment & Infrastructure

Current Topology

Deployment Targets

SurfacePlatformURLNotes
APIRendersalesarc-api.onrender.comNode + Hono; env validated at startup
WebVercelsalesarc-web.vercel.appSPA with client-side routing rewrites
DocsCloudflare Pagessalesarck-documentation.pages.devDocusaurus static site
WorkersNot yet deployedScaffold only (apps/workers)

Environment Model

EnvironmentPurposeAuth/DBPOS credentials
localdeveloper iterationlocal or sandbox Supabasesandbox
devshared integrationseparate dev Supabase projectsandbox
stagingpre-prod validationseparate staging Supabase projectsandbox
prodlive trafficseparate production Supabase projectproduction

Cron and Async Strategy

Webhook path uses fast-ack + setImmediate async processing in-process.

Scheduled jobs run via external cron (Render cron, cron-job.org, or GitHub Actions) calling protected API routes:

RouteSuggested cadencePurpose
POST /api/v1/internal/cron/square-poll-paymentsevery 5 minListPayments poll fallback for Square
POST /api/v1/internal/cron/process-pending-webhooksevery 5 minRetry sweeper for stuck webhook events (both providers)

Both routes require X-Cron-Secret header.

Environment Contract

Backend env validation is codified in apps/api/src/lib/env.ts (Zod, exits on failure).

GroupVariables
DatabaseDATABASE_URL
AuthSUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY
SquareSQUARE_APP_ID, SQUARE_APP_SECRET, SQUARE_ENVIRONMENT, SQUARE_WEBHOOK_SIGNATURE_KEY
CloverCLOVER_APP_ID, CLOVER_APP_SECRET, CLOVER_ENVIRONMENT, CLOVER_WEBHOOK_SECRET
EncryptionENCRYPTION_KEY (64 hex chars)
URLsAPI_BASE_URL, FRONTEND_URL
OpsCRON_SECRET, SENTRY_DSN, LOG_LEVEL, RESEND_API_KEY, RESEND_FROM_EMAIL

Deployment Guardrails

  1. Never reuse production Supabase project in non-prod environments
  2. Keep webhook URLs and signature keys environment-specific
  3. Validate Square and Clover *_ENVIRONMENT values match the credentials before OAuth testing
  4. Rotate secrets through deployment platform secret stores
  5. Run lint/typecheck/test before deploy promotion
  6. Confirm ENCRYPTION_KEY is set before configuring any POS OAuth

Deep Dives

Written byDhruv Doshi