high priority low complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

ClaimStatusBadge renders correctly for all 5 status values: pending, approved, rejected, auto_approved, under_review
Each status uses a distinct color from the design token system with WCAG 2.2 AA contrast ratio >= 4.5:1 against both light and dark backgrounds
Compact mode renders as a small pill/chip suitable for list rows (height ~24dp, concise label)
Expanded mode renders with full status label, optional icon, and additional context text (e.g., 'Auto-approved: below threshold')
Widget exposes a Semantics node with a meaningful label read by VoiceOver/TalkBack (e.g., 'Claim status: Pending review')
Widget accepts a ClaimStatus enum parameter — no raw string inputs
Widget is stateless and pure — no side effects or BLoC dependencies
Passes all golden tests for each status × mode combination
No hardcoded color values — all colors referenced via AppColors or design token constants
Widget renders correctly at text scale factors 1.0, 1.5, and 2.0 without overflow

Technical Requirements

frameworks
Flutter
flutter_test
data models
ClaimStatus (enum: pending, approved, rejected, auto_approved, under_review)
performance requirements
Widget build time < 1ms (stateless, no async work)
No unnecessary rebuilds — const constructor where possible
security requirements
No sensitive claim data stored or logged inside widget
ui components
ClaimStatusBadge (compact mode)
ClaimStatusBadge (expanded mode)
Design token color constants for each status
Semantics wrapper for screen reader support

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Define a ClaimStatus enum in a shared domain layer (not inside the widget file) so other widgets can import it without pulling in UI code. Map each enum value to a color token pair (background + foreground) in a static const map — this makes adding new statuses a one-line change. Use a Container + Text wrapped in Semantics; avoid RichText for the compact mode to keep the semantic tree simple. For expanded mode, consider a Row with an Icon and two Text widgets.

Use ExcludeSemantics on decorative icons so the screen reader only reads the label once. Register the widget in a WidgetBook or Storyboard-equivalent entry for designer QA. Do not use AnimatedContainer unless animation is explicitly requested — keep it simple.

Testing Requirements

Unit tests: verify correct color token and label string returned for each of the 5 status values. Widget tests: render both compact and expanded modes for each status and assert text content, background color, and Semantics label. Golden tests: snapshot each status × mode combination to prevent visual regressions. Accessibility test: verify contrast ratio programmatically using flutter_test's SemanticsController.

Text scaling test: render at scale 1.0, 1.5, 2.0 and assert no RenderFlex overflow. Target 100% line coverage for the widget file.

Epic Risks (3)
medium impact medium prob technical

Maintaining multi-select state across paginated list pages is architecturally complex in Flutter with Riverpod/BLoC. If the selection state is stored in the widget tree rather than the state layer, page transitions and list redraws can silently clear selections, causing coordinators to lose their multi-select and re-enter it.

Mitigation & Contingency

Mitigation: Store the selected claim ID set in a dedicated Riverpod StateNotifier outside the paginated list widget tree. The paginated list reads selection state from this provider and does not own it. Selection persists independently of list scroll position or page loads.

Contingency: If cross-page selection proves prohibitively complex, limit bulk selection to the currently visible page (add a clear warning in the UI) and prioritise single-page bulk approval for the initial release.

medium impact medium prob integration

If a coordinator has the queue open while another coordinator approves claims from the same queue (possible in large organisations with shared chapter coverage), the Realtime update may arrive out of order or be missed during a reconnect, leaving the first coordinator's view stale and allowing them to attempt to approve an already-actioned claim.

Mitigation & Contingency

Mitigation: The ApprovalWorkflowService's optimistic locking (from the foundation epic) will catch the concurrent edit at the database level. The CoordinatorReviewQueueScreen should handle the resulting ConcurrencyException by removing the claim from the local list and showing a brief snackbar: 'This claim was already actioned by another coordinator.'

Contingency: Add a queue staleness indicator (a subtle 'last updated X seconds ago' label) and a manual refresh button as a fallback for coordinators who notice inconsistencies.

low impact high prob dependency

The end-to-end test requirement that a peer mentor receives a push notification within 30 seconds of coordinator approval depends on FCM delivery latency, which is outside the application's control and can vary significantly in CI/CD environments.

Mitigation & Contingency

Mitigation: Structure end-to-end tests to verify notification intent (correct FCM payload dispatched, correct Realtime event emitted) rather than actual device delivery timing. Use test doubles for FCM delivery in automated tests and reserve real-device delivery tests for manual pre-release validation.

Contingency: If notification timing requirements must be validated in automation, instrument the ApprovalNotificationService with a test hook that records dispatch timestamps and assert against those rather than actual FCM callbacks.