# User Preferences Update Bug - Root Cause & Fix ## Issue Summary User preferences updates (theme, favorite_apps) were not being saved to the database despite the API returning 200 OK responses. ## Root Cause ### Duplicate Route Definitions The `auth.py` file had **TWO different endpoints** with the **same route path**: 1. **OLD Endpoint (Line 847)** - `PUT /me/preferences` - Function: `update_user_preferences()` - Input: Generic `dict` - Output: `UserProfile` (no preference fields) - **Only handled**: `last_active_project_id` - **Ignored**: `theme`, `favorite_apps`, and all other preference fields 2. **NEW Endpoint (Line 1242)** - `PUT /me/preferences` - Function: `update_my_preferences()` - Input: `UserPreferencesUpdate` schema - Output: `UserPreferencesResponse` (includes all preference fields) - **Handles**: `favorite_apps`, `theme`, `language`, notifications, etc. ### Why It Failed When FastAPI registers routes, **only the first matching route is registered**. The old endpoint (line 847) was being called for all `/me/preferences` PUT requests, which: - Accepted the request body as a dict - Only looked for `last_active_project_id` - **Silently ignored** `theme`, `favorite_apps`, and other fields - Returned `UserProfile` without preference data - This is why the browser console showed: `favoriteAppsCount: 0, favoriteAppsJson: undefined` ## Evidence from Logs ### Browser Console (browserconsole.txt) ``` Line 48: [DATA] Updating user preferences {theme: 'light', favoriteAppsJson: undefined} Line 49: PUT https://kamau1-swiftops-backend.hf.space/api/v1/auth/me/preferences Line 50: PUT .../api/v1/auth/me/preferences → 200 (625ms) Line 51: [DATA] User preferences updated successfully {updatedFields: Array(1), theme: undefined, favoriteAppsCount: 0, favoriteAppsJson: undefined} ``` The request succeeded (200 OK) but the response didn't contain the updated data. ### Server Logs (runtimeerror.txt) ``` Line 35: PUT /api/v1/auth/me/preferences HTTP/1.1" 200 OK Line 181: PUT /api/v1/auth/me/preferences HTTP/1.1" 200 OK Line 260: PUT /api/v1/auth/me/preferences HTTP/1.1" 200 OK Line 264: PUT /api/v1/auth/me/preferences HTTP/1.1" 200 OK ``` Multiple successful requests, but the old endpoint was being called. ## The Fix ### Changes Made **1. Added `last_active_project_id` to `UserPreferencesUpdate` schema** - File: `src/app/schemas/user_preferences.py` - Added the field so the preferences endpoint can handle project context updates **2. Enhanced the preferences endpoint with project validation** - File: `src/app/api/v1/auth.py` (line 1242+) - Added validation logic for `last_active_project_id`: - Prevents platform admins from setting project context - Verifies user is assigned to the project - Verifies project exists and is active - Updated field exclusion list to skip validated fields **3. Removed the old duplicate endpoint entirely** - File: `src/app/api/v1/auth.py` (previously line 847-1020) - **Deleted** the old `PUT /me/active-project` endpoint - No longer needed since the new endpoint handles everything ### Result: Single Unified Endpoint Now there is **ONE endpoint** that handles **ALL** user preference updates: **`PUT /api/v1/auth/me/preferences`** - Input: `UserPreferencesUpdate` schema - Output: `UserPreferencesResponse` - Handles: - ✅ `favorite_apps` - Array of app codes (max 6, role-validated) - ✅ `theme` - 'light', 'dark', or 'auto' - ✅ `language` - Language code - ✅ `last_active_project_id` - Project context (validated) - ✅ `email_notifications` - Boolean - ✅ `push_notifications` - Boolean - ✅ `sms_notifications` - Boolean - ✅ `dashboard_widgets` - Array of widget codes - ✅ `default_tickets_view` - 'list', 'kanban', or 'calendar' - ✅ All other preference fields ### Response Format The endpoint now returns `UserPreferencesResponse` which includes: ```json { "id": "uuid", "user_id": "uuid", "favorite_apps": ["dashboard", "organizations", "users", "activity"], "theme": "light", "language": "en", "email_notifications": true, "last_active_project_id": "uuid", ... } ``` ## Testing Required 1. **Restart the backend server** to load the updated route 2. **Test theme updates**: - Toggle theme from dark to light - Verify database `user_preferences.theme` column updates - Verify API response contains updated theme 3. **Test favorite apps updates**: - Add/remove favorite apps - Verify database `user_preferences.favorite_apps` column updates - Verify API response contains updated favorite_apps array 4. **Test project context updates**: - Switch active project - Verify database `user_preferences.last_active_project_id` column updates - Verify API response contains updated project ID ## Migration Notes ### Breaking Changes - **Removed**: `PUT /me/active-project` endpoint (was never in production) - **Use instead**: `PUT /me/preferences` for all preference updates ### Unified Endpoint - **Route**: `PUT /api/v1/auth/me/preferences` - **Purpose**: Update all user preferences in one place - **Supports**: All preference fields including `last_active_project_id` ## Database Schema The fix doesn't require any database changes. The `user_preferences` table already has all the necessary columns: - `favorite_apps` (JSONB array) - `theme` (VARCHAR) - `language` (VARCHAR) - `email_notifications` (BOOLEAN) - etc. The issue was purely in the routing layer.