Expense Receipt
Data Entity
Description
Stores receipt image metadata and file references for expense claims submitted by peer mentors. Required for expenses exceeding the configured reimbursement threshold (e.g. 100 NOK for HLF). Links a receipt photo captured via the mobile app to a parent expense record.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key | PKrequiredunique |
expense_id |
uuid |
Foreign key to the parent expense record | required |
file_key |
string |
Object storage key (path) for the uploaded receipt image in cloud storage | requiredunique |
file_name |
string |
Original filename as captured or selected by the user | required |
mime_type |
string |
MIME type of the uploaded file (e.g. image/jpeg, image/png, application/pdf) | required |
file_size_bytes |
integer |
Size of the uploaded file in bytes, used for storage quota and validation | required |
upload_status |
enum |
Tracks the upload lifecycle for offline-first support | required |
checksum_sha256 |
string |
SHA-256 hash of the file for integrity verification and deduplication | - |
thumbnail_key |
string |
Object storage key for a server-generated thumbnail, used in the receipt preview UI | - |
captured_at |
datetime |
Timestamp when the photo was taken or the file was selected on the device | - |
uploaded_at |
datetime |
Timestamp when the file was successfully persisted to cloud storage | - |
created_at |
datetime |
Record creation timestamp | required |
updated_at |
datetime |
Record last-updated timestamp | required |
Database Indexes
idx_expense_receipts_expense_id
Columns: expense_id
idx_expense_receipts_file_key
Columns: file_key
idx_expense_receipts_upload_status
Columns: upload_status
Validation Rules
allowed_mime_types
error
Validation failed
max_file_size
error
Validation failed
file_key_not_empty
error
Validation failed
expense_id_exists
error
Validation failed
upload_status_transition
error
Validation failed
Business Rules
receipt_required_above_threshold
A receipt must be attached when the expense amount exceeds the organization-configured threshold (e.g. 100 NOK for HLF). Expenses above threshold cannot be submitted without at least one receipt record with upload_status = 'uploaded'.
receipt_belongs_to_submitter
A receipt may only be created by the user who owns the parent expense. Coordinators acting as proxies may attach receipts on behalf of the peer mentor they are registering for.
immutable_after_approval
Once the parent expense has been approved, receipts linked to it cannot be deleted or replaced. Modifications require the approval to be revoked first.
max_receipts_per_expense
An expense may have at most 5 receipt attachments to prevent storage abuse.
pending_receipts_block_sync
An expense with receipts in 'pending' or 'uploading' status cannot be submitted for approval. The mutation outbox retries upload before the expense progresses.