Expense
Data Entity
Description
Records travel and reimbursement expense claims submitted by peer mentors, including kilometer allowance, tolls, parking, and public transit costs, linked to activities and subject to approval workflows.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key | PKrequiredunique |
user_id |
uuid |
Peer mentor who submitted the expense | required |
activity_id |
uuid |
Activity this expense is associated with | - |
organization_id |
uuid |
Organization the expense belongs to (derived from user context) | required |
expense_type_id |
uuid |
Type of expense selected from org-configured fixed list | required |
amount |
decimal |
Monetary amount claimed in NOK | required |
distance_km |
decimal |
Distance in kilometers for kilometer-allowance expense types | - |
description |
text |
Optional notes about the expense | - |
expense_date |
datetime |
Date the expense was incurred | required |
status |
enum |
Approval status of the expense | required |
requires_receipt |
boolean |
Whether a receipt is required for this expense (set based on amount threshold and expense type) | required |
auto_approved |
boolean |
Whether the expense was approved automatically by auto-approval rules | required |
approved_by_user_id |
uuid |
User (coordinator/admin) who manually approved or rejected the expense | - |
approved_at |
datetime |
Timestamp when the expense was approved or rejected | - |
rejection_reason |
text |
Coordinator's reason for rejecting the expense | - |
confidentiality_declaration_id |
uuid |
Reference to confidentiality declaration if expense involves driver role | - |
submitted_at |
datetime |
Timestamp when expense was submitted | required |
created_at |
datetime |
Record creation timestamp | required |
updated_at |
datetime |
Record last update timestamp | required |
offline_id |
string |
Client-generated ID for offline-created expenses before server sync | - |
Database Indexes
idx_expenses_user_id
Columns: user_id
idx_expenses_activity_id
Columns: activity_id
idx_expenses_organization_id
Columns: organization_id
idx_expenses_status
Columns: status
idx_expenses_org_status
Columns: organization_id, status
idx_expenses_user_date
Columns: user_id, expense_date
idx_expenses_expense_date
Columns: expense_date
Validation Rules
amount_positive
error
Validation failed
expense_date_not_future
error
Validation failed
expense_type_required
error
Validation failed
distance_required_for_km_type
error
Validation failed
valid_expense_type_for_organization
error
Validation failed
rejection_reason_required
error
Validation failed
Business Rules
receipt_required_above_threshold
Expenses above 100 NOK require at least one receipt photo to be attached before submission
mutually_exclusive_expense_types
Certain expense type combinations are forbidden (e.g. kilometer allowance and public transit ticket cannot both be claimed for the same trip). The fixed expense type list prevents invalid combinations at the UI level.
auto_approve_under_threshold
Expenses meeting org-configured auto-approval criteria (e.g. under 50 km / no receipts) are automatically approved without manual coordinator review
confidentiality_declaration_required_for_driver
When expense type is driver-related (sjåfør), a confidentiality declaration must be completed before the expense can be submitted
only_submitter_can_cancel
An expense can only be cancelled by the peer mentor who submitted it, and only while it is in pending status
approved_expense_immutable
Once an expense is approved or rejected, its amount, type, and date cannot be modified
organization_isolation
Expenses are scoped to the submitting user's organization and cannot be viewed or approved by users of other organizations