from sqlalchemy import String, Text, Integer, Float, Boolean, ForeignKey, func from sqlalchemy.orm import Mapped, mapped_column from datetime import datetime from typing import Optional from app.database import Base class Settings(Base): __tablename__ = "settings" id: Mapped[int] = mapped_column(primary_key=True, index=True) # FK to users table — NOT NULL enforced by migration 023 after data backfill user_id: Mapped[int] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True, ) accent_color: Mapped[str] = mapped_column(String(20), default="cyan") upcoming_days: Mapped[int] = mapped_column(Integer, default=7) preferred_name: Mapped[str | None] = mapped_column(String(100), nullable=True, default=None) weather_city: Mapped[str | None] = mapped_column(String(100), nullable=True, default=None) weather_lat: Mapped[float | None] = mapped_column(Float, nullable=True, default=None) weather_lon: Mapped[float | None] = mapped_column(Float, nullable=True, default=None) first_day_of_week: Mapped[int] = mapped_column(Integer, default=0) # 0=Sunday, 1=Monday # ntfy push notification configuration ntfy_server_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True, default=None) ntfy_topic: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, default=None) ntfy_auth_token: Mapped[Optional[str]] = mapped_column(String(500), nullable=True, default=None) ntfy_enabled: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") # Per-type notification toggles (default on so they work immediately once master is enabled) ntfy_events_enabled: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true") ntfy_reminders_enabled: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true") ntfy_todos_enabled: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true") ntfy_projects_enabled: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true") # Lead time controls ntfy_event_lead_minutes: Mapped[int] = mapped_column(Integer, default=15, server_default="15") ntfy_todo_lead_days: Mapped[int] = mapped_column(Integer, default=1, server_default="1") ntfy_project_lead_days: Mapped[int] = mapped_column(Integer, default=2, server_default="2") # Auto-lock settings auto_lock_enabled: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") auto_lock_minutes: Mapped[int] = mapped_column(Integer, default=5, server_default="5") # Profile fields (shareable with connections) phone: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, default=None) mobile: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, default=None) address: Mapped[Optional[str]] = mapped_column(Text, nullable=True, default=None) company: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, default=None) job_title: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, default=None) # Social settings accept_connections: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") # Sharing defaults (what fields are shared with connections by default) share_first_name: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_last_name: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_preferred_name: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true") share_email: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_phone: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_mobile: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_birthday: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_address: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_company: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") share_job_title: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") # ntfy connection notification toggle (gates push only, not in-app) ntfy_connections_enabled: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true") @property def ntfy_has_token(self) -> bool: """Derived field for SettingsResponse — True when an auth token is stored.""" return bool(self.ntfy_auth_token) created_at: Mapped[datetime] = mapped_column(default=func.now()) updated_at: Mapped[datetime] = mapped_column(default=func.now(), onupdate=func.now())