Peer Mentor
Data Entity
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.
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
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
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
Columns: status
Supports filtering mentors by status for coordinator dashboards, pause management screens, and nightly certification expiry jobs.
idx_peer_mentor_association_status
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
CRUD Operations
Storage Configuration
Entity Relationships
A local association has many peer mentors operating within it
A peer mentor profile links to its annual summaries enabling quick lookup for the Wrapped feature
A peer mentor is the recipient of many encrypted assignments dispatched by coordinators
A peer mentor profile is directly associated with its certifications for fast expiry status lookups
A peer mentor has a full history of status transitions (active, paused, suspended, deactivated)
A user who serves as a peer mentor has exactly one extended peer mentor profile