Skip to main content

System Architecture Overview

This overview reflects the current implementation in salesarck_code.

Runtime Components

API Composition

apps/api/src/app.ts wires middleware and route groups:

  • /api/v1/auth
  • /api/v1/consumer
  • /api/v1/pos (POS operator code verification)
  • /api/v1/client
  • /api/v1/admin
  • /api/v1/webhooks
  • /api/v1/oauth
  • /api/v1/internal/cron

Global middleware order:

  1. secure headers
  2. CORS
  3. correlation ID
  4. DB context attachment
  5. request logger
  6. route guards

Security Boundary Model

Identity

Supabase verifies bearer token identity server-side.

Authorization

SalesArck computes role and tenant membership from internal tables.

Tenant Isolation

Tenant context is derived from URL parameter + server-side claims, never body/query payload.

Permission Model

RBAC permissions are explicit and route-attached. 17 permissions across 4 roles.

Data and Domain Model

14 tables in PostgreSQL:

  • users and tenant membership + operator invites
  • POS connections and raw webhooks
  • transactions and reward rules + reward events
  • wallets, append-only ledger, and redemption codes
  • idempotency keys and admin audit logs

See Data Model and Migrations for full schema details.

Event Processing Architecture

Recovery paths:

  • Square poll fallback: POST /api/v1/internal/cron/square-poll-payments — paginates ListPayments, same ingestion pipeline
  • Webhook retry sweeper: POST /api/v1/internal/cron/process-pending-webhooks — reprocesses processed=false events (both Square and Clover); only Clover recovery path

Frontend Architecture

Single web app (apps/web) serves all four personas through layered route guards and role-based navigation shells (sidebar, topbar, or bottom-tab bar depending on role).

Key characteristics:

  • PKCE callback recovery routing
  • Profile state fetch with retries and coalescing (400ms → 12s backoff)
  • Onboarding gating for merchant users until POS preference is set
  • API-backed pages for admin/client/consumer/pos_operator workflows
  • Session storage for Supabase session (isolated per browser window)

See Frontend Architecture.

Operational Architecture Notes

  • Sentry initialization occurs at API startup.
  • Pino logger redacts common PII fields.
  • Every API response includes X-Correlation-Id.
  • OAuth tokens (Square and Clover) are AES-256-GCM encrypted at rest.
  • Tenant logos stored in Supabase Storage; path persisted in tenants.branding_logo_path.
  • Worker app (apps/workers) exists as scaffold for durable queue-based async phase.

Canonical Deep Dives

Written byDhruv Doshi