diff --git a/app/database/crud/rules.py b/app/database/crud/rules.py index c66fa05f..43de490d 100644 --- a/app/database/crud/rules.py +++ b/app/database/crud/rules.py @@ -1,6 +1,6 @@ import logging from typing import Optional -from sqlalchemy import select +from sqlalchemy import select, update from sqlalchemy.ext.asyncio import AsyncSession from datetime import datetime @@ -53,10 +53,37 @@ async def create_or_update_rules( await db.commit() await db.refresh(new_rules) - logger.info(f"✅ Правила для языка {language} обновлены") + logger.info(f"✅ Правила для языка {language} обновлены (ID: {new_rules.id})") return new_rules +async def clear_all_rules(db: AsyncSession, language: str = "ru") -> bool: + try: + result = await db.execute( + update(ServiceRule) + .where( + ServiceRule.language == language, + ServiceRule.is_active == True + ) + .values( + is_active=False, + updated_at=datetime.utcnow() + ) + ) + + await db.commit() + + rows_affected = result.rowcount + logger.info(f"✅ Очищены правила для языка {language}. Деактивировано записей: {rows_affected}") + + return rows_affected > 0 + + except Exception as e: + logger.error(f"❌ Ошибка при очистке правил для языка {language}: {e}") + await db.rollback() + raise + + async def get_current_rules_content(db: AsyncSession, language: str = "ru") -> str: rules = await get_rules_by_language(db, language) @@ -79,4 +106,113 @@ async def get_current_rules_content(db: AsyncSession, language: str = "ru") -> s 6. При возникновении вопросов обращайтесь в техническую поддержку. Используя сервис, вы соглашаетесь с данными правилами. -""" \ No newline at end of file +""" + + +async def get_all_rules_versions( + db: AsyncSession, + language: str = "ru", + limit: int = 10 +) -> list[ServiceRule]: + result = await db.execute( + select(ServiceRule) + .where(ServiceRule.language == language) + .order_by(ServiceRule.created_at.desc()) + .limit(limit) + ) + return result.scalars().all() + + +async def restore_rules_version( + db: AsyncSession, + rule_id: int, + language: str = "ru" +) -> Optional[ServiceRule]: + try: + result = await db.execute( + select(ServiceRule).where( + ServiceRule.id == rule_id, + ServiceRule.language == language + ) + ) + rule_to_restore = result.scalar_one_or_none() + + if not rule_to_restore: + logger.warning(f"Правило с ID {rule_id} не найдено для языка {language}") + return None + + await db.execute( + update(ServiceRule) + .where( + ServiceRule.language == language, + ServiceRule.is_active == True + ) + .values( + is_active=False, + updated_at=datetime.utcnow() + ) + ) + + restored_rule = ServiceRule( + title=rule_to_restore.title, + content=rule_to_restore.content, + language=language, + is_active=True, + order=0 + ) + + db.add(restored_rule) + await db.commit() + await db.refresh(restored_rule) + + logger.info(f"✅ Восстановлена версия правил ID {rule_id} как новое правило ID {restored_rule.id}") + return restored_rule + + except Exception as e: + logger.error(f"❌ Ошибка при восстановлении правил ID {rule_id}: {e}") + await db.rollback() + raise + + +async def get_rules_statistics(db: AsyncSession) -> dict: + try: + active_result = await db.execute( + select(ServiceRule).where(ServiceRule.is_active == True) + ) + active_rules = active_result.scalars().all() + + all_result = await db.execute(select(ServiceRule)) + all_rules = all_result.scalars().all() + + languages_stats = {} + for rule in active_rules: + lang = rule.language + if lang not in languages_stats: + languages_stats[lang] = { + 'active_count': 0, + 'last_updated': None, + 'content_length': 0 + } + + languages_stats[lang]['active_count'] += 1 + languages_stats[lang]['content_length'] = len(rule.content) + + if not languages_stats[lang]['last_updated'] or rule.updated_at > languages_stats[lang]['last_updated']: + languages_stats[lang]['last_updated'] = rule.updated_at + + return { + 'total_active': len(active_rules), + 'total_all_time': len(all_rules), + 'languages': languages_stats, + 'total_languages': len(languages_stats) + } + + except Exception as e: + logger.error(f"❌ Ошибка при получении статистики правил: {e}") + return { + 'total_active': 0, + 'total_all_time': 0, + 'languages': {}, + 'total_languages': 0, + 'error': str(e) + }