Webhooks — Code Map
Module
apps/api/src/webhooks/webhooks.module.ts— importsUsersModuleandMembershipsModule; registers the Clerk controller.
Controller
apps/api/src/webhooks/clerk-webhook.controller.ts— single@Public() POST /webhooks/clerkhandler. Verifies the Svix signature, switches onevent.type, delegates to user/membership services.
Dependencies
apps/api/src/users/users.service.tsfindOrCreateFromClerk(clerkId)— creates/loads the DB user.syncFromClerk(clerkId, { email, imageUrl })— mirrors Clerk profile.deleteSelf(clerkId, { skipClerk: true })— soft-deletes the local row.
apps/api/src/memberships/memberships.service.tsacceptPendingInvitations(clerkId)— promotesinvitedmemberships toactiveon first sign-up.
apps/api/src/event-tracking/event-tracking.service.tsidentify(userId, props)+track(userId, event, props)— PostHog fanout.
Raw body capture
apps/api/src/main.ts— expressjsonparser is configured with averifyhook that stashesreq.rawBody = bufso Svix can re-hash the exact bytes.
Env
CLERK_WEBHOOK_SECRET— set inapps/api/.env. Provided by the Clerk dashboard.
Schema
libs/db/src/lib/schema/users.ts—userstable.libs/db/src/lib/schema/memberships.ts—membershipstable (status enum).
Payment provider webhooks (related, not part of this module)
apps/api/src/payments/providers/cardcom.provider.tsapps/api/src/payments/providers/morning.provider.tsapps/api/src/payments/providers/bit.provider.ts- Each exposes its own
@Public()controller endpoint.