core PK: id 8 required 2 unique

Description

An extended profile for users who serve as peer mentors (likepersoner), supplementing the base user record with mentoring-specific fields such as certification status, assignment count, pause status, and location coordinates for geographic matching. One-to-one with user.

14
Attributes
7
Indexes
10
Validation Rules
55
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Surrogate primary key for the peer mentor profile record. Generated server-side on creation.
PKrequiredunique
user_id uuid Foreign key referencing the users table. Enforces the one-to-one relationship: one user has at most one peer mentor profile. Used as the join key in all mentor-context queries.
requiredunique
local_association_id uuid Foreign key referencing the local_associations table. Determines which local association this peer mentor primarily operates under for coordinator assignment, report scoping, and geographic map display. A mentor may have multi-association memberships in user_organization_roles, but this field stores the primary affiliation used for matching.
required
status enum Current operational status of the peer mentor. Controls visibility in coordinator tools, geographic map display, assignment eligibility, and website listing. Transitions are logged immutably in peer_mentor_status_logs.
required
assignment_count integer Denormalized running total of completed assignments for this peer mentor within the current honorarium period. Used by the threshold tracking system to evaluate when honorarium tiers are crossed (e.g., 3rd and 15th assignment for Blindeforbundet). Updated atomically on assignment completion or cancellation.
required
lat decimal WGS84 latitude coordinate for the peer mentor's primary location, geocoded from their registered address. Used by the geographic map view to display mentor pins and enable proximity-based matching by coordinators. Null until address is geocoded.
-
lng decimal WGS84 longitude coordinate for the peer mentor's primary location, geocoded from their registered address. Stored alongside lat for geographic queries and Haversine distance calculations.
-
certification_expires_at datetime Expiry datetime of the peer mentor's most recent active certification. Denormalized from the certifications table for fast status lookups without a join. The certification expiry scheduler evaluates this field nightly to trigger deactivation and reminder notifications. Set to null if no certification has been issued.
-
pause_reason text Free-text reason provided when the peer mentor status is set to 'paused' or 'suspended'. Displayed to coordinators in the pause status widget. Required when status transitions to 'paused'; null otherwise.
-
pause_expected_return_at datetime Optional expected return date when a peer mentor activates a pause. Used by coordinators to plan workload redistribution and by the automated reminder system to prompt status review near the return date.
-
is_visible_on_website boolean Controls whether this peer mentor appears on the organization's public-facing website listings. Automatically set to false when status transitions to 'deactivated' or when certification has expired (HLF requirement). Coordinators may also set this manually.
required
geocoded_address text The source address string that was geocoded to produce lat/lng. Stored to detect when the address changes and coordinates need to be refreshed. May differ from the user's current registered address if geocoding is asynchronous.
-
created_at datetime Timestamp when the peer mentor profile was first created, typically coinciding with role assignment by a coordinator or administrator. Immutable after creation.
required
updated_at datetime Timestamp of the most recent modification to any field on this record. Updated automatically on every write. Used for optimistic concurrency control and sync conflict detection.
required

Database Indexes

idx_peer_mentor_user_id
btree unique

Columns: user_id

Enforces one-to-one relationship with users and enables O(1) lookup by user_id from JWT claims.

idx_peer_mentor_local_association_id
btree

Columns: local_association_id

Supports coordinator queries fetching all mentors for a given local association — the most common access pattern in team reports and map views.

idx_peer_mentor_status
btree

Columns: status

Supports filtering mentors by status for coordinator dashboards, pause management screens, and nightly certification expiry jobs.

idx_peer_mentor_association_status
btree

Columns: local_association_id, status

Composite index for the common query pattern: 'get all active mentors for association X' used in coordinator team reports and map view.

idx_peer_mentor_certification_expires_at
btree

Columns: certification_expires_at

Supports nightly certification expiry scheduler queries that scan for mentors with certification_expires_at < now() and status = 'active'.

idx_peer_mentor_lat_lng
btree

Columns: lat, lng

Enables geographic bounding box queries for the map view coordinator screen. A GiST index on a point expression may be added as a future optimization if query volume warrants it.

idx_peer_mentor_assignment_count
btree

Columns: local_association_id, assignment_count

Supports honorarium threshold queries that rank or filter mentors by assignment count within a local association for Blindeforbundet's honorarium tier system.

Validation Rules

user_id_exists error

Validation failed

local_association_id_exists error

Validation failed

status_enum_valid error

Validation failed

assignment_count_non_negative warning

Validation failed

lat_range_valid error

Validation failed

lng_range_valid error

Validation failed

lat_lng_both_or_neither error

Validation failed

certification_expires_at_future_on_set error

Validation failed

pause_expected_return_future error

Validation failed

pause_fields_cleared_on_resume error

Validation failed

Business Rules

one_to_one_user_constraint
on_create

Each user may have at most one peer mentor profile. A peer mentor profile cannot exist without a corresponding user record. Attempting to create a second profile for the same user_id must raise a conflict error.

valid_status_transition
on_update

Status transitions must follow the allowed state machine: active → paused, active → suspended, active → deactivated, paused → active, paused → deactivated, suspended → active, suspended → deactivated. Transitions from deactivated to any other state require administrator action and a new status log entry. Direct transitions that skip states (e.g., paused → suspended) are not permitted.

