high priority medium complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Screen is composed of exactly two steps: Step 1 — mentor selection (MentorSingleSelectWidget), Step 2 — activity form (ProxyActivityForm)
Back button on Step 2 returns to Step 1 with the previously selected mentor still highlighted
Back button on Step 1 navigates out of the registration flow entirely via GoRouter pop
Tapping 'Continue' on Step 1 is disabled until a mentor is selected
Step 2 displays the selected mentor's name in a non-editable summary chip at the top
Inline validation errors appear on the form fields in Step 2 on blur and on submit attempt
On Step 2 'Review' tap, the ProxyConfirmationScreen is pushed via GoRouter with full draft data
ProxyRegistrationBLoC manages all form state so that orientation changes and navigation events do not lose user input
Submission errors surfaced from the BLoC are displayed as an inline banner above the action buttons
Screen is accessible: step indicator (Step 1 of 2) is announced by screen readers, each step's heading has a Semantics heading role
GoRouter back-stack is correctly maintained — pressing hardware back on Android behaves identically to the back button

Technical Requirements

frameworks
Flutter
BLoC
GoRouter
data models
ProxyActivityDraft
MentorSummary
ProxyRegistrationState
performance requirements
Step transition animation completes in under 300ms
No layout shift or jank during mentor chip rendering in Step 2
security requirements
mentor_id passed through the flow must be validated as belonging to the coordinator's chapter before submission — enforced by ActivityAttributionValidator
Form data must not be logged to console or analytics in production
ui components
StepIndicator (Step 1 of 2)
MentorSingleSelectWidget
ProxyActivityForm
SelectedMentorChip
AppButton (continue, review, back)
InlineErrorBanner
ProxyConfirmationScreen (pushed via GoRouter)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Use an `IndexedStack` or `PageView` with `physics: NeverScrollableScrollPhysics` for the two-step layout so BLoC state is never disposed between steps. Do not push Step 2 as a new GoRouter route — keep both steps within the same screen widget to preserve BLoC state cleanly. Only push ProxyConfirmationScreen as a new route when the coordinator taps Review. This distinction is important: GoRouter back from the confirmation screen should return to Step 2, not exit the flow.

The `ProxyRegistrationBLoC` should be provided above this screen in the widget tree (e.g., via `BlocProvider` at the route level) so it survives the internal step transitions. Apply GoRouter's `onPopInvoked` callback if Flutter 3.22+ is targeted to intercept hardware back and route it correctly.

Testing Requirements

Widget tests: initial render shows Step 1 with continue disabled, selecting a mentor enables continue, tapping continue navigates to Step 2, Step 2 shows selected mentor chip, back from Step 2 returns to Step 1 with mentor preserved, inline validation errors appear on required fields when empty, BLoC error state renders inline banner. Integration test on TestFlight covering the full single-flow path: select mentor → fill form → review → confirm → success state. Accessibility test: step indicator text is included in Semantics tree, all buttons have descriptive labels.

Component
Bulk Proxy Registration Screen
ui high
Epic Risks (3)
high impact high prob scope

Partial failures in bulk registration — where some mentors succeed and others fail — create a complex UX state that is easy to mishandle. If the UI does not clearly communicate which records succeeded and which failed, coordinators may re-submit already-saved records (creating duplicates) or miss failed records entirely (creating underreporting).

Mitigation & Contingency

Mitigation: Design the per-mentor result screen as a primary deliverable of this epic, not an afterthought. Use a clear list view with success/failure indicators per mentor name, and offer a 'Retry failed' action that pre-selects only the failed mentors for resubmission.

Contingency: If partial failure UX proves too complex to deliver within scope, implement a simpler all-or-nothing submission mode for the initial release with a clear error message listing which mentors failed, and defer the partial-retry UI to a follow-up sprint.

medium impact medium prob technical

Submitting proxy records for a large group (e.g., 30+ mentors) as individual Supabase inserts may cause latency issues or hit rate limits, degrading the coordinator experience and potentially causing timeout failures that leave data in an inconsistent state.

Mitigation & Contingency

Mitigation: Implement the BulkRegistrationOrchestrator to batch inserts using a Supabase RPC call that accepts an array of proxy records, reducing round-trips to a single network call. Add progress indication using a stream of per-record results if the RPC supports it.

Contingency: If the RPC approach is blocked by Supabase limitations, fall back to chunked parallel inserts (5 records per batch) with retry logic, capping total submission time and surface a progress bar to manage coordinator expectations.

medium impact medium prob technical

Unifying state management for both single and bulk proxy flows in a single BLoC risks state leakage between flows — for example, a previously selected mentor list persisting when a coordinator switches from bulk to single mode — causing confusing UI states or incorrect submissions.

Mitigation & Contingency

Mitigation: Define separate, named state subtrees within the BLoC for single-proxy state and bulk-proxy state, with explicit reset events triggered on flow entry. Write unit tests for state isolation scenarios using the bloc_test package.

Contingency: If unified BLoC state becomes unmanageable, split into two separate BLoCs (ProxySingleRegistrationBLoC and ProxyBulkRegistrationBLoC) sharing only common events via a parent coordinator Cubit.