Skip to main content
The Soundcheck API is an Encore.ts service (api-events/, port 4000) that is the system of record for the platform. It serves the full public HTTP API, owns PostgreSQL DDL, publishes domain events directly to Pub/Sub, and delegates notification delivery to processors. For platform-wide topology, see System Architecture.

Layer overview

Encore api(...) declarations stay thin: validate auth, call an operation, return a DTO. Operations hold business logic and Prisma access. Pub/Sub follows the same split — handlers/ wire topics to processors/.

Directory structure

Canonical DDL: api-events/src/db/schema.prisma + api-events/src/db/migrations/. Migrations apply on Encore boot and via npm run db:migrate.

Authentication & authorization

Clerk session JWT is the only caller auth path. ENABLE_BASIC_AUTH is removed and fails closed if set. /api/v1/admin/** is parked and 404s. Provisioning. Webhook and middleware paths ensure User, Organization, and membership rows exist before handlers run, closing the race where a request arrives before Clerk webhooks land. Organization authorization. Access is organization-scoped and role-based. Handlers resolve org scope from the authenticated identity — never from untrusted URL or query params. Fail-closed config. ENVIRONMENT must be set explicitly; production secret and CORS validation apply outside development.

Subsystems

  • Pub/Sub notifications. Operations currently publish directly; the business commit and publication are separate. A shared transactional outbox is the target architecture. Pub/Sub processors render and deliver SMS, email, and push. See api-events and the feature assessment.
  • Audit logging. Sensitive mutations write to per-domain audit tables via dedicated operations.
  • Event-file ingestion (UEF). Uploaded files and imports are extracted, analyzed, reviewed, and merged into events. Logic lives under systems/event-ingestions/.
  • HubSpot ↔ Flex pipeline (via n8n). Deal-stage and quote sync runs through n8n webhooks back into api-events.
  • Admin org-config console. Staff surfaces for seat/onboarding and entitlement grants under org-scoped admin routes.
  • Portal auth. Client-portal contacts authenticate through Clerk but are scope-resolved server-side so staff and portal sessions cannot cross-read.

Route registration

Every public path is declared as an Encore api(...) endpoint under src/systems/*/endpoints/ or src/webhooks/. api-events/routes.json holds each route’s domain override; unknown paths return Encore’s native 404. OpenAPI is emitted from Encore (npm run openapi:emit) and synced to docs/openapi/soundcheck.json for client codegen. The e2e/ suite enforces endpoint coverage when E2E_ENFORCE_COVERAGE=1.

Error handling

Errors return structured JSON with an HTTP status:

Best practices

  • Endpoints — keep thin; delegate to operations; return appropriate status codes.
  • Operations — own business logic and transactions; record required asynchronous intent durably according to the workflow contract. A shared outbox remains future implementation work.
  • Migrations — edit api-events/src/db/schema.prisma only; apply with npm run db:migrate or on boot.
  • Testing — unit-test operations with mocked Prisma (vi.mock); integration tests against Postgres on :5434; e2e against :4000.