Spaces:
Sleeping
Sleeping
| # User Preferences API Documentation | |
| ## Overview | |
| The User Preferences API allows users to customize their experience in the SwiftOps platform, including favorite apps in the navigation bar, UI theme, language, notification settings, and dashboard layout. | |
| **Key Features:** | |
| - Role-based default preferences | |
| - Maximum 6 favorite apps (database constraint) | |
| - Automatic preference creation on first access | |
| - Full CRUD operations with audit logging | |
| - Context-aware app availability based on user role | |
| --- | |
| ## Table of Contents | |
| 1. [Authentication](#authentication) | |
| 2. [Endpoints](#endpoints) | |
| 3. [Data Models](#data-models) | |
| 4. [Role-Based Defaults](#role-based-defaults) | |
| 5. [Frontend Integration Guide](#frontend-integration-guide) | |
| 6. [Common Use Cases](#common-use-cases) | |
| 7. [Error Handling](#error-handling) | |
| 8. [Best Practices](#best-practices) | |
| --- | |
| ## Authentication | |
| All endpoints require authentication via JWT token in the Authorization header: | |
| ``` | |
| Authorization: Bearer <access_token> | |
| ``` | |
| --- | |
| ## Endpoints | |
| ### 1. Get Current User's Preferences | |
| **Endpoint:** `GET /api/v1/auth/me/preferences` | |
| **Description:** Retrieves the current user's preferences. If no preferences exist yet, they are automatically created with role-based defaults. | |
| **Response:** Returns full preference object including: | |
| - Favorite apps array (max 6 items) | |
| - UI theme (light/dark/auto) | |
| - Language preference | |
| - Notification settings (email, push, SMS) | |
| - Dashboard widget configuration | |
| - Table/list preferences (view type, pagination, sorting) | |
| - Map preferences (zoom level, center coordinates) | |
| - Additional custom settings | |
| **Use Cases:** | |
| - Load user preferences on application startup | |
| - Populate settings page | |
| - Configure UI based on user theme preference | |
| - Display favorite apps in navigation bar | |
| --- | |
| ### 2. Update User Preferences | |
| **Endpoint:** `PUT /api/v1/auth/me/preferences` | |
| **Description:** Updates one or more preference fields. Only send fields you want to update - all fields are optional. | |
| **Request Body Fields:** | |
| - `favorite_apps` - Array of app codes (max 6, validated against role) | |
| - `theme` - One of: `light`, `dark`, `auto` | |
| - `language` - Language code (e.g., `en`, `sw`) | |
| - `email_notifications` - Boolean | |
| - `push_notifications` - Boolean | |
| - `sms_notifications` - Boolean | |
| - `dashboard_widgets` - Array of widget codes | |
| - `default_tickets_view` - One of: `list`, `kanban`, `calendar` | |
| - `tickets_per_page` - Integer between 10-100 | |
| - `default_sort_field` - String (field name for default sorting) | |
| - `default_sort_order` - One of: `asc`, `desc` | |
| - `default_map_zoom` - Integer (map zoom level) | |
| - `default_map_center_lat` - Float (latitude) | |
| - `default_map_center_lng` - Float (longitude) | |
| - `additional_settings` - Object (free-form custom settings) | |
| **Validation Rules:** | |
| - Maximum 6 favorite apps | |
| - Favorite apps must be from the role's available apps list | |
| - Theme must be one of the valid options | |
| - Tickets per page must be between 10-100 | |
| **Response:** Returns updated preference object | |
| **Use Cases:** | |
| - Save settings from user preferences page | |
| - Update theme when user toggles dark mode | |
| - Reorder favorite apps in navigation | |
| - Change language preference | |
| - Toggle notification preferences | |
| --- | |
| ### 3. Get Available Apps for Role | |
| **Endpoint:** `GET /api/v1/auth/me/preferences/available-apps` | |
| **Description:** Returns the list of apps available for the user to favorite based on their role, along with current favorites and defaults. | |
| **Response Fields:** | |
| - `role` - User's current role | |
| - `current_favorites` - Array of currently favorited app codes | |
| - `available_apps` - Array of all apps user can choose from | |
| - `default_favorites` - Array of role's default favorite apps | |
| - `max_favorites` - Maximum number allowed (always 6) | |
| **Use Cases:** | |
| - Populate app picker in settings UI | |
| - Show which apps can be added/removed | |
| - Display role-appropriate app options | |
| - Validate favorite apps client-side before submission | |
| --- | |
| ## Data Models | |
| ### UserPreferencesResponse | |
| Full preference object returned by GET and PUT endpoints: | |
| **Core Fields:** | |
| - `id` - UUID of preference record | |
| - `user_id` - UUID of user who owns these preferences | |
| **App & Navigation:** | |
| - `favorite_apps` - Array of app codes (e.g., `["dashboard", "users", "tickets"]`) | |
| **UI Preferences:** | |
| - `theme` - `"light"`, `"dark"`, or `"auto"` | |
| - `language` - Language code (default: `"en"`) | |
| **Notifications:** | |
| - `email_notifications` - Boolean (default: `true`) | |
| - `push_notifications` - Boolean (default: `true`) | |
| - `sms_notifications` - Boolean (default: `false`) | |
| **Dashboard:** | |
| - `dashboard_widgets` - Array of widget codes (e.g., `["recent_tickets", "team_performance"]`) | |
| **Table/List Preferences:** | |
| - `default_tickets_view` - View type (default: `"list"`) | |
| - `tickets_per_page` - Pagination size (default: `25`) | |
| - `default_sort_field` - Default sort field (default: `"created_at"`) | |
| - `default_sort_order` - Sort direction (default: `"desc"`) | |
| **Map Preferences:** | |
| - `default_map_zoom` - Zoom level (default: `12`) | |
| - `default_map_center_lat` - Latitude (nullable) | |
| - `default_map_center_lng` - Longitude (nullable) | |
| **Flexible Storage:** | |
| - `additional_settings` - Object for custom settings | |
| --- | |
| ## Role-Based Defaults | |
| Each role gets context-appropriate default preferences: | |
| ### Platform Admin | |
| **Favorite Apps:** `dashboard`, `organizations`, `users`, `activity` | |
| **Available Apps:** Core apps (dashboard, organizations, users, activity) + Management apps (settings, billing, notifications, help) | |
| **Dashboard Widgets:** Recent tickets, team performance, SLA metrics, organizations overview | |
| ### Client Admin | |
| **Favorite Apps:** `dashboard`, `projects`, `tickets`, `team` | |
| **Available Apps:** Dashboard, projects, tickets, team, sales orders, customers, contractors, reports, settings, help | |
| **Dashboard Widgets:** Recent tickets, team performance, SLA metrics, project status | |
| ### Contractor Admin | |
| **Favorite Apps:** `dashboard`, `projects`, `tickets`, `team` | |
| **Available Apps:** Dashboard, projects, tickets, team, timesheets, payroll, reports, settings, help | |
| **Dashboard Widgets:** Recent tickets, team performance, payroll summary, project status | |
| ### Sales Manager | |
| **Favorite Apps:** `dashboard`, `sales_orders`, `customers`, `reports` | |
| **Available Apps:** Dashboard, sales orders, customers, reports, team, maps, settings, help | |
| **Dashboard Widgets:** Sales pipeline, revenue metrics, team performance, conversion rates | |
| ### Project Manager | |
| **Favorite Apps:** `dashboard`, `projects`, `tickets`, `team` | |
| **Available Apps:** Dashboard, projects, tickets, team, reports, maps, settings, help | |
| **Dashboard Widgets:** Project status, team performance, SLA metrics, map view | |
| ### Dispatcher | |
| **Favorite Apps:** `dashboard`, `tickets`, `maps`, `team` | |
| **Available Apps:** Dashboard, tickets, maps, team, projects, reports, settings, help | |
| **Dashboard Widgets:** Recent tickets, map view, team availability, SLA metrics | |
| ### Field Agent | |
| **Favorite Apps:** `tickets`, `maps`, `timesheets`, `profile` | |
| **Available Apps:** Tickets, maps, timesheets, profile, expenses, documents, help | |
| **Dashboard Widgets:** My tickets, earnings summary, attendance summary | |
| ### Sales Agent | |
| **Favorite Apps:** `dashboard`, `sales_orders`, `customers`, `maps` | |
| **Available Apps:** Dashboard, sales orders, customers, maps, profile, reports, help | |
| **Dashboard Widgets:** My sales, customer pipeline, earnings summary | |
| --- | |
| ## Frontend Integration Guide | |
| ### Application Startup Flow | |
| 1. **After successful login**, fetch user preferences: | |
| - Call `GET /api/v1/auth/me/preferences` | |
| - Store preferences in global state (Redux, Vuex, Context, etc.) | |
| - If preferences don't exist, backend automatically creates them with role defaults | |
| 2. **Apply preferences to UI:** | |
| - Set theme based on `theme` field (light/dark/auto) | |
| - Configure language/i18n based on `language` field | |
| - Render favorite apps in top navigation bar | |
| - Configure dashboard widgets | |
| - Set default table views and pagination sizes | |
| 3. **Cache preferences locally:** | |
| - Store in localStorage/sessionStorage for quick access | |
| - Sync with backend on changes | |
| - Handle offline scenarios gracefully | |
| ### Settings Page Implementation | |
| **Favorite Apps Section:** | |
| - Display current favorite apps with drag-to-reorder functionality | |
| - Show "Add App" button that opens modal with available apps | |
| - Validate max 6 apps client-side | |
| - Allow removal of favorites | |
| - Show role-appropriate apps only (fetch from `/available-apps` endpoint) | |
| **Theme Selector:** | |
| - Radio buttons or dropdown for Light/Dark/Auto | |
| - Apply theme immediately on change (optimistic UI) | |
| - Save to backend in background | |
| **Notification Preferences:** | |
| - Toggle switches for each notification type | |
| - Group by delivery method (Email, Push, SMS) | |
| - Show current state from backend | |
| - Update backend on toggle | |
| **Dashboard Customization:** | |
| - Widget picker showing available widgets for role | |
| - Drag-and-drop to reorder widgets | |
| - Toggle widget visibility | |
| - Save layout to `dashboard_widgets` field | |
| **Table Preferences:** | |
| - Dropdown for default view (List/Kanban/Calendar) | |
| - Number input for pagination size (10-100) | |
| - Dropdowns for sort field and order | |
| ### Navigation Bar Integration | |
| **Rendering Favorite Apps:** | |
| - Fetch `favorite_apps` array from preferences | |
| - Map app codes to app metadata (icons, names, routes) | |
| - Render in top navigation or app drawer | |
| - Maintain order from array | |
| - Show all available apps in "All Apps" menu or 9-dot launcher | |
| **App Code to Route Mapping:** | |
| ``` | |
| dashboard -> /dashboard | |
| organizations -> /organizations | |
| users -> /users | |
| tickets -> /tickets | |
| projects -> /projects | |
| sales_orders -> /sales-orders | |
| customers -> /customers | |
| maps -> /map | |
| team -> /team | |
| reports -> /reports | |
| timesheets -> /timesheets | |
| payroll -> /payroll | |
| profile -> /profile | |
| expenses -> /expenses | |
| documents -> /documents | |
| settings -> /settings | |
| billing -> /billing | |
| notifications -> /notifications | |
| help -> /help | |
| ``` | |
| ### Theme Management | |
| **Auto Theme Implementation:** | |
| - When `theme: "auto"`, detect system preference | |
| - Listen for system theme changes | |
| - Update UI dynamically without backend call | |
| - Only `light` and `dark` are stored in backend, `auto` uses system detection | |
| **Theme Application:** | |
| - Set CSS variables or toggle theme classes | |
| - Persist across page refreshes | |
| - Apply before first paint to avoid flash | |
| ### Optimistic Updates | |
| For better UX, update UI immediately before backend confirmation: | |
| 1. User changes preference in UI | |
| 2. Update local state/UI immediately | |
| 3. Call PUT endpoint in background | |
| 4. On success: Keep UI as is | |
| 5. On error: Revert UI to previous state and show error message | |
| --- | |
| ## Common Use Cases | |
| ### Use Case 1: Customizing Favorite Apps | |
| **User Story:** As a platform admin, I want to add "Billing" to my favorite apps. | |
| **Implementation Steps:** | |
| 1. User opens Settings → Favorite Apps | |
| 2. Frontend calls `GET /api/v1/auth/me/preferences/available-apps` to get available apps | |
| 3. Display current favorites (4 apps) and available apps (8 apps) | |
| 4. User clicks "Add App" → Modal shows available apps not already favorited | |
| 5. User selects "billing" → Add to favorites array | |
| 6. Frontend calls `PUT /api/v1/auth/me/preferences` with `{"favorite_apps": ["dashboard", "organizations", "users", "activity", "billing"]}` | |
| 7. Backend validates (max 6, role-appropriate) and saves | |
| 8. Frontend updates navigation bar with new favorite | |
| ### Use Case 2: Toggling Dark Mode | |
| **User Story:** As a user, I want to switch to dark mode. | |
| **Implementation Steps:** | |
| 1. User clicks theme toggle in header/settings | |
| 2. Frontend immediately applies dark theme to UI (optimistic update) | |
| 3. Frontend calls `PUT /api/v1/auth/me/preferences` with `{"theme": "dark"}` | |
| 4. Backend saves preference | |
| 5. On next login, dark theme is automatically applied | |
| ### Use Case 3: Reordering Favorite Apps | |
| **User Story:** As a dispatcher, I want "maps" to be my first favorite app. | |
| **Implementation Steps:** | |
| 1. User drags "maps" to first position in favorites list | |
| 2. Frontend updates array order: `["maps", "dashboard", "tickets", "team"]` | |
| 3. UI updates immediately (optimistic) | |
| 4. Frontend calls `PUT /api/v1/auth/me/preferences` with new array | |
| 5. Backend saves new order | |
| 6. Navigation bar reflects new order | |
| ### Use Case 4: Setting Default Map Center | |
| **User Story:** As a field agent, I want the map to always center on my region. | |
| **Implementation Steps:** | |
| 1. User navigates map to preferred location | |
| 2. User clicks "Set as default center" button | |
| 3. Frontend captures current map center coordinates | |
| 4. Frontend calls `PUT /api/v1/auth/me/preferences` with `{"default_map_center_lat": -1.2921, "default_map_center_lng": 36.8219, "default_map_zoom": 13}` | |
| 5. Backend saves preferences | |
| 6. On next map load, map centers at saved coordinates with saved zoom level | |
| ### Use Case 5: Customizing Dashboard | |
| **User Story:** As a sales manager, I want to see "Conversion Rates" widget on my dashboard. | |
| **Implementation Steps:** | |
| 1. User opens Dashboard Settings | |
| 2. Frontend shows available widgets for sales_manager role | |
| 3. User toggles "conversion_rates" widget on | |
| 4. Frontend updates `dashboard_widgets` array | |
| 5. Frontend calls `PUT /api/v1/auth/me/preferences` with updated widget list | |
| 6. Dashboard re-renders with new widget | |
| --- | |
| ## Error Handling | |
| ### Common Errors | |
| **400 Bad Request - Invalid App for Role:** | |
| ```json | |
| { | |
| "detail": "Invalid apps for dispatcher: billing, organizations. Available apps: dashboard, tickets, maps, team, projects, reports, settings, help" | |
| } | |
| ``` | |
| **Action:** Show user which apps are invalid and provide picker with valid apps only. | |
| **400 Bad Request - Too Many Favorites:** | |
| ```json | |
| { | |
| "detail": "Maximum 6 favorite apps allowed" | |
| } | |
| ``` | |
| **Action:** Disable "Add" button when 6 apps are already favorited, show count (e.g., "5/6 favorites"). | |
| **400 Bad Request - Invalid Theme:** | |
| ```json | |
| { | |
| "detail": "Theme must be one of: light, dark, auto" | |
| } | |
| ``` | |
| **Action:** Use dropdown/radio buttons to prevent invalid values client-side. | |
| **401 Unauthorized:** | |
| ```json | |
| { | |
| "detail": "Could not validate credentials" | |
| } | |
| ``` | |
| **Action:** Token expired or invalid - redirect to login page. | |
| ### Error Handling Strategy | |
| 1. **Validate client-side first** - Prevent invalid requests before sending | |
| 2. **Show specific error messages** - Extract `detail` field from error response | |
| 3. **Revert optimistic updates** - Roll back UI changes if API call fails | |
| 4. **Retry on network errors** - Implement exponential backoff for transient failures | |
| 5. **Log errors** - Track preference update failures for debugging | |
| --- | |
| ## Best Practices | |
| ### Performance | |
| 1. **Cache preferences locally** - Fetch once on login, update on changes | |
| 2. **Debounce rapid updates** - If user changes multiple settings quickly, batch into single API call | |
| 3. **Use optimistic updates** - Update UI immediately, sync with backend asynchronously | |
| 4. **Lazy load available apps** - Only fetch when user opens app picker modal | |
| ### User Experience | |
| 1. **Show loading states** - Display skeleton or spinner during fetch | |
| 2. **Provide immediate feedback** - Visual confirmation when settings save | |
| 3. **Persist across sessions** - Store preferences in localStorage as backup | |
| 4. **Handle offline gracefully** - Queue preference updates if offline, sync when online | |
| 5. **Validate before submission** - Check constraints client-side (max 6 apps, valid values) | |
| ### Security | |
| 1. **Never cache sensitive data** - Clear preferences on logout | |
| 2. **Validate all inputs** - Don't trust client-side validation alone | |
| 3. **Use HTTPS** - Ensure all API calls are over secure connection | |
| 4. **Handle token expiration** - Refresh token or redirect to login gracefully | |
| ### Accessibility | |
| 1. **Keyboard navigation** - Allow keyboard control of app picker and settings | |
| 2. **Screen reader support** - Announce preference changes | |
| 3. **High contrast mode** - Respect system high contrast preferences | |
| 4. **Focus management** - Return focus appropriately after modal closes | |
| ### State Management | |
| 1. **Single source of truth** - Store preferences in global state manager | |
| 2. **Sync with backend** - Keep local state in sync with server | |
| 3. **Handle race conditions** - Use timestamps or version numbers to resolve conflicts | |
| 4. **Broadcast changes** - Notify all components when preferences update | |
| --- | |
| ## Example Implementation Flows | |
| ### Complete Settings Page Flow | |
| **Initial Load:** | |
| 1. Component mounts → Check if preferences in state | |
| 2. If not in state → Call `GET /api/v1/auth/me/preferences` | |
| 3. Store in state and render current preferences | |
| 4. Enable editing | |
| **User Makes Change:** | |
| 1. User modifies setting (e.g., toggles notification) | |
| 2. Update local state immediately (optimistic) | |
| 3. Debounce API call (500ms wait for more changes) | |
| 4. Call `PUT /api/v1/auth/me/preferences` with changed fields only | |
| 5. On success: Keep optimistic update | |
| 6. On error: Revert to previous value, show error toast | |
| **Adding Favorite App:** | |
| 1. User clicks "Add Favorite App" button | |
| 2. If favorites.length === 6 → Show "Maximum reached" message | |
| 3. Else → Call `GET /api/v1/auth/me/preferences/available-apps` | |
| 4. Filter out already favorited apps | |
| 5. Show modal with available apps | |
| 6. User selects app → Add to favorites array | |
| 7. Update UI immediately | |
| 8. Call `PUT` endpoint with new array | |
| 9. On success: Close modal | |
| 10. On error: Remove app from array, show error | |
| ### Theme Toggle Implementation | |
| **Toggle Component:** | |
| 1. Read current theme from preferences state | |
| 2. Render toggle switch (Light/Dark) or three-way selector (Light/Dark/Auto) | |
| 3. On click: | |
| - Update UI theme immediately | |
| - Call `PUT /api/v1/auth/me/preferences` with `{"theme": newTheme}` | |
| - Show loading indicator on toggle | |
| - On success: Remove loading indicator | |
| - On error: Revert theme, show error | |
| **Auto Theme Handling:** | |
| 1. If theme is "auto", detect system preference: | |
| ```javascript | |
| const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' | |
| ``` | |
| 2. Apply system theme to UI | |
| 3. Listen for changes: | |
| ```javascript | |
| window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { | |
| if (preferences.theme === 'auto') { | |
| applyTheme(e.matches ? 'dark' : 'light') | |
| } | |
| }) | |
| ``` | |
| --- | |
| ## Testing Recommendations | |
| ### Unit Tests | |
| - Test preference state management (Redux/Vuex actions) | |
| - Test validation logic (max 6 apps, valid values) | |
| - Test app code to route mapping | |
| - Test theme application logic | |
| ### Integration Tests | |
| - Test full settings page flow (fetch → edit → save) | |
| - Test favorite app picker flow | |
| - Test theme toggle with API calls | |
| - Test error handling and rollback | |
| ### E2E Tests | |
| - Test complete user journey: Login → Change preferences → Logout → Login (preferences persisted) | |
| - Test preference changes reflect across multiple tabs | |
| - Test offline handling and sync on reconnect | |
| --- | |
| ## Migration Guide | |
| If your app currently stores preferences differently: | |
| 1. **Phase 1: Dual Read** - Read from old storage, fallback to new API | |
| 2. **Phase 2: Migrate Data** - Background job to copy old preferences to new system | |
| 3. **Phase 3: Dual Write** - Write to both old and new storage | |
| 4. **Phase 4: Cut Over** - Stop reading from old storage, read from API only | |
| 5. **Phase 5: Cleanup** - Remove old preference storage code | |
| --- | |
| ## Support & Troubleshooting | |
| ### Common Issues | |
| **Issue:** Preferences not saving | |
| **Solution:** Check network tab for API errors, verify authentication token is valid | |
| **Issue:** Default preferences not created | |
| **Solution:** Preferences are auto-created on first GET request, ensure user is authenticated | |
| **Issue:** Theme not applying | |
| **Solution:** Ensure theme CSS classes/variables are correctly wired to preference value | |
| **Issue:** Favorite apps showing wrong apps for role | |
| **Solution:** Fetch available apps from API, don't hardcode app lists in frontend | |
| ### Debug Checklist | |
| - [ ] User is authenticated (valid token) | |
| - [ ] API endpoint returns 200 status | |
| - [ ] Response data structure matches expected format | |
| - [ ] Preferences are stored in state manager | |
| - [ ] UI components read from state correctly | |
| - [ ] Optimistic updates revert on error | |
| - [ ] Error messages are displayed to user | |
| --- | |
| ## API Versioning | |
| Current Version: **v1** | |
| All endpoints are under `/api/v1/auth/me/preferences` | |
| Breaking changes will be introduced in new API versions (v2, v3, etc.) with deprecation notices. | |
| --- | |
| ## Changelog | |
| **Version 1.0** (Current) | |
| - Initial release | |
| - Support for favorite apps, theme, notifications, dashboard widgets | |
| - Role-based defaults and validation | |
| - Maximum 6 favorite apps constraint | |
| --- | |
| ## Additional Resources | |
| - **User Management API:** See general user profile endpoints | |
| - **Authentication API:** Token management and session handling | |
| - **Role Definitions:** Complete list of roles and permissions | |
| --- | |
| **Last Updated:** November 18, 2025 | |
| **Maintained By:** SwiftOps Backend Team | |