critical priority medium complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Activity wizard router accepts a boolean isProxyMode flag and a pre-selected PeerMentor object as entry parameters
When isProxyMode is true, the peer mentor selection step is skipped entirely and does not appear in the step sequence
When isProxyMode is true, the ProxyAttributionBanner is rendered at the top of every wizard step scaffold
When isProxyMode is false, wizard behavior is identical to the current implementation — no regressions
Existing wizard steps (type, date, duration, notes) are not modified — proxy mode injects behavior via the scaffold wrapper, not step internals
Back navigation from the first wizard step in proxy mode returns to the proxy mode selector, not the peer mentor selection step
Step progress indicator (if present) correctly reflects the reduced step count in proxy mode
Widget test confirms that in proxy mode the peer mentor step widget is never mounted
Widget test confirms that in non-proxy mode the wizard renders identically to pre-change behavior

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
data models
ProxyActivityPayload
ActivityRegistration
performance requirements
Step routing logic must be computed once at wizard initialization, not re-evaluated on every rebuild
security requirements
Proxy mode must only be activatable by users with coordinator or admin roles — validate role in the BLoC before enabling the flag
ui components
ProxyAttributionBanner
ActivityWizardScaffold (existing, extended)
ActivityWizardRouter (existing, extended)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Introduce a `WizardConfig` value object that encapsulates the step list and optional banner widget. Pass this config to the wizard scaffold at construction time based on the isProxyMode flag. This avoids conditional logic scattered throughout the scaffold. To inject the banner without modifying step widgets, wrap each step's body in a `Column` inside the scaffold that prepends the banner when `WizardConfig.attributionBanner != null`.

For step count in the progress indicator, derive it from `WizardConfig.steps.length` rather than a hardcoded constant. Ensure the route parameter contract is documented (which fields are required for proxy mode entry) so the proxy mode selector (upstream) can pass the correct data.

Testing Requirements

Write flutter_test widget tests covering: (1) proxy mode skips peer mentor step — verify by asserting the step widget is never found in the widget tree, (2) attribution banner is present on step 1, step 2, and final step in proxy mode, (3) non-proxy mode renders all original steps in original order, (4) back navigation on step 1 in proxy mode pops to the correct parent route. Use a fake GoRouter or NavigatorObserver to assert navigation events without relying on real routing.

Component
Proxy Activity Wizard
ui medium
Epic Risks (3)
medium impact medium prob scope

If the batch insert RPC returns a mix of successes and failures (e.g., 3 of 10 mentors fail due to constraint violations that slipped through application-level duplicate detection), the confirmation screen result state becomes ambiguous. A coordinator who sees '7 of 10 succeeded' may not know whether to manually register the 3 failures, retry, or escalate — leading to either duplicate registrations or silent underreporting.

Mitigation & Contingency

Mitigation: Design the Bulk Registration Service to return a strongly typed BulkRegistrationResult with per-mentor RegistrationOutcome (success | duplicate_detected | constraint_violation | permission_denied). Design the result screen to list each failed mentor with a specific, plain-language reason and a one-tap 'Retry for this mentor' action that pre-fills the activity wizard with the batch template for that individual.

Contingency: If per-mentor retry UI is too complex to deliver within the epic scope, fall back to displaying failed mentors with their error codes and instructing coordinators to use single-proxy mode for the failures. Document this as a known limitation in release notes and create a follow-up ticket for per-mentor retry in the next sprint.

medium impact medium prob dependency

The Proxy Activity Wizard must reuse the existing activity wizard step widgets (type, date, duration, notes) while injecting a proxy attribution banner and a different submission payload builder. If the existing wizard is not designed for composability, the proxy variant may require forking the widget tree, creating two maintenance-diverging codebases that will drift out of sync when the base wizard is updated (e.g., new activity types added, new mandatory fields).

Mitigation & Contingency

Mitigation: Before implementing the Proxy Activity Wizard, audit the existing activity wizard's architecture. If steps are already extracted as independent StatelessWidget/ConsumerWidget classes, compose them directly with a wrapping Column that injects the attribution banner. If they are tightly coupled inside a parent widget, refactor the existing wizard to accept a nullable ProxyContext parameter before starting the proxy variant — this refactor should be a prerequisite task in this epic.

Contingency: If refactoring the base wizard is blocked by unrelated in-flight work on that component, implement the proxy wizard as a full fork but create a shared StepWidgets library file that both the base wizard and proxy wizard import. Schedule a deduplication refactor as a tech-debt ticket in the next planning cycle.

medium impact medium prob technical

The bulk registration flow spans three sequential screens (multi-select → activity form → confirmation → result) with shared mutable state: the selected mentor list, the activity template, the per-mentor duplicate warnings, and the final submission result. Managing this state across screens without a well-designed Bloc risks state leaks, stale duplicate warning data after mentor removal, and confirmation screen inconsistencies if the user navigates back and changes the mentor selection.

Mitigation & Contingency

Mitigation: Define a single BulkRegistrationBloc (or Cubit) with explicit state transitions covering: MentorsSelected → ActivityTemplateCompleted → DuplicatesChecked → ConfirmationReady → Submitting → SubmissionResult. Each backward navigation event (e.g., 'Back' from confirmation to mentor selection) dispatches a ResetToMentorSelection event that clears downstream state. Unit test every state transition with edge cases including empty mentor list, all mentors having duplicates, and network failure during submission.

Contingency: If state management complexity causes persistent bugs in testing, simplify by passing state explicitly through Navigator arguments (immutable snapshots per screen) rather than a shared Bloc. This reduces flexibility but eliminates cross-screen state mutation bugs.