apps/scheduler-api is the central API server powering all booking,
business management, billing, and orchestration. It exposes two surfaces:
a public REST API (contract-first, slug-scoped) and an admin tRPC surface
consumed by the portals.
Customer-facing. Contract-first via @nexus/scheduler-contracts — the Zod
schemas are the single source of truth. A schema drift is a runtime 500,
not a silent type mismatch.
Portal-facing (both portal and portal-business). End-to-end type-safe via
tRPC — types are inferred from the server router, never hand-written on the
client.
graph LR
subgraph "Inbound"
PB_IN[portal-business\nFastify BFF]
P_IN[portal\ntRPC client]
Sites[site-* / scheduler-sdk]
STR_WH[Stripe webhooks]
PBK_WH[Porkbun webhooks]
DIR_WH[Directus webhooks\n→ convergence trigger]
TMP_CB[Temporal activity callbacks]
end
SA[scheduler-api]
subgraph "Outbound"
DB[(Neon PostgreSQL\nDrizzle)]
RD[(Redis\nBullMQ jobs)]
TMP[Temporal\nworkflow starts]
VS_OUT[vendure-server\nGraphQL mutations]
DIR_OUT[directus REST API]
WOS_OUT[WorkOS API]
STR_OUT[Stripe API]
PBK_OUT[Porkbun API]
end
PB_IN --> SA
P_IN --> SA
Sites --> SA
STR_WH --> SA
PBK_WH --> SA
DIR_WH --> SA
TMP_CB --> SA
SA --> DB
SA --> RD
SA --> TMP
SA --> VS_OUT
SA --> DIR_OUT
SA --> WOS_OUT
SA --> STR_OUT
SA --> PBK_OUT
Key tables:businesses, bookings, staff_members, customers, services, availability_overrides, notification_log, notifications, chat_conversations, billing_invoice_mirror, business_billing_audit, platform_config (domain fields are columns on businesses, not a separate table)