Implement post-submission confirmation and navigation
epic-structured-post-session-report-screen-task-005 — After a successful report submission, display a confirmation screen or bottom sheet acknowledging the report was saved, then navigate back to the calling screen (activity detail or home). Include a 'Report submitted' live-region announcement for screen readers. If submission fails, surface a plain-language error with a retry option rather than a raw error code.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Handle success/error navigation purely via BlocListener — never inside a button onPressed handler. Use a sealed SubmissionState class with SubmissionSuccess, SubmissionError, and SubmissionRetrying variants. For the live region, wrap only the confirmation message Text widget in Semantics(liveRegion: true, child: ...) — do not wrap the entire bottom sheet as this causes unwanted announcements for all child elements. For back navigation, pass a returnRoute or backAction callback via the screen's constructor (or route extra) from the calling screen; the confirmation sheet invokes this callback on dismiss.
Map all PostgrestException codes to a small set of user-facing strings in a dedicated ErrorMessageMapper utility — never interpolate raw exception messages into the UI string. Norwegian Bokmål localisation strings must be added to the app's l10n ARB files for 'report_saved' and 'report_save_failed_retry' keys.
Testing Requirements
Widget tests (flutter_test): BlocListener triggers showModalBottomSheet when BLoC emits submissionSuccess state; confirmation bottom sheet contains Semantics node with liveRegion=true; tapping 'Back' on confirmation calls Navigator.pop or GoRouter.pop; error widget is shown when BLoC emits submissionError; retry button dispatches RetrySubmissionEvent to BLoC; form fields remain populated after error dismissal. BLoC unit tests: submissionSuccess event emitted after mock Supabase returns success; submissionError event emitted with user-friendly message on PostgrestException. Integration test: full submission success flow on Supabase test instance ends at correct previous screen.
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.