Users & Auth — Code Map
API
Auth module (apps/api/src/auth/)
| File | Purpose |
|---|---|
auth.module.ts | Global module. Provides CLERK_CLIENT token (Clerk SDK), injected anywhere as @Inject(CLERK_CLIENT) private clerk: ClerkClient. |
auth.guard.ts | Global AuthGuard (registered in AppModule). Verifies bearer JWT via @clerk/backend.verifyToken, attaches request.auth = {userId, sessionId, user}. Test bypass for non-prod. |
current-user.decorator.ts | `@CurrentUser(‘userId' |
public.decorator.ts | @Public() marks a handler as outside the AuthGuard. |
auth.guard.unit.spec.ts | Coverage of verify + test-bypass + bearer parsing. |
Users module (apps/api/src/users/)
| File | Purpose |
|---|---|
users.module.ts | Exports UsersService. |
users.controller.ts | Routes /users/me, /users/me (PATCH), /users/me (DELETE), /users/:id. |
users.service.ts | findOrCreateFromClerk, findByClerkId (30s cache), syncFromClerk, syncToClerk, updateProfile, isProfileComplete, deleteSelf, hasOutstandingConsents, national ID helpers. |
national-id-encryption.service.ts | Envelope encryption for Israeli ID. |
dto/update-profile.dto.ts | All editable fields + Israeli ID/phone/DOB validators (isValidIsraeliId, isValidDob, normalizeIsraeliPhone). |
validation.unit.spec.ts | National ID + phone + DOB validators. |
Webhooks module (apps/api/src/webhooks/)
| File | Purpose |
|---|---|
webhooks.module.ts | Wires controller. |
clerk-webhook.controller.ts | POST /webhooks/clerk — @Public() + Svix verify. Dispatches user.created, user.updated, user.deleted. |
Routes
| Method | Path | Handler |
|---|---|---|
| GET | /users/me | UsersController.getMe |
| PATCH | /users/me | UsersController.updateMe |
| DELETE | /users/me | UsersController.deleteMe |
| GET | /users/:id | UsersController.getById (self-only) |
| POST | /webhooks/clerk | ClerkWebhookController.handleWebhook |
Web
Routes (auth)
| Route | Description |
|---|---|
apps/web/src/app/[lang]/(auth)/sign-in/[[...sign-in]]/page.tsx | Clerk sign-in. |
apps/web/src/app/[lang]/(auth)/sign-up/[[...sign-up]]/page.tsx | Clerk sign-up. |
apps/web/src/app/[lang]/auth/reset/... | Password reset (Clerk-hosted). |
apps/web/src/app/[lang]/(protected)/complete-profile/... | Profile completion form (if profileComplete=false). |
apps/web/src/app/[lang]/(protected)/accept-terms/... | Legal consents gate (if pendingLegalConsents=true). |
Middleware
apps/web/src/middleware.ts — uses clerkMiddleware from @clerk/nextjs/server. Protects all locale-prefixed paths under (protected)/. Skips API routes and tRPC. Resolves locale via cookie / Negotiator.
Components
apps/web/src/components/protected-shell.tsx— wraps Clerk’sUserProviderand role-router.apps/web/src/components/role-router.tsx— routes user to/dashboard/overview(owner/admin/coach) or/(member) based on memberships.apps/web/src/components/guest/— guest user menu, prefs.apps/web/src/components/legal/legal-acceptance-form.tsx— consents UI used in onboarding and in the accept-terms route.
DB tables
| Table | Used as |
|---|---|
users | Owned. Global identity. |
memberships | Joined to users; counts toward org access. |
device_tokens | Push notification targets; soft-deleted on user delete. |
subscriptions | Cancelled on user delete. |
legal_documents / legal_consents | Read by hasOutstandingConsents. |
member_profiles | Per-(user, org) extended profile. |
Shared schemas
UserResponseinlibs/shared/src/lib/schemas/user.schema.ts— includesprofileComplete,pendingLegalConsents,nationalIdMasked.UserWithMembershipsResponse— same plusmemberships[].normalizeIsraeliPhone,isValidIsraeliId,isValidDob,normalizeIsraeliId,relationshipValues— validators.
Tests
| File | What it covers |
|---|---|
apps/api/src/auth/auth.guard.unit.spec.ts | JWT verify, test bypass, bearer parsing. |
apps/api/src/users/national-id-encryption.service.unit.spec.ts | Encrypt/decrypt + mask. |
apps/api/src/users/validation.unit.spec.ts | Profile validators. |
apps/web/e2e/ | Clerk auth flows are stubbed via usePersona + storageState (see CLAUDE.md “E2E Driver Pattern”). |