certification_expiry_auto_deactivation
on_update

When a peer mentor's certification_expires_at date is in the past and their status is 'active' or 'paused', the nightly certification expiry job must automatically transition their status to 'deactivated', set is_visible_on_website to false, write a status log entry with reason 'certification_expired', and dispatch a coordinator notification. This is a non-negotiable HLF requirement.

website_visibility_sync
on_update

Whenever status transitions to 'deactivated', is_visible_on_website must be set to false in the same transaction. When status transitions back to 'active', is_visible_on_website is NOT automatically restored — a coordinator must manually re-enable it to prevent premature re-listing of mentors whose deactivation reason may not have been fully resolved.

pause_reason_required
on_update

When status transitions to 'paused', a non-empty pause_reason must be provided. The system must reject status change requests that omit or provide a blank reason string.

coordinator_notification_on_status_change
on_update

Every status transition (pause activation, pause lift, deactivation) must trigger a push notification to all coordinators associated with the mentor's local_association_id. This ensures coordinators are aware of availability changes without manual follow-up.

assignment_count_honorarium_threshold
on_update

When assignment_count is incremented to a value that crosses a configured honorarium threshold for the mentor's local association (e.g., 3rd or 15th for Blindeforbundet), a threshold-crossing domain event must be emitted. The honorarium notification service handles coordinator alerting. The assignment_count field must never be decremented below 0.

geocoding_on_address_change
on_update

When a user's registered address changes (via the users table), the peer mentor's lat, lng, and geocoded_address fields must be refreshed asynchronously via the geocoding infrastructure. The update is not blocking — coordinates may temporarily be stale until geocoding completes.

inactive_mentors_excluded_from_map
always

Peer mentors with status 'paused', 'suspended', or 'deactivated' must not appear in geographic map view results returned to coordinators. The peer-mentor-location-repository must filter by status = 'active' in all map coordinate queries.

assignment_count_atomic_update
on_update

Increments and decrements to assignment_count must be applied atomically using database-level locking or optimistic concurrency (compare-and-swap). Race conditions during concurrent assignment completions must not result in an incorrect final count.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
No Partitioning
Retention
Permanent Storage

Entity Relationships

local_association
incoming one_to_many

A local association has many peer mentors operating within it

required
annual_summary
outgoing one_to_many

A peer mentor profile links to its annual summaries enabling quick lookup for the Wrapped feature

optional
assignment
outgoing one_to_many

A peer mentor is the recipient of many encrypted assignments dispatched by coordinators

required
certification
outgoing one_to_many

A peer mentor profile is directly associated with its certifications for fast expiry status lookups

optional
peer_mentor_status_log
outgoing one_to_many

A peer mentor has a full history of status transitions (active, paused, suspended, deactivated)

required
user
incoming one_to_one

A user who serves as a peer mentor has exactly one extended peer mentor profile

optional cascade delete

Components Managing This Entity

service Identity Verification Service ["backend"] service Proxy Registration Service ["mobile","backend"] ui Bulk Registration Screen ["mobile"] ui Peer Mentor Selection Screen ["mobile"] data Contact Repository ["mobile"] service Contact Service ["mobile"] ui Contacts List Screen ["mobile"] data Contact Repository ["mobile"] service Contact Service ["mobile"] data Peer Mentor Repository ["mobile"] service Peer Mentor Service ["mobile","backend"] ui Peer Mentor Card Widget ["mobile"] ui Peer Mentor Detail Screen ["mobile"] data Peer Mentor Status Repository ["backend"] infrastructure Certification Expiry Background Job ["backend"] service Pause Mentor Service ["backend"] service Pause Notification Service ["backend"] ui Pause Status Widget ["mobile","frontend"] ui Pause Toggle Screen ["mobile","frontend"] data Peer Mentor Location Repository ["backend"] infrastructure Geocoding API Infrastructure ["backend"] service Location Service ["mobile","backend"] ui Map View Screen ["mobile"] ui Mentor Bottom Sheet Widget ["mobile"] ui Mentor Map Pin Widget ["mobile"] data Team Report Repository ["backend"] service Team Report Service ["mobile","backend"] ui Peer Mentor Summary Row Widget ["mobile"] service Duplicate Detection Service ["backend"] data Honorarium Repository ["backend"] infrastructure Assignment Counter Cache ["backend"] service Honorarium Notification Service ["backend"] service Threshold Tracking Service ["backend"] ui Assignment Counter Widget ["frontend","mobile"] ui Threshold Alert Banner ["frontend","mobile"] data Dashboard Repository ["mobile"] service Dashboard Service ["mobile"] ui Home Screen (Coordinator) ["mobile"] ui Home Screen (Peer Mentor) ["mobile"] service User Management Service ["backend"] data Analytics Repository ["backend"] service Analytics Service ["backend"] ui Admin Dashboard Screen ["frontend"] service Certification Service ["backend"] service Annual Summary Aggregation Job ["backend"] service Annual Summary Service ["mobile","backend"] data Local Cache Repository ["mobile"] infrastructure Local Database Infrastructure ["mobile"] service Sync Service ["mobile"]