Integrate dynamic form engine into report screen
epic-structured-post-session-report-screen-task-004 — Connect the dynamic field renderer and way-forward section widget into the post-session report screen scaffold. The screen must load the org-specific field schema via the report schema service, render all dynamic fields, and include the way-forward section. Handle loading, error, and empty-schema states. Use the report form orchestrator as the single BLoC/service mediating form state.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Model the report screen as a BlocProvider + BlocBuilder tree at the top level; pass the orchestrator BLoC down rather than recreating it per widget. The DynamicFieldRenderer should be a stateless widget receiving a list of FieldSchema objects and a callback for value changes — it must not own any state itself. Use a sealed class or freezed union for form field types (TextField, CheckboxField, DropdownField, DateField) to ensure exhaustive handling in the renderer. The WayForwardSectionWidget should always be appended after the dynamic fields list, never inside the dynamic list, so it cannot be accidentally omitted by a schema with no fields.
For draft detection, check the orchestrator BLoC state on initState — if hasDraft is true, dispatch a RestoreDraftEvent before building the form. Avoid Navigator.pop inside form submit logic; instead emit a navigation event from the BLoC and handle it in a BlocListener to keep navigation out of business logic.
Testing Requirements
Widget tests (flutter_test): render loading skeleton when BLoC is in loading state; render dynamic fields matching a mock schema of 5 fields; render way-forward section in all states; render error widget with retry button on schema fetch failure; render empty-schema state when schema has zero fields; pre-populate fields from draft state. BLoC unit tests: emits loading → loaded(schema) on successful fetch; emits loading → error on fetch failure; field update events mutate correct field in state; submit event validates required fields and emits validationError or submitting states. Golden tests for all four screen states. Integration test: full schema fetch from Supabase test instance returns correct fields for test organization.
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.