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:
- secure headers
- CORS
- correlation ID
- DB context attachment
- request logger
- 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— paginatesListPayments, same ingestion pipeline - Webhook retry sweeper:
POST /api/v1/internal/cron/process-pending-webhooks— reprocessesprocessed=falseevents (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)
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