"""User model with combinable roles and admin flag.""" from datetime import datetime from typing import Optional from sqlalchemy import Boolean, DateTime, Enum, Integer, JSON, String, func from sqlalchemy.orm import Mapped, mapped_column from database import Base class User(Base): __tablename__ = "users" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) username: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True) password_hash: Mapped[str] = mapped_column(String(255), nullable=False) email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) display_name: Mapped[str] = mapped_column(String(255), nullable=False) # Roles: combinable JSON array of "Maker", "MeasurementTec", "Metrologist" roles: Mapped[list] = mapped_column(JSON, nullable=False, default=list) # Admin flag separate from roles is_admin: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) # User preferences language_pref: Mapped[str] = mapped_column( Enum("it", "en", name="language_enum"), nullable=False, default="it" ) theme_pref: Mapped[str] = mapped_column( Enum("light", "dark", name="theme_enum"), nullable=False, default="light" ) # Status active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) api_key: Mapped[Optional[str]] = mapped_column(String(64), unique=True, nullable=True, index=True) # Timestamps created_at: Mapped[datetime] = mapped_column( DateTime, nullable=False, server_default=func.now() ) last_login: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) def has_role(self, role: str) -> bool: """Check if user has a specific role.""" return role in (self.roles or []) def __repr__(self) -> str: return f""