swiftops-backend / src /app /models /user_preference.py
kamau1's picture
feat: hub tracking and last active project preference
ae9649e
"""
User Preferences Model
Stores user-specific UI preferences, favorites, theme, and settings
"""
from sqlalchemy import Column, String, Boolean, Integer, Float, ForeignKey, ARRAY, Text
from sqlalchemy.dialects.postgresql import UUID, JSONB
from app.models.base import BaseModel
class UserPreference(BaseModel):
"""
User Preferences model - One row per user
Stores UI preferences, favorites, theme, and settings
"""
__tablename__ = "user_preferences"
# Link to user
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id', ondelete='CASCADE'), nullable=False, unique=True)
# Favorite Apps (for 9-dot app launcher)
# Array of app codes that appear in the top navigation bar
# Max: 6 favorites (enforced in application logic)
favorite_apps = Column(ARRAY(Text), default=['dashboard', 'tickets', 'projects', 'maps'])
# UI Preferences
theme = Column(String(50), default='dark') # 'light', 'dark', 'auto'
language = Column(String(10), default='en') # 'en', 'sw' (Swahili), 'fr', etc.
# Notification Preferences
email_notifications = Column(Boolean, default=True)
push_notifications = Column(Boolean, default=True)
sms_notifications = Column(Boolean, default=False)
# Dashboard Layout (which widgets to show)
# Array of widget codes: ['recent_tickets', 'team_performance', 'sla_metrics', 'map_view']
dashboard_widgets = Column(ARRAY(Text), default=['recent_tickets', 'team_performance', 'sla_metrics'])
# Table/List Preferences
default_tickets_view = Column(String(50), default='list') # 'list', 'kanban', 'calendar'
tickets_per_page = Column(Integer, default=25) # Pagination size
default_sort_field = Column(String(100), default='created_at') # Default sort field
default_sort_order = Column(String(10), default='desc') # 'asc', 'desc'
# Map Preferences (for field agents and dispatchers)
default_map_zoom = Column(Integer, default=12)
default_map_center_lat = Column(Float, nullable=True) # User's preferred map center
default_map_center_lng = Column(Float, nullable=True)
# Project Context (for multi-project users)
last_active_project_id = Column(UUID(as_uuid=True), ForeignKey('projects.id', ondelete='SET NULL'), nullable=True)
# Additional settings (flexible JSONB for future expansion)
# Can store: sidebar_collapsed, compact_mode, color_blind_mode, etc.
additional_settings = Column(JSONB, default={})
def __repr__(self):
return f"<UserPreference(user_id='{self.user_id}', theme='{self.theme}')>"