All checks were successful
CI / lint-and-test (push) Successful in 17s
- Created a new `CHANGELOG.md` file to document all notable changes to the project, adhering to the Keep a Changelog format. - Updated `CONTRIBUTING.md` to include instructions for building and previewing documentation using MkDocs. - Added `mkdocs.yml` configuration for documentation generation, including navigation structure and theme settings. - Enhanced various documentation files, including API reference, architecture overview, configuration reference, and runbook, to provide comprehensive guidance for users and developers. - Included new sections in the README for changelog and documentation links, improving accessibility to project information.
72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
"""SQLAlchemy ORM models for users and duties."""
|
|
|
|
from sqlalchemy import Boolean, 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):
|
|
"""Telegram user and display name; may have telegram_user_id=None for import-only users."""
|
|
|
|
__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)
|
|
name_manually_edited: Mapped[bool] = mapped_column(
|
|
Boolean, nullable=False, server_default="0", default=False
|
|
)
|
|
|
|
duties: Mapped[list["Duty"]] = relationship("Duty", back_populates="user")
|
|
|
|
|
|
class CalendarSubscriptionToken(Base):
|
|
"""One active calendar subscription token per user; token_hash is unique."""
|
|
|
|
__tablename__ = "calendar_subscription_tokens"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
user_id: Mapped[int] = mapped_column(
|
|
Integer, ForeignKey("users.id"), nullable=False
|
|
)
|
|
token_hash: Mapped[str] = mapped_column(Text, nullable=False, unique=True)
|
|
created_at: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
|
|
|
class Duty(Base):
|
|
"""Single duty/unavailable/vacation slot (UTC start_at/end_at, event_type)."""
|
|
|
|
__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)
|