feat: добавлена система миграций БД и CI/CD пайплайны

- Создана система отслеживания миграций (MigrationRepository, таблица migrations)
- Добавлен скрипт apply_migrations.py для автоматического применения миграций
- Созданы CI/CD пайплайны (.github/workflows/ci.yml, deploy.yml)
- Обновлена документация по миграциям в database-patterns.md
- Миграции применяются автоматически при деплое в продакшн
This commit is contained in:
2026-01-25 23:17:09 +03:00
parent 07e72c4d14
commit e2b1353408
109 changed files with 1342 additions and 1441 deletions

View File

@@ -1,27 +1,13 @@
"""Private handlers package for Telegram bot"""
# Local imports - main components
from .private_handlers import (
private_router,
create_private_handlers,
PrivateHandlers
)
# Local imports - services
from .services import (
BotSettings,
UserService,
PostService,
StickerService
)
# Local imports - constants and utilities
from .constants import (
FSM_STATES,
BUTTON_TEXTS,
ERROR_MESSAGES
)
from .constants import BUTTON_TEXTS, ERROR_MESSAGES, FSM_STATES
from .decorators import error_handler
from .private_handlers import (PrivateHandlers, create_private_handlers,
private_router)
# Local imports - services
from .services import BotSettings, PostService, StickerService, UserService
__all__ = [
# Main components

View File

@@ -1,6 +1,6 @@
"""Constants for private handlers"""
from typing import Final, Dict
from typing import Dict, Final
# FSM States
FSM_STATES: Final[Dict[str, str]] = {

View File

@@ -6,7 +6,6 @@ from typing import Any, Callable
# Third-party imports
from aiogram import types
# Local imports
from logs.custom_logger import logger
@@ -22,7 +21,8 @@ def error_handler(func: Callable[..., Any]) -> Callable[..., Any]:
try:
message = next((arg for arg in args if isinstance(arg, types.Message)), None)
if message and hasattr(message, 'bot'):
from helper_bot.utils.base_dependency_factory import get_global_instance
from helper_bot.utils.base_dependency_factory import \
get_global_instance
bdf = get_global_instance()
important_logs = bdf.settings['Telegram']['important_logs']
await message.bot.send_message(

View File

@@ -5,37 +5,28 @@ import asyncio
from datetime import datetime
# Third-party imports
from aiogram import types, Router, F
from aiogram import F, Router, types
from aiogram.filters import Command, StateFilter
from aiogram.fsm.context import FSMContext
# Local imports - filters and middlewares
from database.async_db import AsyncBotDB
from helper_bot.filters.main import ChatTypeFilter
# Local imports - utilities
from helper_bot.keyboards import (get_reply_keyboard,
get_reply_keyboard_for_post)
from helper_bot.keyboards.keyboards import get_reply_keyboard_leave_chat
from helper_bot.middlewares.album_middleware import AlbumMiddleware
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
# Local imports - utilities
from helper_bot.keyboards import get_reply_keyboard, get_reply_keyboard_for_post
from helper_bot.keyboards.keyboards import get_reply_keyboard_leave_chat
from helper_bot.utils import messages
from helper_bot.utils.helper_func import (
get_first_name,
update_user_info,
check_user_emoji
)
from helper_bot.utils.helper_func import (check_user_emoji, get_first_name,
update_user_info)
# Local imports - metrics
from helper_bot.utils.metrics import (
track_time,
track_errors,
db_query_time
)
from helper_bot.utils.metrics import db_query_time, track_errors, track_time
# Local imports - modular components
from .constants import FSM_STATES, BUTTON_TEXTS, ERROR_MESSAGES
from .services import BotSettings, UserService, PostService, StickerService
from .constants import BUTTON_TEXTS, ERROR_MESSAGES, FSM_STATES
from .decorators import error_handler
from .services import BotSettings, PostService, StickerService, UserService
# Expose sleep for tests (tests patch helper_bot.handlers.private.private_handlers.sleep)
sleep = asyncio.sleep

View File

@@ -1,46 +1,31 @@
"""Service classes for private handlers"""
# Standard library imports
import random
import asyncio
import html
import random
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Dict, Callable, Any, Protocol, Union
from dataclasses import dataclass
from typing import Any, Callable, Dict, Protocol, Union
# Third-party imports
from aiogram import types
from aiogram.types import FSInputFile
from database.models import TelegramPost, User
from logs.custom_logger import logger
from helper_bot.keyboards import get_reply_keyboard_for_post
# Local imports - utilities
from helper_bot.utils.helper_func import (
get_first_name,
get_text_message,
determine_anonymity,
send_text_message,
send_photo_message,
send_media_group_message_to_private_chat,
prepare_media_group_from_middlewares,
send_video_message,
send_video_note_message,
send_audio_message,
send_voice_message,
add_in_db_media,
check_username_and_full_name
)
from helper_bot.keyboards import get_reply_keyboard_for_post
add_in_db_media, check_username_and_full_name, determine_anonymity,
get_first_name, get_text_message, prepare_media_group_from_middlewares,
send_audio_message, send_media_group_message_to_private_chat,
send_photo_message, send_text_message, send_video_message,
send_video_note_message, send_voice_message)
# Local imports - metrics
from helper_bot.utils.metrics import (
track_time,
track_errors,
db_query_time,
track_media_processing,
track_file_operations
)
from helper_bot.utils.metrics import (db_query_time, track_errors,
track_file_operations,
track_media_processing, track_time)
from logs.custom_logger import logger
class DatabaseProtocol(Protocol):