Backend Runtime
The backend runtime is implemented in apps/api using Hono and Node.js.
Startup Sequence
apps/api/src/index.ts performs startup in this order:
- Import
./lib/env.jsto validate environment variables at process start. - Initialize Sentry via
initSentry({ dsn, environment }). - Build app via
createApp(). - Start HTTP server with
@hono/node-serveronenv.PORT.
If env validation fails, startup exits immediately (process.exit(1)).
Middleware Chain
Defined in apps/api/src/app.ts.
Order is important and currently:
secureHeaders()cors({...})correlationMiddlewaredbMiddlewarehonoLogger()- Route-level middleware (
auth,rbac,tenant, profile-specific) - Global error handlers (
onError,onNotFound)
CORS and Allowed Headers
CORS is configured from CORS_ALLOWED_ORIGINS and explicitly allows:
AuthorizationContent-TypeIdempotency-KeyX-Correlation-Id
Credentials are allowed (credentials: true).
Route Topology
All routes are mounted under createApp().
Service and Health
GET /— root checkGET /health— health check
Versioned API groups
/api/v1/auth->authRouter/api/v1/consumer->consumerRouter/api/v1/client->clientRouter/api/v1/admin->adminRouter/api/v1/webhooks->webhooksRouter/api/v1/oauth->posOAuthRouter/api/v1/internal/cron->cronRouter
Complete Endpoint Reference
Auth (/api/v1/auth)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /me | authProfileMiddleware | Profile state for authenticated user |
Consumer (/api/v1/consumer)
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /wallets | WALLET_VIEW_OWN | List all wallets for user |
| GET | /wallets/:walletId | WALLET_VIEW_OWN | Single wallet detail |
| GET | /wallets/:walletId/history | WALLET_HISTORY_OWN | Ledger entries (limit capped at 100) |
| POST | /wallets/:walletId/redeem/preview | WALLET_REDEEM | Redemption preview calculation |
| POST | /wallets/:walletId/redeem/confirm | WALLET_REDEEM | Execute redemption with row lock |
Client (/api/v1/client)
| Method | Path | Permission | Description |
|---|---|---|---|
| POST | /bootstrap-merchant-workspace | TENANT_PROFILE_UPDATE | Idempotent workspace creation |
| GET | /tenants/:tenantId | TENANT_VIEW | Dashboard overview with stats |
| PATCH | /tenants/:tenantId/onboarding | TENANT_PROFILE_UPDATE | Update onboarding profile |
| GET | /tenants/:tenantId/pos-connections | TENANT_VIEW | List POS connections |
| POST | /tenants/:tenantId/pos-connections/square/connect | TENANT_POS_CONNECT | Initiate Square OAuth |
| POST | /tenants/:tenantId/pos-connections/clover/connect | TENANT_POS_CONNECT | Initiate Clover OAuth |
| DELETE | /tenants/:tenantId/pos-connections/:connectionId | TENANT_POS_CONNECT | Disconnect POS (soft delete) |
| GET | /tenants/:tenantId/reward-rules | TENANT_VIEW | List all reward rule versions |
| POST | /tenants/:tenantId/reward-rules | TENANT_REWARD_CONFIG | Create new reward rule version |
| GET | /tenants/:tenantId/transactions | TENANT_ANALYTICS_VIEW | Transaction feed (limit capped at 100) |
| GET | /tenants/:tenantId/consumers | TENANT_CONSUMER_VIEW | Wallet holders list |
| GET | /debug/square | TENANT_VIEW | Square config diagnostics (no secrets) |
Admin (/api/v1/admin)
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /tenants | ADMIN_TENANTS_VIEW_ALL | List all tenants (limit 200) |
| GET | /tenants/:tenantId | ADMIN_TENANTS_VIEW_ALL | Tenant detail with members and POS |
| POST | /wallets/:walletId/freeze | ADMIN_WALLET_FREEZE | Freeze wallet + audit log |
| POST | /wallets/:walletId/unfreeze | ADMIN_WALLET_FREEZE | Unfreeze wallet + audit log |
| POST | /wallets/:walletId/adjust | ADMIN_WALLET_ADJUST | Manual points adjustment + audit log |
| GET | /audit-logs | ADMIN_AUDIT_LOGS_VIEW | Immutable audit trail (limit 200) |
| GET | /users/search | ADMIN_USER_SEARCH | Search users or list pending approvals |
| PATCH | /users/:userId/approve | ADMIN_USER_SEARCH | Approve user + auto-provision workspace |
| PATCH | /users/:userId/role | ADMIN_USER_SEARCH | Change user role + audit log |
Webhooks (/api/v1/webhooks) — No JWT auth
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /square | HMAC signature | Square webhook receiver (fast-ack) |
| POST | /clover | HMAC signature | Clover webhook receiver (fast-ack) |
OAuth Callbacks (/api/v1/oauth) — No JWT auth
| Method | Path | Description |
|---|---|---|
| GET | /square/callback | Square OAuth code exchange + redirect |
| GET | /clover/callback | Clover OAuth code exchange + redirect |