from sqlalchemy import ForeignKey, Integer, Text from sqlalchemy.dialects.postgresql import ARRAY, JSONB from sqlalchemy.orm import Mapped, mapped_column from scribe.models import Base from scribe.models.base import TimestampMixin class UserProfile(Base, TimestampMixin): __tablename__ = "user_profiles" id: Mapped[int] = mapped_column(primary_key=True) user_id: Mapped[int] = mapped_column( Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, unique=True ) display_name: Mapped[str | None] = mapped_column(Text, nullable=True) job_title: Mapped[str | None] = mapped_column(Text, nullable=True) industry: Mapped[str | None] = mapped_column(Text, nullable=True) # novice / intermediate / expert — calibrates explanation depth expertise_level: Mapped[str | None] = mapped_column(Text, nullable=True) # concise / balanced / detailed response_style: Mapped[str | None] = mapped_column(Text, nullable=True) # casual / professional / technical tone: Mapped[str | None] = mapped_column(Text, nullable=True) interests: Mapped[list[str] | None] = mapped_column(ARRAY(Text), nullable=True) # {days: ["Mon","Tue",...], start: "09:00", end: "17:00"} work_schedule: Mapped[dict | None] = mapped_column(JSONB, nullable=True) def to_dict(self) -> dict: return { "display_name": self.display_name or "", "job_title": self.job_title or "", "industry": self.industry or "", "expertise_level": self.expertise_level or "intermediate", "response_style": self.response_style or "balanced", "tone": self.tone or "casual", "interests": self.interests or [], "work_schedule": self.work_schedule or {}, }