User
Data Entity
Description
Represents an authenticated system user account with a unique email address. Each user belongs to one or more organizations and is assigned one or more roles that determine their access scope. Users may also be represented as peer mentors, coordinators, or administrators depending on their role assignments.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Immutable primary key generated by Supabase Auth (auth.users.id). Serves as the foreign key anchor for all user-related tables including user_roles, sessions, notifications, and peer_mentor profiles. | PKrequiredunique |
email |
string |
The user's verified email address used for credential-based login and system notifications. Must be globally unique across all organizations. Supabase Auth owns this field; the application layer reads it from the session JWT claims. | requiredunique |
full_name |
string |
Display name of the user, sourced from BankID or Vipps identity verification if available, otherwise provided during registration. Used in notifications, audit trails, and coordinator-facing roster views. | - |
phone_number |
string |
Optional phone number for the user, may be retrieved from Vipps userinfo endpoint (phoneNumber claim). Stored in E.164 format. | - |
bankid_verified |
boolean |
Flag indicating whether the user has successfully completed BankID identity verification. When true, the associated personnummer_encrypted field is expected to be populated. Enables higher-trust workflows for organizations requiring verified identity. | required |
bankid_verified_at |
datetime |
UTC timestamp of the most recent successful BankID verification event. Null if bankid_verified is false. Used to enforce re-verification policies and displayed in admin audit views. | - |
personnummer_encrypted |
string |
AES-256 encrypted Norwegian national identity number (personnummer / fødselsnummer) obtained from Vipps NIN claim or BankID identity assertion. Encryption key is organization-scoped and managed via Supabase Vault. Required for Vipps-linked accounts where NIN is returned. Never returned in plain text via API. | - |
is_active |
boolean |
Soft-delete flag and account status indicator. When false the user cannot authenticate and all active sessions are invalidated. Set to false on account deactivation by an org_admin or global_admin. Does not delete any associated data. | required |
last_login_at |
datetime |
UTC timestamp of the user's most recent successful authentication event (email/password, BankID, Vipps, or biometric session resume). Updated on every successful auth. Exposed to org_admin for inactive user reporting. | - |
preferred_language |
string |
BCP-47 language tag for the user's preferred UI language. Defaults to 'nb' (Norwegian Bokmål). Used to localize push notification payloads, email notifications, and in-app content. | - |
avatar_url |
string |
URL pointing to the user's profile image stored in Supabase Storage. Falls back to initials-based avatar in the UI when null. Organization-scoped storage path. | - |
created_at |
datetime |
UTC timestamp when the user account was first created in Supabase Auth. Immutable after creation. Used for audit reporting and user lifecycle analytics. | required |
updated_at |
datetime |
UTC timestamp of the most recent modification to any mutable field on this record. Automatically maintained by a Supabase trigger. Used for cache invalidation in the terminology sync and role resolution services. | required |
Database Indexes
idx_user_email
Columns: email
idx_user_is_active
Columns: is_active
idx_user_bankid_verified
Columns: bankid_verified
idx_user_last_login_at
Columns: last_login_at
idx_user_created_at
Columns: created_at
Validation Rules
email_format
error
Validation failed
email_lowercase_normalization
error
Validation failed
personnummer_format
error
Validation failed
full_name_not_blank_if_provided
warning
Validation failed
phone_e164_format
warning
Validation failed
preferred_language_valid_bcp47
warning
Validation failed
avatar_url_valid_format
error
Validation failed
id_matches_supabase_auth
error
Validation failed
Business Rules
unique_email_globally
A user's email address must be unique across the entire Supabase Auth namespace. Attempting to register a second account with an existing email must be rejected at the Supabase Auth layer before reaching the application layer.
bankid_verification_immutability
Once bankid_verified is set to true and personnummer_encrypted is populated, these fields may only be updated by a global_admin or via an explicit re-verification flow. The application layer must not overwrite a verified NIN with a new value without coordinator or admin approval.
inactive_user_session_revocation
When is_active is set to false, all active Supabase sessions for the user must be revoked immediately. The auth-session-manager must call Supabase Auth admin.signOut(userId) and clear any cached tokens in secure storage.
global_admin_mobile_access_denied
Users whose only role assignment is global_admin must be redirected to the no-access screen after authentication. Global admins perform their work in the web-based admin portal, not the mobile app.
personnummer_encryption_required
The personnummer must never be stored in plain text. It must be encrypted with an organization-scoped key managed via Supabase Vault before being written to the personnummer_encrypted column. Decryption is only permitted in server-side contexts (Edge Functions).
single_account_per_email
A user may belong to multiple organizations but must use a single account (email address). Multi-organization membership is modeled through user_role records, not separate user accounts.
last_login_updated_on_auth
The last_login_at field must be updated to the current UTC timestamp on every successful authentication event regardless of method (email/password, BankID, Vipps, biometric resume).
CRUD Operations
Storage Configuration
Entity Relationships
A periodic summary is computed for and owned by a specific user (peer mentor or coordinator) for the relevant period
Each user has exactly one accessibility preferences record controlling font scale, contrast mode, and haptic feedback settings
A user may have FCM push tokens registered across multiple devices simultaneously
A user receives many notifications over their lifetime across all notification types
A user has one preference record per notification category controlling opt-in and opt-out state
A user account that holds the peer_mentor role is linked to exactly one peer_mentor profile record per organization
A user may have multiple active sessions across different devices for biometric re-authentication
Each user has exactly one preferences record storing last-used activity type, default duration, and notification settings
A user may hold multiple role assignments across different organizations (peer_mentor in one org, coordinator in another)