from datetime import datetime from typing import Any from sqlalchemy import ( JSON, BigInteger, Boolean, DateTime, Float, Integer, String, Text, UniqueConstraint, func, ) from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(DeclarativeBase): pass class TelegramUser(Base): __tablename__ = "telegram_users" telegram_id: Mapped[int] = mapped_column(BigInteger, primary_key=True) display_name: Mapped[str] = mapped_column(String(255), default="") username: Mapped[str | None] = mapped_column(String(255)) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class AllowedChat(Base): __tablename__ = "allowed_chats" chat_id: Mapped[int] = mapped_column(BigInteger, primary_key=True) kind: Mapped[str] = mapped_column(String(32), default="group") enabled: Mapped[bool] = mapped_column(Boolean, default=True) class Message(Base): __tablename__ = "messages" __table_args__ = ( UniqueConstraint("chat_id", "telegram_message_id", name="uq_message_chat_id"), ) id: Mapped[int] = mapped_column(primary_key=True) chat_id: Mapped[int] = mapped_column(BigInteger, index=True) telegram_message_id: Mapped[int] = mapped_column(BigInteger) thread_id: Mapped[int | None] = mapped_column(BigInteger, index=True) user_id: Mapped[int | None] = mapped_column(BigInteger, index=True) user_name: Mapped[str] = mapped_column(String(255), default="") text: Mapped[str] = mapped_column(Text, default="") sent_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), index=True) reply_to_message_id: Mapped[int | None] = mapped_column(BigInteger) edited: Mapped[bool] = mapped_column(Boolean, default=False) edited_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) message_type: Mapped[str] = mapped_column(String(32), default="text") attachment_data: Mapped[dict[str, Any] | None] = mapped_column(JSON) class Summary(Base): __tablename__ = "summaries" id: Mapped[int] = mapped_column(primary_key=True) chat_id: Mapped[int] = mapped_column(BigInteger, index=True) thread_id: Mapped[int | None] = mapped_column(BigInteger, index=True) version: Mapped[int] = mapped_column(Integer) text: Mapped[str] = mapped_column(Text) from_message_id: Mapped[int] = mapped_column(BigInteger) to_message_id: Mapped[int] = mapped_column(BigInteger) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class PromptVersion(Base): __tablename__ = "prompt_versions" id: Mapped[int] = mapped_column(primary_key=True) version: Mapped[int] = mapped_column(Integer, unique=True) text: Mapped[str] = mapped_column(Text) author_id: Mapped[int] = mapped_column(BigInteger) active: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class Setting(Base): __tablename__ = "settings" key: Mapped[str] = mapped_column(String(100), primary_key=True) value: Mapped[str] = mapped_column(Text) class RepositoryState(Base): __tablename__ = "repository_state" id: Mapped[int] = mapped_column(primary_key=True) branch: Mapped[str] = mapped_column(String(255)) commit: Mapped[str] = mapped_column(String(64)) synced_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class RepositoryBinding(Base): """The active read-only repository for a chat or a forum topic.""" __tablename__ = "repository_bindings" id: Mapped[int] = mapped_column(primary_key=True) chat_id: Mapped[int] = mapped_column(BigInteger, index=True) thread_id: Mapped[int | None] = mapped_column(BigInteger, index=True) url: Mapped[str] = mapped_column(String(2_000)) branch: Mapped[str] = mapped_column(String(255), default="HEAD") cache_path: Mapped[str] = mapped_column(String(2_000), unique=True) commit: Mapped[str] = mapped_column(String(64)) attached_by: Mapped[int] = mapped_column(BigInteger) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) synced_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class ProactiveReply(Base): __tablename__ = "proactive_replies" id: Mapped[int] = mapped_column(primary_key=True) chat_id: Mapped[int] = mapped_column(BigInteger, index=True) source_message_id: Mapped[int] = mapped_column(BigInteger, index=True) answer_message_id: Mapped[int | None] = mapped_column(BigInteger) fingerprint: Mapped[str] = mapped_column(String(64), index=True) confidence: Mapped[float] = mapped_column(Float) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class Attachment(Base): __tablename__ = "attachments" id: Mapped[int] = mapped_column(primary_key=True) chat_id: Mapped[int] = mapped_column(BigInteger, index=True) message_id: Mapped[int] = mapped_column(BigInteger) uploaded_by: Mapped[int] = mapped_column(BigInteger) filename: Mapped[str] = mapped_column(String(512)) mime_type: Mapped[str | None] = mapped_column(String(255)) size: Mapped[int] = mapped_column(Integer) mode: Mapped[str] = mapped_column(String(32), default="pending") extracted_text: Mapped[str | None] = mapped_column(Text) accepted: Mapped[bool] = mapped_column(Boolean, default=False) class Correction(Base): __tablename__ = "corrections" id: Mapped[int] = mapped_column(primary_key=True) chat_id: Mapped[int] = mapped_column(BigInteger, index=True) source_message_id: Mapped[int] = mapped_column(BigInteger) text: Mapped[str] = mapped_column(Text) author_id: Mapped[int] = mapped_column(BigInteger) confirmed: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())