DocHub
Complete signup process with unlinked user cleanup and email confirmation polling

Signup Flow

The signup process includes pre-flight checks, unlinked user cleanup, fresh user creation, and email confirmation polling.

User Inputs

The signup form collects:

  • First Name
  • Last Name
  • Email
  • Password (minimum 6 characters)
  • Phone Number (with country code)
  • Country

Step-by-Step Process

1. Pre-flight Checks

  • Check if email exists in user_profile table
  • If yes: show “Email already registered” error
  • If no: check for unlinked auth users

2. Unlinked User Cleanup

Detects and removes orphaned auth users that have no matching user_profile record:

  1. Check if user_profile exists for email — if yes, no cleanup needed
  2. Try dummy sign-in with email + random password
  3. If error = invalid_credentials — unlinked auth user found
  4. If error = user not found — no unlinked user exists
  5. Call delete-unlinked-user edge function to delete the orphaned auth user
  6. Wait 500ms for cleanup completion

3. Fresh Signup

  • Creates new auth.users record (pending confirmation)
  • Sends confirmation email with redirect link
  • Shows green “Check your email” message
  • Inserts app_logs entry: “Waiting for email confirmation”

4. Email Confirmation Polling

  • Polls every 3 seconds to check if email is confirmed
  • Attempts to sign in with provided credentials each poll
  • Maximum polling duration: 5 minutes
  • Once successful: cancels the polling timer

5. Account Activation

  • Shows “Processing account…” dialog
  • Creates user_profile record with full data (name, phone, country)
  • Updates local JSON cache (user_profile.json)
  • Updates app_logs: “Email confirmed and account created successfully”
  • Navigates to home screen with welcome dialog

Unlinked User Profile Handling (Self-Healing)

If a user_profile exists but has no matching auth user:

  • The system creates a new auth user normally
  • Updates the existing user_profile record with the new user_id
  • No data is lost — the profile is relinked

Email Resend

  • Rate limited to once per 60 seconds (Supabase rate limit)
  • UI shows a countdown timer during cooldown
  • Confirmation link expires in 24 hours

Implementation Files

File Purpose
lib/screens/login_screen.dart Signup UI, form validation
lib/providers/user_provider.dart Email confirmation polling, profile creation
lib/services/supabase_service.dart Unlinked user detection and cleanup
supabase/functions/delete-unlinked-user/index.ts Edge function for admin-level cleanup