"""SQLAlchemy ORM models for users and duties.""" from sqlalchemy import ForeignKey, Integer, BigInteger, Text from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): """Declarative base for all models.""" pass class User(Base): __tablename__ = "users" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) telegram_user_id: Mapped[int | None] = mapped_column( BigInteger, unique=True, nullable=True ) full_name: Mapped[str] = mapped_column(Text, nullable=False) username: Mapped[str | None] = mapped_column(Text, nullable=True) first_name: Mapped[str | None] = mapped_column(Text, nullable=True) last_name: Mapped[str | None] = mapped_column(Text, nullable=True) phone: Mapped[str | None] = mapped_column(Text, nullable=True) duties: Mapped[list["Duty"]] = relationship("Duty", back_populates="user") class Duty(Base): __tablename__ = "duties" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column( Integer, ForeignKey("users.id"), nullable=False ) # UTC, ISO 8601 with Z suffix (e.g. 2025-01-15T09:00:00Z) start_at: Mapped[str] = mapped_column(Text, nullable=False) end_at: Mapped[str] = mapped_column(Text, nullable=False) # duty | unavailable | vacation event_type: Mapped[str] = mapped_column(Text, nullable=False, server_default="duty") user: Mapped["User"] = relationship("User", back_populates="duties") class GroupDutyPin(Base): """Stores which message to update in each group for the pinned duty notice.""" __tablename__ = "group_duty_pins" chat_id: Mapped[int] = mapped_column(BigInteger, primary_key=True) message_id: Mapped[int] = mapped_column(Integer, nullable=False)