Build draft indicator banner on report screen
epic-structured-post-session-report-screen-task-002 — Display a visible draft indicator banner at the top of the post-session report screen when an incomplete (draft) report already exists for the given activity_id. Load draft state from the post-session report repository on screen entry and render a dismissible banner with a 'Continue draft' affordance. Follow WCAG 2.2 AA contrast and semantics requirements.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
Implement DraftIndicatorBanner as a standalone stateful widget (or a BLoC-consumer widget) that accepts `activityId` as a parameter and manages its own loading/dismiss state internally — this keeps the parent report screen clean. Use a `ValueNotifier
Ensure the Semantics widget wraps the entire banner with `container: true` and a `label` describing its purpose for screen readers — this satisfies the WCAG 4.1.3 Status Messages criterion relevant to Norwegian accessibility law (which the app must comply with given its public-sector context).
Testing Requirements
Write widget tests using `WidgetTester` that cover: (1) banner visible when draft exists, (2) banner absent when no draft, (3) banner absent after dismiss, (4) 'Continue draft' calls the onContinue callback with the draft report object, (5) skeleton shown during loading state, (6) banner absent on error state. Mock PostSessionReportRepository with mockito. Add a golden test for the banner in its draft-present state to catch visual regressions. Verify accessibility with `tester.getSemantics()` to assert the live region and button labels are correctly set.
End-to-end integration tests that span Flutter UI → Supabase → RLS → storage are inherently flaky in CI due to network timing, test database state, and Supabase cold-start latency. Flaky tests erode confidence and slow the release pipeline.
Mitigation & Contingency
Mitigation: Use a dedicated Supabase test project with seeded org and user fixtures. Wrap all E2E tests in retry logic with a fixed seed and tear-down hooks. Keep E2E tests in a separate test suite that runs on-demand rather than on every PR, with unit and widget tests as the primary CI gate.
Contingency: If E2E tests remain unreliable, replace the Supabase calls in integration tests with a verified fake (in-memory repository implementations) and promote the real Supabase tests to a nightly scheduled run rather than blocking PR merges.
Health status, course interest, and assistive device fields contain personal health data. If any logger, analytics event, or crash reporter captures field values — through automated error serialisation or developer-added debug logs — the feature could violate GDPR and Blindeforbundet's data processor agreement.
Mitigation & Contingency
Mitigation: Audit all log statements in the report feature's code paths before the epic is marked done. Apply a PII-safe logging wrapper that strips field values from any serialised form state before it reaches the logger. Add a CI lint rule that flags direct logger calls within report-related files.
Contingency: If PII is found in logs post-launch, immediately disable the affected logging call and rotate any credentials that were exposed. Notify the data protection officer and document the incident per GDPR Article 33 requirements.