# Signup Flow Fix - Database Entry Creation ## Problem Successful signups were not creating entries in the database. The database was empty even after successful signup attempts. ## Root Cause 1. **verify-otp endpoint** was returning 404 error if user didn't exist, preventing new user creation 2. **signup endpoint** was only populating minimal fields (phone_number, name, country_code) and missing important data like language and timezone from device_info ## Solution Implemented ### 1. Fixed verify-otp Endpoint (Lines 431-465) - **Before**: Returned 404 error if user didn't exist - **After**: Creates a minimal user entry if user doesn't exist (for signup flow) - Now creates user with: - `phone_number` (encrypted) - `country_code` (extracted from phone number) - `language` (from device_info) - `timezone` (from device_info) - User is created without a name initially, which will be added by the signup endpoint ### 2. Enhanced signup Endpoint (Lines 959-978, 810-831) - **Before**: Only inserted phone_number, name, and country_code - **After**: Now also populates: - `language` (from device_info.language_code) - `timezone` (from device_info.timezone) - When updating existing user (created by verify-otp), also updates language and timezone ### 3. Device Information Storage - Device information is already properly stored in `user_devices` table via upsert operation - Includes: platform, model, os_version, app_version, language_code, timezone ## Complete Signup Flow 1. **User requests OTP** → OTP is sent to phone number 2. **User verifies OTP** → `verify-otp` endpoint: - Verifies OTP code - Creates minimal user entry if user doesn't exist - Creates/updates device entry in `user_devices` table - Returns access_token and refresh_token 3. **User completes signup** → `signup` endpoint: - Updates user with name and location data - Updates language and timezone if provided - Creates location entry if location data provided - Returns updated user info and tokens ## Database Fields Populated ### Users Table - ✅ `id` - Auto-generated UUID - ✅ `phone_number` - Encrypted phone number - ✅ `name` - User's name (from signup) - ✅ `country_code` - Extracted from phone number - ✅ `language` - From device_info.language_code - ✅ `timezone` - From device_info.timezone - ✅ `is_active` - Default TRUE - ✅ `roles` - Default ['seller_buyer'] - ✅ `active_role` - Default 'seller_buyer' - ✅ `user_type` - Default 'user' - ✅ `token_version` - Default 1 - ✅ `deleted` - Default FALSE - ✅ `created_at` - Auto-generated timestamp - ✅ `updated_at` - Auto-updated timestamp - ✅ `last_login_at` - Updated on login/signup ### User Devices Table - ✅ `user_id` - Foreign key to users - ✅ `device_identifier` - Device ID - ✅ `device_platform` - From device_info.platform - ✅ `device_model` - From device_info.model - ✅ `os_version` - From device_info.os_version - ✅ `app_version` - From device_info.app_version - ✅ `language_code` - From device_info.language_code - ✅ `timezone` - From device_info.timezone - ✅ `last_seen_at` - Updated on each request - ✅ `is_active` - Set to TRUE ### Locations Table (Optional) - ✅ Created if state, district, or city_village provided - ✅ Linked to user via user_id ## Testing To verify the fix works: 1. **Check users table:** ```sql SELECT id, phone_number, name, country_code, language, timezone, created_at, last_login_at FROM users WHERE deleted = FALSE ORDER BY created_at DESC; ``` 2. **Check user_devices table:** ```sql SELECT ud.*, u.name, u.phone_number FROM user_devices ud JOIN users u ON ud.user_id = u.id WHERE u.deleted = FALSE ORDER BY ud.created_at DESC; ``` 3. **Check locations table:** ```sql SELECT l.*, u.name, u.phone_number FROM locations l JOIN users u ON l.user_id = u.id WHERE u.deleted = FALSE ORDER BY l.created_at DESC; ``` ## Notes - Phone numbers are encrypted before storage (field-level encryption) - Device information is automatically collected from Android app - All timestamps are in UTC - Users are soft-deleted (deleted flag) rather than hard-deleted - Device entries are upserted (created or updated) on each login/signup