feat: персональные AI модели, оптимизация задач, фильтрация словаря
- Добавлена поддержка персональных AI моделей для каждого пользователя - Оптимизация создания заданий: батч-запрос к AI вместо N запросов - Фильтрация слов по языку изучения (source_lang) в словаре - Удалены неиспользуемые колонки examples и category из vocabulary - Миграции для ai_model_id и удаления колонок 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,6 @@ class VocabularyService:
|
||||
source_lang: Optional[str] = None,
|
||||
translation_lang: Optional[str] = None,
|
||||
transcription: Optional[str] = None,
|
||||
examples: Optional[dict] = None,
|
||||
category: Optional[str] = None,
|
||||
difficulty_level: Optional[str] = None,
|
||||
source: WordSource = WordSource.MANUAL,
|
||||
notes: Optional[str] = None
|
||||
@@ -32,8 +30,6 @@ class VocabularyService:
|
||||
word_original: Оригинальное слово
|
||||
word_translation: Перевод
|
||||
transcription: Транскрипция
|
||||
examples: Примеры использования
|
||||
category: Категория слова
|
||||
difficulty_level: Уровень сложности
|
||||
source: Источник добавления
|
||||
notes: Заметки пользователя
|
||||
@@ -56,8 +52,6 @@ class VocabularyService:
|
||||
source_lang=source_lang,
|
||||
translation_lang=translation_lang,
|
||||
transcription=transcription,
|
||||
examples=examples,
|
||||
category=category,
|
||||
difficulty_level=difficulty_enum,
|
||||
source=source,
|
||||
notes=notes
|
||||
@@ -138,7 +132,12 @@ class VocabularyService:
|
||||
return len(words)
|
||||
|
||||
@staticmethod
|
||||
async def find_word(session: AsyncSession, user_id: int, word: str) -> Optional[Vocabulary]:
|
||||
async def find_word(
|
||||
session: AsyncSession,
|
||||
user_id: int,
|
||||
word: str,
|
||||
source_lang: Optional[str] = None
|
||||
) -> Optional[Vocabulary]:
|
||||
"""
|
||||
Найти слово в словаре пользователя
|
||||
|
||||
@@ -146,19 +145,28 @@ class VocabularyService:
|
||||
session: Сессия базы данных
|
||||
user_id: ID пользователя
|
||||
word: Слово для поиска
|
||||
source_lang: Язык изучения для фильтрации (если указан)
|
||||
|
||||
Returns:
|
||||
Объект слова или None
|
||||
"""
|
||||
result = await session.execute(
|
||||
query = (
|
||||
select(Vocabulary)
|
||||
.where(Vocabulary.user_id == user_id)
|
||||
.where(Vocabulary.word_original.ilike(f"%{word}%"))
|
||||
)
|
||||
if source_lang:
|
||||
query = query.where(Vocabulary.source_lang == source_lang.lower())
|
||||
result = await session.execute(query)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def get_word_by_original(session: AsyncSession, user_id: int, word: str) -> Optional[Vocabulary]:
|
||||
async def get_word_by_original(
|
||||
session: AsyncSession,
|
||||
user_id: int,
|
||||
word: str,
|
||||
source_lang: Optional[str] = None
|
||||
) -> Optional[Vocabulary]:
|
||||
"""
|
||||
Получить слово по точному совпадению
|
||||
|
||||
@@ -166,15 +174,19 @@ class VocabularyService:
|
||||
session: Сессия базы данных
|
||||
user_id: ID пользователя
|
||||
word: Слово для поиска (точное совпадение)
|
||||
source_lang: Язык изучения для фильтрации (если указан)
|
||||
|
||||
Returns:
|
||||
Объект слова или None
|
||||
"""
|
||||
result = await session.execute(
|
||||
query = (
|
||||
select(Vocabulary)
|
||||
.where(Vocabulary.user_id == user_id)
|
||||
.where(Vocabulary.word_original == word.lower())
|
||||
)
|
||||
if source_lang:
|
||||
query = query.where(Vocabulary.source_lang == source_lang.lower())
|
||||
result = await session.execute(query)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user