- Add ContextVarsMiddleware for automatic user_id/chat_id/username binding
via structlog contextvars (aiogram) and http_method/http_path (FastAPI)
- Use bound_contextvars() context manager instead of clear_contextvars()
to safely restore previous state instead of wiping all context
- Register ContextVarsMiddleware as outermost middleware (before GlobalError)
so all error logs include user context
- Replace structlog.get_logger() with structlog.get_logger(__name__) across
270 calls in 265 files for meaningful logger names
- Switch wrapper_class from BoundLogger to make_filtering_bound_logger()
for pre-processor level filtering (performance optimization)
- Migrate 1411 %-style positional arg logger calls to structlog kwargs
style across 161 files via AST script
- Migrate log_rotation_service.py from stdlib logging to structlog
- Add payment module prefixes to TelegramNotifierProcessor.IGNORED_LOGGER_PREFIXES
and ExcludePaymentFilter.PAYMENT_MODULES to prevent payment data leaking
to Telegram notifications and general log files
- Fix LoggingMiddleware: add from_user null-safety for channel posts,
switch time.time() to time.monotonic() for duration measurement
- Remove duplicate logger assignments in purchase.py, config.py,
inline.py, and admin/payments.py
- Add pyproject.toml with uv and ruff configuration
- Pin Python version to 3.13 via .python-version
- Add Makefile commands: lint, format, fix
- Apply ruff formatting to entire codebase
- Remove unused imports (base64 in yookassa/simple_subscription)
- Update .gitignore for new config files
Рефакторинг архитектуры ежедневных конкурсов:
- Создан модуль app/services/contests/ с новой архитектурой:
- enums.py: GameType, RoundStatus, PrizeType enum классы
- games.py: паттерн Стратегия для 7 типов игр
- attempt_service.py: ContestAttemptService для атомарных операций
- Упрощён handlers/contests.py:
- Удалены отдельные _render_* функции (заменены на стратегии)
- Логика обработки попыток вынесена в ContestAttemptService
- Уменьшено с 523 до 342 строк (-35%)
- Обновлён contest_rotation_service.py:
- Заменена if-elif цепочка на get_game_strategy().build_payload()
- Используются enum классы вместо магических строк
- Исправлен handlers/admin/daily_contests.py:
- prize_days → prize_type/prize_value (соответствие модели БД)
- Обновлены EDITABLE_FIELDS и отображение приза
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Создание попытки сразу при показе вопроса (cipher/emoji/anagram)
- Проверка attempt.answer is not None для блокировки повторного ответа
- Обновление существующей попытки вместо создания новой
- Добавлена функция update_attempt() в CRUD
Изменения:
- ContestTemplate: prize_days заменен на prize_type и prize_value для поддержки разных типов наград (days, balance, custom)
- _award_prize: обновлена логика выдачи призов для всех типов наград
- DEFAULT_TEMPLATES: обновлены для использования prize_type/prize_value
- upsert_template: обновлена сигнатура для новых полей
- _announce_round_start: добавлена локализация и напоминания о конкурсах
- handle_text_answer: исправлена гонка условий с атомарным инкрементом победителей
- Локализация: добавлены ключи CONTEST_START_ANNOUNCEMENT, CONTEST_PRIZE, DAYS, CONTEST_WINNERS, CONTEST_ATTEMPTS, CONTEST_ELIGIBILITY, REMINDER, CONTEST_REMINDER_TEXT в ru.json и en.json
- API схемы: обновлены ContestTemplateResponse и ContestTemplateUpdateRequest
Требуется миграция БД для новых колонок prize_type и prize_value.
- Добавлена защита от спама: rate limiting для попыток (1 попытка/3-5 сек)
- Усилена валидация входных данных: функция _validate_callback_data для безопасного парсинга callback.data
- Перепроверка авторизации: статус подписки проверяется на каждом шаге
- Атомарные операции победителей: использование select with_for_update для предотвращения гонок условий
- Улучшено логирование: добавлены логи попыток и побед для аудита
- Добавлена кнопка 'Назад' в игру 'Блиц' для предотвращения застревания пользователей
- Исправлены отступы и ошибки линтера в _render_blitz
Все изменения направлены на повышение безопасности, стабильности и UX конкурсов.