Files
tg_bot_language/database/models.py

84 lines
3.8 KiB
Python
Raw Normal View History

from datetime import datetime
from typing import Optional
from sqlalchemy import String, BigInteger, DateTime, Integer, Boolean, JSON, Enum as SQLEnum
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
import enum
class Base(DeclarativeBase):
"""Базовая модель"""
pass
class LanguageLevel(str, enum.Enum):
"""Уровни владения языком"""
A1 = "A1"
A2 = "A2"
B1 = "B1"
B2 = "B2"
C1 = "C1"
C2 = "C2"
class WordSource(str, enum.Enum):
"""Источник добавления слова"""
MANUAL = "manual" # Ручное добавление
SUGGESTED = "suggested" # Предложено ботом
CONTEXT = "context" # Из контекста диалога
IMPORT = "import" # Импорт из текста
ERROR = "error" # Из ошибок в заданиях
class User(Base):
"""Модель пользователя"""
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
telegram_id: Mapped[int] = mapped_column(BigInteger, unique=True, nullable=False)
username: Mapped[Optional[str]] = mapped_column(String(255))
language_interface: Mapped[str] = mapped_column(String(2), default="ru") # ru/en
learning_language: Mapped[str] = mapped_column(String(2), default="en") # en
level: Mapped[LanguageLevel] = mapped_column(SQLEnum(LanguageLevel), default=LanguageLevel.A1)
timezone: Mapped[str] = mapped_column(String(50), default="UTC")
daily_task_time: Mapped[Optional[str]] = mapped_column(String(5)) # HH:MM
streak_days: Mapped[int] = mapped_column(Integer, default=0)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
last_active: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Vocabulary(Base):
"""Модель словарного запаса"""
__tablename__ = "vocabulary"
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
word_original: Mapped[str] = mapped_column(String(255), nullable=False)
word_translation: Mapped[str] = mapped_column(String(255), nullable=False)
transcription: Mapped[Optional[str]] = mapped_column(String(255))
examples: Mapped[Optional[dict]] = mapped_column(JSON) # JSON массив примеров
category: Mapped[Optional[str]] = mapped_column(String(100))
difficulty_level: Mapped[Optional[LanguageLevel]] = mapped_column(SQLEnum(LanguageLevel))
source: Mapped[WordSource] = mapped_column(SQLEnum(WordSource), default=WordSource.MANUAL)
times_reviewed: Mapped[int] = mapped_column(Integer, default=0)
correct_answers: Mapped[int] = mapped_column(Integer, default=0)
last_reviewed: Mapped[Optional[datetime]] = mapped_column(DateTime)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
notes: Mapped[Optional[str]] = mapped_column(String(500)) # Заметки пользователя
class Task(Base):
"""Модель задания"""
__tablename__ = "tasks"
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
task_type: Mapped[str] = mapped_column(String(50), nullable=False) # translate, sentence, fill, etc.
content: Mapped[dict] = mapped_column(JSON, nullable=False) # Содержание задания
correct_answer: Mapped[Optional[str]] = mapped_column(String(500))
user_answer: Mapped[Optional[str]] = mapped_column(String(500))
is_correct: Mapped[Optional[bool]] = mapped_column(Boolean)
ai_feedback: Mapped[Optional[str]] = mapped_column(String(1000))
completed_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)