Reimbursements
Data Entity
Description
Tracks the financial payout status of approved expense claims, linking each approved expense to its reimbursement lifecycle including payment scheduling, execution, and accounting export reconciliation.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Unique identifier for the reimbursement record | PKrequiredunique |
expense_id |
uuid |
Foreign key to the approved expense claim this reimbursement fulfills | requiredunique |
user_id |
uuid |
The peer mentor or coordinator receiving the reimbursement payment | required |
organization_id |
uuid |
Organization responsible for the reimbursement, used for tenant isolation | required |
amount |
decimal |
Reimbursement amount in NOK, copied from the approved expense total at approval time | required |
currency |
enum |
Currency code for the reimbursement amount | required |
status |
enum |
Current state in the reimbursement lifecycle | required |
payment_method |
enum |
How the reimbursement is paid out to the recipient | - |
bank_account_number |
string |
Recipient bank account number for direct transfer (Norwegian format) | - |
payment_reference |
string |
External payment reference ID from bank or accounting system for reconciliation | - |
accounting_export_id |
uuid |
Foreign key to the accounting export batch that included this reimbursement | - |
scheduled_date |
datetime |
Date when the reimbursement is scheduled for payment | - |
paid_date |
datetime |
Date when the reimbursement was actually paid out | - |
failure_reason |
text |
Reason for payment failure if status is failed | - |
notes |
text |
Administrative notes about the reimbursement | - |
approved_by |
uuid |
User ID of the administrator who approved the underlying expense | - |
approved_at |
datetime |
Timestamp when the underlying expense was approved, triggering reimbursement creation | - |
period_start |
datetime |
Start of the reporting period this reimbursement falls within | - |
period_end |
datetime |
End of the reporting period this reimbursement falls within | - |
created_at |
datetime |
Timestamp when the reimbursement record was created | required |
updated_at |
datetime |
Timestamp of the last update to this reimbursement record | required |
Database Indexes
idx_reimbursements_expense_id
Columns: expense_id
idx_reimbursements_user_id
Columns: user_id
idx_reimbursements_organization_id
Columns: organization_id
idx_reimbursements_status
Columns: status
idx_reimbursements_org_status
Columns: organization_id, status
idx_reimbursements_org_period
Columns: organization_id, period_start, period_end
idx_reimbursements_paid_date
Columns: paid_date
idx_reimbursements_accounting_export
Columns: accounting_export_id
idx_reimbursements_user_org_period
Columns: user_id, organization_id, period_start
Validation Rules
amount_positive
error
Validation failed
expense_exists_and_approved
error
Validation failed
user_matches_expense_owner
error
Validation failed
organization_matches_expense_org
error
Validation failed
bank_account_format
error
Validation failed
scheduled_date_not_in_past
warning
Validation failed
failure_reason_required_on_failed
error
Validation failed
currency_consistency
warning
Validation failed
Business Rules
one_reimbursement_per_expense
Each expense can have at most one reimbursement record. The expense_id column has a unique constraint enforcing a one-to-one relationship.
auto_create_on_approval
A reimbursement record is automatically created when an expense claim transitions to approved status, either via manual approval or auto-approval rule match.
amount_matches_approved_expense
The reimbursement amount must exactly match the total amount from the associated approved expense at the time of creation. Amounts cannot be independently modified.
status_transition_enforcement
Reimbursement status must follow valid transitions: pending → scheduled → processing → paid, or pending/scheduled → cancelled, or processing → failed → scheduled (retry).
tenant_isolation
All reimbursement queries must be scoped by organization_id. Coordinators see their local association scope; Org Admins see full organization; Global Admins see system-level aggregates only.
no_deletion_allowed
Reimbursement records are financial audit records and must never be deleted. Cancellation sets status to cancelled rather than removing the record.
paid_date_required_on_paid_status
When status transitions to paid, the paid_date must be set. When status is not paid, paid_date must be null.
accounting_export_linkage
When a reimbursement is included in an accounting system export batch (Xledger, Dynamics), the accounting_export_id must be set for reconciliation and idempotent re-export.
period_assignment
Reimbursements must be assigned to a reporting period matching the activity date of the underlying expense, enabling correct Bufdir reporting aggregation.