Peer Mentor
Data Entity
Description
Profile record for a peer mentor (likeperson), the primary subject of coordinator bulk registration and the actor who creates activity records. Drives accessibility-aware form flows throughout the app and is referenced for activity attribution, role-based access, and certification tracking.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Surrogate primary key, generated on insert. Used as the canonical reference across all foreign keys in activity, accessibility_preferences, user_preferences, and related tables. | PKrequiredunique |
user_id |
uuid |
Foreign key to the Supabase auth.users table. Nullable to allow coordinator-created proxy mentor records that have not yet been linked to a registered app user. Must be unique per organisation to prevent one auth account holding two mentor profiles in the same org. | - |
organisation_id |
uuid |
Foreign key to the organizations table. Scopes the peer mentor record to a single organisation. All row-level security policies key on this column. | required |
full_name |
string |
Display name of the peer mentor as it appears in coordinator lists, activity attribution banners, proxy audit badges, and Bufdir export rows. Must not be empty. | required |
status |
enum |
Current operational status of the peer mentor. Drives visibility in assignment pools, coordinator rosters, and HLF public website sync. State transitions are enforced by MentorStatusService. | required |
is_paused |
boolean |
Denormalised flag derived from status. True when status is 'paused' or 'expired_cert'. Kept as a separate column for fast index-based filtering in coordinator roster queries and assignment pool lookups without a CASE expression. | required |
paused_at |
datetime |
UTC timestamp when the most recent pause was activated, either by the mentor themselves or auto-triggered by certification expiry. Null when status is active or resigned. | - |
pause_reason |
string |
Optional free-text reason provided by the peer mentor or coordinator when activating a pause. Displayed in the coordinator's pause status banner and notification payload. Max 200 characters per notification payload constraint. | - |
expected_return_date |
datetime |
Optional date the peer mentor expects to reactivate. Displayed in the coordinator pause roster and used by assignment planning. Must be in the future at the time of writing. | - |
certification_expiry |
datetime |
Expiry date of the peer mentor's active certification. Mandatory for HLF organisations where expired certification triggers auto-pause and suppression from the public website. Null for organisations that do not use the certification module (NHF, Blindeforbundet). | - |
certification_type |
string |
Type identifier for the certification (e.g., 'hlf_peer_mentor_v2'). Determines which renewal workflow is triggered and which badge criteria apply. Null when certification module is disabled for the organisation. | - |
renewal_history |
json |
Append-only JSONB array of certification renewal events. Each entry contains issued_at, expires_at, renewed_by (user_id), and notes. Consumed by the certification status screen's renewal history timeline and HLF Dynamics sync on renewal. | - |
is_visible_on_website |
boolean |
Controls whether HLF syncs this mentor to the public Dynamics website listing. Automatically set to false when status transitions to paused or expired_cert, and restored to true on reactivation via HlfWebsiteSyncService. | required |
primary_chapter_id |
uuid |
Reference to the peer mentor's primary chapter within the organisation hierarchy. Used for coordinator scoping, stats aggregation, and Bufdir geographic distribution. Nullable for organisations with flat structures. | - |
email |
string |
Contact email address for the peer mentor. May differ from auth user email if the mentor was registered by a coordinator. Used for coordinator-initiated notifications and accounting export identifiers. | - |
phone |
string |
Mobile phone number in E.164 format. Used for SMS fallback notifications and contact list display. Optional but recommended for Blindeforbundet assignment flows. | - |
bankid_verified |
boolean |
True when the peer mentor has successfully completed BankID or Vipps identity verification. Used by coordinators as a trust signal and required for certain sensitive data flows. | required |
personnummer |
string |
Norwegian national identity number (fødselsnummer) retrieved from Vipps OAuth nin claim. Stored encrypted at rest using Supabase Vault. Used to link Vipps login to existing member records. Nullable until Vipps login is completed. | - |
birth_year |
integer |
Year of birth, derived from personnummer for Bufdir demographic reporting. Stored separately to allow anonymised queries without decrypting the full personnummer. | - |
summaries |
json |
JSON string containing three audience-specific summaries (executive, project_manager, developer) generated by the SummaryGenerationManager pipeline. Consumed by peer mentor detail pages and coordinator statistics views. | - |
created_at |
datetime |
UTC timestamp of record creation. Immutable after insert. | required |
updated_at |
datetime |
UTC timestamp of the last field update. Updated automatically by a Supabase trigger on every row mutation. | required |
Database Indexes
idx_peer_mentor_user_id
Columns: user_id
idx_peer_mentor_organisation_id
Columns: organisation_id
idx_peer_mentor_organisation_status
Columns: organisation_id, status
idx_peer_mentor_organisation_is_paused
Columns: organisation_id, is_paused
idx_peer_mentor_certification_expiry
Columns: certification_expiry
idx_peer_mentor_primary_chapter
Columns: primary_chapter_id
idx_peer_mentor_user_organisation
Columns: user_id, organisation_id
Validation Rules
full_name_non_empty
error
Validation failed
organisation_id_references_active_org
error
Validation failed
user_id_references_valid_auth_user
error
Validation failed
status_enum_value
error
Validation failed
email_format_when_present
error
Validation failed
phone_e164_format_when_present
error
Validation failed
personnummer_11_digits_when_present
error
Validation failed
certification_expiry_valid_date
error
Validation failed
birth_year_plausible_range
error
Validation failed
pause_reason_no_pii
warning
Validation failed
Business Rules
status_state_machine
Status transitions are restricted to valid paths: active → paused (manual), active → expired_cert (auto via nightly job), active → resigned (admin), paused → active (manual reactivation), expired_cert → paused (if cert not renewed), expired_cert → active (on renewal), any → inactive (admin soft-delete). Direct transition from paused to resigned is blocked.
is_paused_consistency
The is_paused flag must always be consistent with the status field. is_paused = true when status IN ('paused', 'expired_cert'). Enforced via a Supabase database trigger that sets is_paused automatically on any status change to avoid the two columns drifting.
hlf_auto_pause_on_cert_expiry
For HLF organisations, when certification_expiry passes midnight UTC, the nightly certification-expiry-job must transition status from 'active' to 'expired_cert', set is_paused = true, and trigger coordinator notification. This is organisation-scoped and must not run for NHF or Blindeforbundet records.
hlf_website_visibility_sync
For HLF, is_visible_on_website must be false whenever status is 'paused' or 'expired_cert'. On any status transition, HlfWebsiteSyncService must call the Dynamics portal API to synchronise visibility. Failures are retried with exponential backoff; persistent failures raise an alert.
coordinator_notification_on_status_change
Every status transition must trigger a push notification and in-app notification to the coordinator(s) responsible for the peer mentor. The notification payload includes mentor name, new status, effective date, and optional pause reason.
unique_user_per_organisation
A single auth user (user_id) may not hold two active peer_mentor records within the same organisation. The unique index on (user_id, organisation_id) enforces this at the database level. Coordinators may create mentor records without a user_id for proxy-only mentors.
pause_reason_max_length
pause_reason must not exceed 200 characters, matching the PauseNotificationPayloadBuilder constraint that composes coordinator notification messages from this field.
expected_return_date_must_be_future
expected_return_date, when provided, must be strictly greater than the current UTC timestamp at write time. It is informational and does not automatically trigger reactivation.
renewal_history_append_only
Entries in the renewal_history JSONB array may only be appended, never deleted or mutated, to preserve an immutable audit trail of all certification renewals. The CertificationManagementService enforces this by always calling appendRenewalHistory and never replacing the field wholesale.
activity_attribution_requires_active_or_paused_mentor
Activities may only be attributed to peer mentors with status 'active' or 'paused'. Resigned or inactive mentors cannot receive new activity attributions. Coordinator proxy flows must validate this before submission.
organisation_scoped_rls
All queries against the peer_mentor table must be scoped by organisation_id via Supabase row-level security. The Supabase RLS tenant configurator injects app.current_org_id into the session before any query executes. Cross-org access is only permitted for super_admin role via the admin-rls-guard bypass.
CRUD Operations
Storage Configuration
Entity Relationships
A certification record belongs to exactly one peer mentor and tracks the full HLF certification lifecycle including renewal history
A peer mentor is the attributed actor for all activities they conduct, regardless of whether they self-registered or a coordinator registered on their behalf
A peer mentor has one annual summary record per year for the Wrapped impact feature, supporting multiple period types per year
A peer mentor holds multiple active and historical assignments to contacts across their service tenure
An HLF peer mentor has exactly one current certification record tracking issue date, expiry, and renewal history
A peer mentor accumulates earned badges over time as activity and engagement milestones are reached
A peer mentor has one stats snapshot record that is recomputed on each activity event for gamification and dashboard display
A peer mentor has periodic summaries generated for each half-year and quarterly period they are active
A peer mentor may have multiple referral codes over time (active plus rotated/invalidated historical codes) for membership recruitment tracking
A peer mentor receives scenario prompts when the rule engine detects trigger conditions in their activity data
A user account that holds the peer_mentor role is linked to exactly one peer_mentor profile record per organization