high priority medium complexity integration pending integration specialist Tier 3

Acceptance Criteria

On valid form submission, ReferralAttributionService.submitAttribution() is called with the new member's contact details and the validated referral token
A loading indicator (e.g. CircularProgressIndicator overlay or button spinner) is shown during the Supabase write operation; the submit button is disabled to prevent double submission
On Supabase success (2xx), the user is navigated to the membership registration flow via GoRouter; the onboarding screen is removed from the navigation stack (no back-navigation to onboarding)
On network/server error, an inline error banner (not a modal) is shown with a Norwegian retry message; the form fields remain populated so the user does not re-enter data
On duplicate attribution attempt (same referral code + same phone/email already exists), a specific user-friendly error distinguishes this from a generic network error
Attribution record written to Supabase includes: referral_code, new_member_name, new_member_phone, new_member_email, organisation_id, created_at timestamp
ReferralAttributionService is injected via Riverpod — no direct Supabase client calls from the widget layer
After successful navigation, Riverpod onboarding state providers are disposed/invalidated to free memory

Technical Requirements

frameworks
Flutter
Riverpod
GoRouter
apis
Supabase PostgREST (INSERT into referral_attributions table)
Supabase Edge Function (optional — if attribution logic requires server-side validation before insert)
data models
contact
assignment
performance requirements
Supabase INSERT operation completes within 3 seconds on a standard 4G connection
Navigation to membership registration flow occurs within 200ms of receiving success response
security requirements
RLS policy on referral_attributions table enforces that anonymous/unauthenticated inserts are only permitted with a valid referral token (validated via Supabase RLS check or Edge Function)
New member PII (phone, email) transmitted over TLS only — never logged
Referral token invalidated or marked as used server-side after successful attribution to prevent reuse
ui components
LoadingOverlayWidget
ErrorBannerWidget
AppButton (submit)
NewMemberOnboardingScreen

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Implement ReferralAttributionService as an injectable Riverpod Provider wrapping a Supabase client. Use AsyncNotifierProvider for the submission state to cleanly handle loading/data/error transitions. In GoRouter, use context.go() (not context.push()) after success so the onboarding screen is popped from the stack — prevents user navigating back to a completed onboarding. Consider a Supabase Edge Function for the attribution write if server-side token invalidation is required; otherwise a standard RLS-protected INSERT is sufficient.

ErrorBannerWidget should use Semantics(liveRegion: true) so screen readers announce the error. Handle PostgrestException error codes: 23505 (unique violation) maps to duplicate attribution message; all others map to generic retry message.

Testing Requirements

Widget test all three submission outcome states: loading (verify button disabled, spinner visible), success (verify GoRouter push called with correct route, providers invalidated), and error (verify error banner displayed, fields still populated). Mock ReferralAttributionService via Riverpod override in tests. Integration test the full submit → Supabase → navigate flow against a test Supabase project. Test duplicate submission scenario returns the correct error state.

Test that pressing submit twice in rapid succession only triggers one API call.

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.