high priority medium complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

NewMemberOnboardingScreen widget exists as a StatefulWidget or ConsumerWidget (Riverpod) and renders without runtime errors
Route is registered in the GoRouter (or equivalent) configuration and is reachable via the deep-link URI pattern (e.g. app://onboarding?ref=<token>)
On screen entry, DeepLinkHandler is called and the referral token is extracted from the URI query parameters
A Riverpod provider validates the token against Supabase (e.g. check referrals table for token existence and expiry); validation result drives UI state
Invalid or expired tokens render a dedicated error state widget with a Norwegian-language message and a 'Go to main screen' CTA
Valid tokens transition the screen to the welcome/form state without visible flash or rebuild artifacts
Deep link navigates correctly from a cold start (app not running) and from a warm start (app already running in background)
No referral token in the URI (direct route access) defaults to an error state rather than crashing
Screen is navigable back via the device back button/gesture without leaving the app in a broken state

Technical Requirements

frameworks
Flutter
Riverpod
GoRouter
apis
Supabase PostgREST (referral token validation query)
DeepLinkHandler internal service
data models
contact
assignment
performance requirements
Token validation Supabase query completes within 2 seconds on a 4G connection
Screen initial render (skeleton or loading state) appears within 300ms of navigation
security requirements
Referral token must never be logged to console or crash reports in production builds
Token validation executed server-side via Supabase RLS / Edge Function — never trust client-side token inspection alone
Deep-link URI validated with allow-list pattern before processing to prevent injection
ui components
NewMemberOnboardingScreen
ErrorStateWidget
LoadingStateWidget

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Use GoRouter's redirect or onEnter hook to parse the URI and pass the token as an extra or path parameter to the screen. Create a dedicated AsyncNotifierProvider (Riverpod) for token validation state — keep token validation side-effect-free from the widget tree. The ErrorStateWidget should be reusable across other onboarding error scenarios. Ensure the route is protected against direct navigation without a token (guard in GoRouter).

On iOS, configure Associated Domains; on Android, configure intent-filter in AndroidManifest.xml. Store the validated referral token temporarily in a Riverpod StateProvider scoped to the onboarding flow — clear it on success or dismissal.

Testing Requirements

Unit test the token extraction logic in DeepLinkHandler with valid, expired, malformed, and missing token inputs. Widget test NewMemberOnboardingScreen with a mocked Riverpod provider returning each possible state (loading, valid, invalid, expired). Integration test the full deep-link cold-start path using flutter_test + a test Supabase environment. Test both iOS Universal Links and Android App Links URI schemes.

Minimum 80% branch coverage on the screen and its providers.

Component
New Member Onboarding Screen
ui medium
Epic Risks (3)
medium impact medium prob technical

QR codes rendered at the minimum 200×200 size may fail to scan under typical indoor lighting conditions on older or lower-resolution phone cameras, causing recruitment moments to fail when a peer mentor shows the screen to a prospective member.

Mitigation & Contingency

Mitigation: Set the default QR render size to 260×260 logical pixels (not the 200px minimum) and apply a high-contrast white module background. Test scan reliability on at minimum three physical devices (budget Android, mid-range Android, iPhone SE) before marking the screen as done.

Contingency: If scan reliability remains an issue, add a 'Enlarge QR' full-screen mode triggered by tapping the code, and ensure the text referral URL with copy-to-clipboard is always visible as a fallback sharing method.

high impact medium prob integration

The onboarding screen submits attribution and then hands off to an external membership registration URL (HLF's Dynamics portal or similar). If the external URL is unavailable, changes its format, or requires authentication the new member does not have, the conversion funnel is broken at its final step.

Mitigation & Contingency

Mitigation: Confirm the external registration URL and its expected query parameters with HLF's portal team before implementing the handoff. Record the pending_signup attribution event before launching the URL so data is not lost if the external site fails. Display a fallback message with contact information if the URL launch fails.

Contingency: If the external membership URL is not available at feature launch, implement a temporary form that collects name and email and stores a pending_member record in Supabase, allowing coordinators to manually complete registration while the integration is finalised.

low impact medium prob integration

Embedding the RecruitmentStatsWidget on the peer mentor home screen may conflict with existing layout components (activity summary, badge shelf), causing overflow or requiring a redesign of the home screen that is outside this epic's scope.

Mitigation & Contingency

Mitigation: Design the widget as a horizontally constrained card with a maximum height of 96dp so it can be inserted into any vertical list without overflow. Coordinate with the home screen's existing layout owners before starting the embedding task.

Contingency: If home screen embedding creates unacceptable layout conflicts, defer embedding to a separate home-screen redesign task and make the widget accessible only via the dedicated ReferralCodeScreen for the initial release.