tRPC route catalogue
The api and data-provider expose tRPC routers under presentation/.
This page enumerates the routers; precise input / output shapes live
with the code (packages/business/shared/src/ for the wire DTOs).
api (apps/backend/api)
Section titled “api (apps/backend/api)”Located in apps/backend/api/src/presentation/routers/.
Auth: every router except the user-facing magic-link entry points
requires a Better-Auth session cookie. The jobs router additionally
requires an HMAC signature using JOBS_HMAC_SECRET.
data-provider (apps/backend/data-provider)
Section titled “data-provider (apps/backend/data-provider)”Located in apps/backend/data-provider/src/presentation/routers/.
Composed in apps/backend/data-provider/src/presentation/router.ts.
Auth column: Bearer = DATA_PROVIDER_API_KEY (every api / worker call). Cookie = Better-Auth session, only available when CLOUD_MANAGEMENT_ENABLED=true and the data-provider is fronted by the cloud-frontend. Public = no auth (rate-limited per-IP).
Wire contracts
Section titled “Wire contracts”Input / output shapes are zod schemas in
packages/business/shared/src/. Every router’s payload schema is
also the source of truth for the SPA’s tRPC client types.
How calls are gated
Section titled “How calls are gated”Three gates fire in order:
- Bearer / cookie auth. No bearer / cookie →
UNAUTHORIZED. - Capability gate. A call needing a provider key (e.g.
ai.parseScreenshotneedsOPENAI_API_KEY) returnsPRECONDITION_FAILEDwhen unconfigured. - Rate limit. Per-provider rate limiter
(
@scani/rate-limiter) returnsTOO_MANY_REQUESTSwhen the upstream’s quota is hit. The api retries via BullMQ’s retry policy.
Adding a new router
Section titled “Adding a new router”- Create the router file in the appropriate
src/presentation/routers/directory. - Define the input / output zod schema in
packages/business/shared/src/. - Register the router in the app’s root router (
index.tsalongside the existing routers). - The SPA’s tRPC client picks it up automatically via the end-to-end-typed client factory.