Reimbursement Approval Workflow
Feature Detail
Description
This feature implements a configurable approval pipeline for submitted travel expense reports, supporting both automatic approval for low-risk submissions and manual attestation for higher-value claims. Automatic approval is triggered when total mileage is below a configured threshold (e.g., 50 km) and no additional expense items are attached. All other submissions enter a manual queue where coordinators review, approve, or reject claims with optional comments. Approval status is tracked and surfaced to submitters in real time, with push notifications triggered on status changes. A full audit trail of approval decisions is maintained for reporting purposes.
Analysis
Approval workflow automation directly addresses the administrative bottleneck that coordinators face when manually reviewing every reimbursement submission regardless of value. By automatically approving routine low-value claims, coordinators can focus attention on higher-value submissions requiring genuine scrutiny, significantly reducing processing time. For peer mentors, faster approvals improve satisfaction and trust in the reimbursement process, supporting volunteer retention. The structured attestation flow also ensures that organisations maintain the audit evidence required for Bufdir grant accountability, reducing compliance risk. Configurable thresholds allow each organisation to apply their own financial controls without requiring custom development, supporting the multi-organisation deployment model.
Implement approval logic as a Supabase Edge Function triggered on insert to `travel_expense_reports`. The function evaluates configured thresholds from `integration_configs` and writes the initial approval record to `reimbursement_approvals` with status `auto_approved` or `pending_attestation`. The coordinator approval queue screen uses a Riverpod stream provider subscribed to real-time Supabase changes on the `reimbursement_approvals` table filtered by the coordinator's organisation scope. Approval and rejection actions invoke authenticated RPC calls that update status and append an audit comment. BLoC manages local UI state for the queue list and detail view. Push notifications are dispatched via the Push Notification Service on status transitions. All status changes are immutable append-only records to preserve the audit trail.
Dependencies
Definition of Done
Components (7)
User Stories (11)
As a As a user
I want I want to see the current approval status of any specific reimbursement submission — whether auto-approved, pending, approved, or rejected — with live updates as the status changes
So that So that I can quickly check the state of any submission without navigating the full detail view, supporting efficient follow-up and status enquiries from peer mentors
- Given a reimbursement submission has status 'auto_approved', when the Approval Status Widget renders, then it displays an 'Auto-Approved' label with teal styling
- Given a submission has status 'pending_attestation', when the widget renders, then it displays a 'Pending Review' label with amber styling to indicate action is required
- Given a coordinator approves a submission, when the status transitions to 'approved', then the widget updates to 'Approved' with green styling within 3 seconds on all connected screens displaying that submission
- +2 more
As a As a user
I want I want to see the current approval status of any specific reimbursement submission — whether auto-approved, pending, approved, or rejected — with live updates as the status changes
So that So that I can quickly check the state of any submission without navigating the full detail view, supporting efficient follow-up and status enquiries from peer mentors
- Given a reimbursement submission has status 'auto_approved', when the Approval Status Widget renders, then it displays an 'Auto-Approved' label with teal styling
- Given a submission has status 'pending_attestation', when the widget renders, then it displays a 'Pending Review' label with amber styling to indicate action is required
- Given a coordinator approves a submission, when the status transitions to 'approved', then the widget updates to 'Approved' with green styling within 3 seconds on all connected screens displaying that submission
- +2 more
As a As a Organization Administrator
I want I want to view aggregate data on how many reimbursement submissions are being auto-approved versus routed to manual review within my organisation
So that So that I can validate whether the configured auto-approval threshold is correctly calibrated for my organisation's submission patterns, and adjust configuration if the manual review burden is unexpectedly high
- Given I am authenticated as an organisation administrator, when I access the reimbursement workflow overview, then I can see a breakdown of submission counts by approval status (auto_approved, manually_approved, rejected, pending) for a selectable period
- Given submissions exist across multiple coordinators in my organisation, when I view the overview, then the data aggregates across all coordinator scopes within my organisation
- Given the auto-approval threshold is set very conservatively (e.g., 5 km), when I view the distribution, then I can see that few submissions are being auto-approved and consider increasing the threshold
- +2 more
As a As a Coordinator
I want I want to reject a reimbursement submission with a mandatory reason comment, triggering a push notification to the submitter explaining the rejection
So that So that the peer mentor understands why their claim was rejected and can correct and resubmit if appropriate, while the organisation retains a compliant record of every rejection decision
- Given I tap Reject on a pending submission, when the rejection dialog appears, then a comment field is shown and marked as required — the confirm button is disabled until at least one character is entered
- Given I complete the mandatory reason and confirm, when the RPC call succeeds, then an immutable rejection record is appended with status 'rejected', my identity, timestamp, and the full comment text
- Given rejection is confirmed, when the record is written, then the submission is removed from the active pending queue and the submitter receives a push notification containing the rejection reason
- +2 more
As a As a user
I want I want to view the complete, immutable audit trail of all approval decisions — including auto-approvals, manual approvals, and rejections — for any reimbursement submission
So that So that I can verify the decision history of any claim for compliance reporting, dispute resolution, or Bufdir grant accountability reviews
- Given I open any reimbursement submission detail view, when the screen loads, then all historical approval records are displayed in chronological order with decision type, timestamp, and actor identity
- Given a submission was auto-approved, when I view its audit trail, then the auto-approval record shows 'System (Auto-Approval Service)' as the actor and the threshold criteria that matched
- Given a submission was manually approved or rejected, when I view its audit trail, then the coordinator's name and any comment they entered are displayed alongside the timestamp
- +2 more
As a As a Coordinator
I want I want the approval queue to update automatically in real time as new submissions arrive or existing ones are actioned by colleagues, without requiring a manual page refresh
So that So that I always work from the current state of the queue and never miss a new submission or waste time acting on a record another coordinator has already processed
- Given I have the approval queue screen open, when a colleague approves a submission on their device, then the submission disappears from my queue within 3 seconds without a manual refresh
- Given I have the approval queue open, when a new submission enters 'pending_attestation' status, then it appears in my queue within 3 seconds and is visually distinguished as newly arrived
- Given I lose network connectivity temporarily, when connectivity is restored, then the queue stream reconnects automatically and reflects the current state without requiring me to restart the app
- +2 more
As a As a Organization Administrator
I want I want to configure the mileage threshold and expense-item conditions that trigger automatic approval for reimbursement submissions in my organisation
So that So that routine low-value claims are approved instantly without consuming coordinator time, while higher-value or complex submissions are appropriately routed to manual review, applying my organisation's own financial controls
- Given I am authenticated as an organisation administrator, when I navigate to reimbursement workflow settings, then I can view and edit the current auto-approval mileage threshold and expense-item exclusion rule
- Given I update the mileage threshold to a new value and save, when a new submission is created below that threshold with no additional expense items, then it is automatically approved without entering the manual queue
- Given I set the expense-item exclusion rule to enabled, when a submission includes any additional expense item regardless of mileage, then it is routed to pending_attestation even if mileage is below the threshold
- +2 more
As a As a user
I want I want to view the complete, immutable audit trail of all approval decisions — including auto-approvals, manual approvals, and rejections — for any reimbursement submission
So that So that I can verify the decision history of any claim for compliance reporting, dispute resolution, or Bufdir grant accountability reviews
- Given I open any reimbursement submission detail view, when the screen loads, then all historical approval records are displayed in chronological order with decision type, timestamp, and actor identity
- Given a submission was auto-approved, when I view its audit trail, then the auto-approval record shows 'System (Auto-Approval Service)' as the actor and the threshold criteria that matched
- Given a submission was manually approved or rejected, when I view its audit trail, then the coordinator's name and any comment they entered are displayed alongside the timestamp
- +2 more
As a As a Coordinator
I want I want to view a prioritised, real-time list of all pending reimbursement submissions within my organisational scope
So that So that I can efficiently triage incoming claims and ensure no submission is left unreviewed, reducing the administrative backlog that currently forces coordinators to manually track outstanding approvals
- Given I am authenticated as a coordinator, when I navigate to the approval queue, then only submissions within my organisational scope are displayed
- Given submissions exist with status 'pending_attestation', when the queue loads, then they appear in chronological order with submitter name, date, mileage total, and expense item count visible without opening the record
- Given a new submission enters the pending state, when it is created in the database, then the queue updates within 3 seconds without requiring a manual page refresh
- +2 more
As a As a Coordinator
I want I want to open a reimbursement submission and review all expense items, receipts, mileage data, and the complete prior approval history before approving or rejecting
So that So that I can make well-informed attestation decisions backed by full documentation, meeting the audit evidence requirements for Bufdir grant accountability
- Given I tap a submission in the approval queue, when the detail screen opens, then all expense line items are listed with type, amount, and supporting data (distance for mileage, toll booth for tolls)
- Given the submission has attached receipts, when I view the detail screen, then receipt thumbnails are displayed and tappable to open a full-resolution view
- Given previous approval decisions exist on this submission, when I view the detail screen, then the full audit trail is displayed in chronological order with decision, timestamp, and coordinator identity
- +2 more
As a As a Coordinator
I want I want to approve a reimbursement submission with an optional comment, triggering an immutable audit record and a push notification to the submitter
So that So that the peer mentor receives timely confirmation of their reimbursement and the organisation maintains a verifiable compliance record for every approved claim
- Given I am on the reimbursement detail screen, when I tap Approve, then an optional comment input field appears before final confirmation
- Given I confirm the approval, when the RPC call completes, then an immutable record is appended to the audit trail with status 'approved', my coordinator ID, the current timestamp, and any comment I entered
- Given approval succeeds, when the record is written, then the submission disappears from my pending queue and the submitter receives a push notification confirming approval
- +2 more