"""Базовые модели данных для GPU воркера (минимальный набор для работы с БД).""" from datetime import datetime from uuid import uuid4 from sqlalchemy import JSON, BigInteger, ForeignKey, Integer, String, Text, func from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): """Базовый класс SQLAlchemy моделей.""" pass class User(Base): """Минимальная модель пользователя для GPU воркера.""" __tablename__ = "users" id: Mapped[int] = mapped_column(Integer, primary_key=True) email: Mapped[str] = mapped_column(String(255)) name: Mapped[str] = mapped_column(String(255)) plan: Mapped[str] = mapped_column(String(20), default="free") is_verified: Mapped[bool] = mapped_column(default=False) created_at: Mapped[datetime] = mapped_column(server_default=func.now()) class Task(Base): """Модель задачи.""" __tablename__ = "tasks" id: Mapped[str] = mapped_column(String(36), primary_key=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id")) type: Mapped[str] = mapped_column(String(20)) status: Mapped[str] = mapped_column(String(20), default="queued") celery_task_id: Mapped[str | None] = mapped_column(String(255), nullable=True) input_data: Mapped[dict] = mapped_column(JSON, default=dict) result: Mapped[dict | None] = mapped_column(JSON, nullable=True) error: Mapped[str | None] = mapped_column(Text, nullable=True) queue_position: Mapped[int | None] = mapped_column(nullable=True) created_at: Mapped[datetime] = mapped_column(server_default=func.now()) updated_at: Mapped[datetime | None] = mapped_column(nullable=True) class Document(Base): """Модель документа в базе знаний.""" __tablename__ = "documents" id: Mapped[int] = mapped_column(Integer, primary_key=True) source: Mapped[str] = mapped_column(String(50)) ext_id: Mapped[str] = mapped_column(String(255)) doi: Mapped[str | None] = mapped_column(String(255), nullable=True) title: Mapped[str] = mapped_column(Text) authors: Mapped[list] = mapped_column(JSON, default=list) year: Mapped[int | None] = mapped_column(nullable=True) lang: Mapped[str | None] = mapped_column(String(10), nullable=True) journal: Mapped[str | None] = mapped_column(Text, nullable=True) volume: Mapped[str | None] = mapped_column(String(50), nullable=True) issue: Mapped[str | None] = mapped_column(String(50), nullable=True) pages: Mapped[str | None] = mapped_column(String(50), nullable=True) abstract: Mapped[str | None] = mapped_column(Text, nullable=True) url: Mapped[str | None] = mapped_column(Text, nullable=True) minio_key: Mapped[str | None] = mapped_column(Text, nullable=True) faiss_id: Mapped[int | None] = mapped_column(nullable=True) indexed_at: Mapped[datetime] = mapped_column(server_default=func.now())