Assignment Honorarium Record
Data Entity
Description
Tracks cumulative assignment counts per peer mentor and records when honorarium threshold milestones are crossed. Used by Blindeforbundet to calculate volunteer compensation at the 3rd assignment (office honorarium) and 15th assignment (higher rate) thresholds.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key — unique identifier for this honorarium threshold event record | PKrequiredunique |
user_id |
uuid |
Foreign key referencing the peer mentor (users table) whose assignment count triggered this record | required |
organization_id |
uuid |
Foreign key referencing the organization scope under which this threshold record applies — threshold configurations vary per organization | required |
assignment_count |
integer |
Cumulative number of completed assignments for this peer mentor within the organization at the time this record was created. Denormalized from assignments table via database trigger for fast threshold evaluation. | required |
threshold_crossed |
boolean |
Whether this record represents a threshold milestone crossing event (true) or a routine count update (false). Only threshold-crossing records trigger honorarium calculation and coordinator notifications. | required |
threshold_level |
enum |
The specific honorarium threshold tier crossed in this record. 'none' indicates a routine count update. 'office_honorarium' is the 3rd-assignment tier (kontorhonorar). 'higher_rate' is the 15th-assignment tier. 'custom' allows organizations to define additional tiers. | required |
threshold_assignment_number |
integer |
The specific assignment number that defines this threshold (e.g., 3 for office honorarium, 15 for higher rate). Stored explicitly to support organizations with different threshold configurations and for historical accuracy if configurations change. | - |
honorarium_rate |
decimal |
The honorarium rate (in NOK) applicable at the time this threshold was crossed, sourced from the organization's threshold configuration. Stored at event time for historical accuracy if rates are later updated. | - |
fiscal_year |
integer |
The calendar year in which this threshold was crossed. Used for annual honorarium reporting, payment batching, and Bufdir reporting period scoping. Derived from recorded_at but stored explicitly for query efficiency. | required |
payment_status |
enum |
Processing status of the honorarium payment triggered by this threshold crossing. Only relevant when threshold_crossed is true. | required |
payment_processed_at |
datetime |
Timestamp when the honorarium payment was confirmed as processed. Null until payment_status transitions to 'paid'. | - |
coordinator_notified |
boolean |
Whether the coordinator has been notified of this threshold crossing via push notification. Set to true after the threshold notification trigger dispatches the alert. | required |
coordinator_notified_at |
datetime |
Timestamp when the coordinator push notification was dispatched. Null until coordinator_notified transitions to true. | - |
trigger_assignment_id |
uuid |
Foreign key referencing the specific assignment record that triggered this threshold crossing or count update. Provides an audit trail linking the honorarium event to the originating activity. | - |
notes |
text |
Optional coordinator or admin notes attached to this honorarium record — for example, manual corrections, dispute context, or payment reference numbers. | - |
recorded_at |
datetime |
Timestamp when this honorarium record was created, set by the database trigger on assignment insert/delete. Authoritative event time for reporting and payment processing. | required |
created_at |
datetime |
Row creation timestamp managed by Supabase. | required |
updated_at |
datetime |
Row last-update timestamp, updated automatically on any field change. | required |
Database Indexes
idx_assignment_honorarium_records_user_org
Columns: user_id, organization_id
idx_assignment_honorarium_records_user_org_fiscal_year
Columns: user_id, organization_id, fiscal_year
idx_assignment_honorarium_records_threshold_crossed
Columns: user_id, organization_id, threshold_crossed, threshold_level
idx_assignment_honorarium_records_org_fiscal_year
Columns: organization_id, fiscal_year, threshold_crossed
idx_assignment_honorarium_records_payment_status
Columns: organization_id, payment_status, threshold_crossed
idx_assignment_honorarium_records_recorded_at
Columns: recorded_at
Validation Rules
user_must_be_active_peer_mentor
error
Validation failed
organization_id_required_and_valid
error
Validation failed
assignment_count_positive_integer
error
Validation failed
threshold_level_consistency
error
Validation failed
honorarium_rate_required_for_threshold_records
error
Validation failed
threshold_assignment_number_matches_level
error
Validation failed
fiscal_year_valid_range
error
Validation failed
recorded_at_not_in_future
error
Validation failed
payment_processed_at_requires_paid_status
error
Validation failed
notes_max_length
error
Validation failed
Business Rules
office_honorarium_at_third_assignment
When a peer mentor's cumulative assignment count reaches 3 within the organization scope, a threshold-crossing record with threshold_level='office_honorarium' must be created and the applicable honorarium rate recorded. This is Blindeforbundet's contractual kontorhonorar obligation.
higher_rate_at_fifteenth_assignment
When a peer mentor's cumulative assignment count reaches 15 within the organization scope, a threshold-crossing record with threshold_level='higher_rate' must be created. This supersedes the office honorarium rate and triggers the higher compensation tier.
no_duplicate_threshold_crossing_per_period
A given threshold_level for a user_id + organization_id + fiscal_year combination must appear at most once with threshold_crossed=true. Duplicate threshold-crossing records indicate a processing error and must be rejected.
coordinator_notification_on_threshold_cross
Whenever a threshold-crossing record is created (threshold_crossed=true), the assigned coordinator must be notified via push notification. The coordinator_notified flag must be set to true and coordinator_notified_at populated upon successful dispatch.
organization_scoped_threshold_configuration
Threshold numbers (assignment_threshold_number) and honorarium rates are loaded from the organization's configuration at the time of record creation, not hardcoded. This allows organizations other than Blindeforbundet to configure different threshold tiers.
count_decrement_on_assignment_cancellation
If an assignment is deleted or cancelled after a threshold-crossing record was created, and the count drops back below a threshold, the threshold record must be reviewed. The assignment_count field is decremented by the database trigger but the crossing record is NOT automatically deleted — a manual review flag may be set.
fiscal_year_isolation
Assignment counts and threshold milestones are tracked per fiscal_year. At the start of a new calendar year, the cumulative count resets for threshold evaluation purposes. Historical records are preserved for audit and Bufdir reporting.
payment_status_lifecycle
payment_status may only transition in the following sequence: not_applicable (non-threshold records) or pending → processing → paid | cancelled. Reverse transitions are not permitted. Transitions to 'paid' must populate payment_processed_at.
CRUD Operations
Storage Configuration
Entity Relationships
Honorarium records are scoped to an organization as threshold configurations vary per organization
A peer mentor accrues honorarium threshold records as assignment counts cross configured milestones