User profile
Purpose
Private per-user preferences (locale, birth date, notification channel toggles), kept 1:1 with the User record. Preferences only — the public-facing profile (bio, specializations, links, slug) lives on User public profile.
Business-level purpose: TBD by human.
Identity & key fields
- Primary key:
id(uuid, defaultgen_random_uuid()). userId(uuid, NOT NULL, UNIQUE, FK →users.users.id, on-delete cascade).language(nullable text) — preferred locale code.birthDate(nullable date).notificationsEnabled(boolean, defaulttrue) — master toggle.pushEnabled(boolean, defaulttrue).emailEnabled(boolean, defaultfalse).createdAt,updatedAt(timestamps, NOT NULL).
business meaning: TBD by human
Invariants
userIdis UNIQUE → at most one profile row per user (enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/users.schema.ts).userIdON DELETE CASCADE (enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/users.schema.ts).- All notification flags NOT NULL with explicit defaults (enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/users.schema.ts).
business invariants: TBD by human
Lifecycle
No explicit lifecycle — created lazily on first preference update or via signup hook.
Relationships
- User (ENT-021) —
userId→users.users.id, UNIQUE, on-delete cascade. 1:1. - User public profile (ENT-042) — sibling 1:1 extension of the same User. Distinct table because the two carry different responsibilities: this row is private preferences, the public profile is what other users see.
API surfaces
| Surface | Exposed | Notes |
|---|---|---|
| client | yes — /me/notification-preferences, /me (via UpdateMeDto, UpdateNotificationPrefsDto) | Swagger UI |
| business | no | — |
| super-admin | no | — |
Known gotchas / open questions
emailEnableddefaults tofalsewhile the other two channel toggles default totrue— a quiet UX choice. Confirm with product whether this is intentional.languageis free-form text — no enum / locale-validity check at DB level.