from datetime import datetime, timezone from flask_login import UserMixin from sqlalchemy import String from sqlalchemy.orm import Mapped, mapped_column from werkzeug.security import check_password_hash, generate_password_hash from app.extensions import db, login_manager class User(UserMixin, db.Model): id: Mapped[int] = mapped_column(primary_key=True) username: Mapped[str] = mapped_column(String(80), unique=True, index=True) email: Mapped[str] = mapped_column(String(254), unique=True, index=True) password_hash: Mapped[str] = mapped_column(String(256)) role: Mapped[str] = mapped_column(String(20), default="user") created_at: Mapped[datetime] = mapped_column( default=lambda: datetime.now(timezone.utc) ) theme: Mapped[str] = mapped_column(String(20), default="auto") completion_chime: Mapped[bool] = mapped_column(default=True) dyslexia_font: Mapped[bool] = mapped_column(default=False) notification_frequency: Mapped[str] = mapped_column( String(20), default="quiet" ) def set_password(self, password: str) -> None: self.password_hash = generate_password_hash(password) def check_password(self, password: str) -> bool: return check_password_hash(self.password_hash, password) @login_manager.user_loader def load_user(user_id: str) -> User | None: if not user_id.isdigit(): return None return db.session.get(User, int(user_id))