core PK: id 10 required 2 unique

Description

Represents a financial reimbursement record created when an expense claim is approved. Tracks the lifecycle of a payout from approval through disbursement, including amount, payment method, accounting export status, and audit trail. One reimbursement is created per approved expense, forming the authoritative financial record that feeds into accounting system exports and Bufdir reporting.

17
Attributes
6
Indexes
8
Validation Rules
19
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key, globally unique reimbursement identifier
PKrequiredunique
expense_id uuid Foreign key to the approved expense this reimbursement covers. Enforces one-to-one relationship — each approved expense produces exactly one reimbursement record.
requiredunique
organization_id uuid Foreign key to the organization that owns this reimbursement. Used for multi-tenant isolation on all queries.
required
user_id uuid Foreign key to the peer mentor or coordinator being reimbursed. Denormalized from the linked expense for query performance on per-mentor dashboards.
required
approved_by_user_id uuid Foreign key to the coordinator or org admin who approved the underlying expense. Null when approved automatically by the auto-approval rule engine.
-
status enum Lifecycle stage of the reimbursement payout. Pending payout is the initial state after approval. Processing indicates an accounting export is in flight. Paid confirms disbursement. Cancelled is used for reversals.
required
amount_nok decimal Total reimbursement amount in Norwegian kroner, copied from the approved expense at approval time. Precision: 10 digits, 2 decimal places.
required
approval_source enum Indicates whether the reimbursement was created by manual coordinator approval or triggered automatically by the auto-approval rule engine.
required
payment_method enum The disbursement channel for this reimbursement. bank_transfer for direct salary/account transfers, accounting_system for exports to Xledger or Dynamics, manual for ad-hoc cash or check payments.
-
payment_reference string External reference identifier from the payment system or accounting export (e.g., Xledger transaction ID, Dynamics voucher number). Set when status transitions to paid or processing.
-
accounting_export_id uuid Foreign key to the accounting_exports record that included this reimbursement. Null until exported. Used for tracking export batches and preventing double-export.
-
payout_date datetime Timestamp when the payment was confirmed as disbursed. Required when status is paid. Null while pending or in processing.
-
approved_at datetime Timestamp when the underlying expense was approved and this reimbursement record was created.
required
cancellation_reason text Free-text explanation for why a reimbursement was cancelled. Required when status transitions to cancelled.
-
notes text Internal administrative notes visible to coordinators and org admins. Not visible to the peer mentor.
-
created_at datetime Record creation timestamp, set automatically at insert.
required
updated_at datetime Last modification timestamp, updated automatically on every row change.
required

Database Indexes

idx_reimbursement_expense_id
btree unique

Columns: expense_id

idx_reimbursement_organization_id_created_at
btree

Columns: organization_id, created_at

idx_reimbursement_user_id
btree

Columns: user_id

idx_reimbursement_status
btree

Columns: status

idx_reimbursement_accounting_export_id
btree

Columns: accounting_export_id

idx_reimbursement_org_status_created
btree

Columns: organization_id, status, created_at

Validation Rules

amount_positive error

Validation failed

valid_expense_reference error

Validation failed

organization_consistency error

Validation failed

user_consistency error

Validation failed

valid_status_transition error

Validation failed

payment_reference_format error

Validation failed

payout_date_not_future error

Validation failed

approved_at_not_before_expense_submission error

Validation failed

Business Rules

one_reimbursement_per_expense
on_create

Exactly one reimbursement record may exist per expense. Enforced by the unique constraint on expense_id. Any attempt to insert a second reimbursement for the same expense must fail at the database level.

only_approved_expenses_trigger_reimbursement
on_create

A reimbursement record may only be created after the linked expense has been approved (expense_approvals.status = 'approved'). Creating a reimbursement for a pending or rejected expense is not permitted.

amount_matches_approved_expense
on_create

The amount_nok on the reimbursement must match the approved total of the linked expense at the time of approval. Any post-approval correction to the expense amount requires a corresponding update to the reimbursement record with audit logging.

tenant_isolation
always

All reads and writes to the reimbursements table must include an organization_id WHERE clause. Cross-organization access is never permitted. The organization_id on the reimbursement must match the organization_id of the linked expense.

no_double_export
on_update

A reimbursement that already has a non-null accounting_export_id or a status of 'processing' or 'paid' must not be included in a new accounting export batch. The accounting API service must filter these out before submitting a batch.

payout_date_required_on_paid
on_update

When status transitions to 'paid', payout_date must be set to a non-null timestamp. Transitions to 'paid' without a payout_date are rejected.

cancellation_reason_required
on_update

When status transitions to 'cancelled', cancellation_reason must contain a non-empty string explaining the reversal. This is required for audit trail completeness.

immutable_once_paid
on_update

A reimbursement with status 'paid' may not be updated to any other status except 'cancelled' via an explicit reversal workflow with audit logging. Amount and expense_id are immutable after creation.

auto_approval_source_tracking
on_create

When approval_source is 'auto', approved_by_user_id must be null and the triggering auto-approval rule ID must be recorded in audit_logs. This ensures auto-approved reimbursements are distinguishable from manual ones in financial reporting.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
No Partitioning
Retention
Permanent Storage