Основные изменения: ✨ Новые функции: - Система регистрации пользователей с множественными счетами - Автоматическое подтверждение выигрышей через inline-кнопки - Механизм переигровки для неподтвержденных выигрышей (24 часа) - Подтверждение на уровне счетов (каждый счет подтверждается отдельно) - Скрипт полной очистки базы данных 🔧 Технические улучшения: - Исправлена ошибка MissingGreenlet при lazy loading (добавлен joinedload/selectinload) - Добавлено поле claimed_at для отслеживания времени подтверждения - Пакетное добавление счетов с выбором розыгрыша - Проверка владения конкретным счетом при подтверждении 📚 Документация: - docs/AUTO_CONFIRM_SYSTEM.md - Полная документация системы подтверждения - docs/ACCOUNT_BASED_CONFIRMATION.md - Подтверждение на уровне счетов - docs/REGISTRATION_SYSTEM.md - Система регистрации - docs/ADMIN_COMMANDS.md - Команды администратора - docs/CLEAR_DATABASE.md - Очистка БД - docs/QUICK_GUIDE.md - Быстрое начало - docs/UPDATE_LOG.md - Журнал обновлений 🗄️ База данных: - Миграция 003: Таблицы accounts, winner_verifications - Миграция 004: Поле claimed_at в таблице winners - Скрипт scripts/clear_database.py для полной очистки 🎮 Новые команды: Админские: - /check_unclaimed <lottery_id> - Проверка неподтвержденных выигрышей - /redraw <lottery_id> - Повторный розыгрыш - /add_accounts - Пакетное добавление счетов - /list_accounts <telegram_id> - Список счетов пользователя Пользовательские: - /register - Регистрация с вводом данных - /my_account - Просмотр своих счетов - Callback confirm_win_{id} - Подтверждение выигрыша 🛠️ Makefile: - make clear-db - Очистка всех данных из БД (с подтверждением) 🔒 Безопасность: - Проверка владения счетом при подтверждении - Защита от подтверждения чужих счетов - Независимое подтверждение каждого выигрышного счета 📊 Логика работы: 1. Пользователь регистрируется и добавляет счета 2. Счета участвуют в розыгрыше 3. Победители получают уведомление с кнопкой подтверждения 4. Каждый счет подтверждается отдельно (24 часа на подтверждение) 5. Неподтвержденные выигрыши переигрываются через /redraw
15 KiB
Система автоматического подтверждения и повторного розыгрыша
🎯 Обзор системы
Реализована полная система автоматического подтверждения выигрышей с возможностью повторного розыгрыша для неподтвержденных призов.
🔄 Как это работает
1. Победитель получает уведомление
После проведения розыгрыша победителю автоматически отправляется сообщение с интерактивной кнопкой:
🎉 Поздравляем! Ваш счет выиграл!
🎯 Розыгрыш: Новогодний розыгрыш
🏆 Место: 1
🎁 Приз: Главный приз
💳 Счет: 11-22-33-44-55-66-77
⏰ У вас есть 24 часа для подтверждения!
Нажмите кнопку ниже, чтобы подтвердить получение приза.
Если вы не подтвердите в течение 24 часов, приз будет разыгран заново.
[✅ Подтвердить получение приза]
[📞 Связаться с администратором]
2. Победитель подтверждает выигрыш
Пользователь нажимает кнопку "✅ Подтвердить получение приза":
Что происходит:
- В БД устанавливается
is_claimed = True - Сохраняется время подтверждения
claimed_at - Победитель видит подтверждение:
✅ Выигрыш успешно подтвержден!
🎯 Розыгрыш: Новогодний розыгрыш
🏆 Место: 1
🎁 Приз: Главный приз
🎊 Поздравляем! Администратор свяжется с вами
для передачи приза в ближайшее время.
Спасибо за участие!
Администраторы получают уведомление:
✅ Победитель подтвердил получение приза!
🎯 Розыгрыш: Новогодний розыгрыш
🏆 Место: 1
🎁 Приз: Главный приз
👤 Победитель: Иван (@ivan)
🎫 Клубная карта: 2223
📱 Телефон: +7 900 123-45-67
💳 Счет: 11-22-33-44-55-66-77
3. Если победитель не подтверждает (24 часа)
Администратор проверяет неподтвержденные выигрыши:
/check_unclaimed 1
Ответ бота:
⚠️ Неподтвержденные выигрыши в розыгрыше 'Новогодний розыгрыш':
🏆 1 место - Главный приз
👤 Иван (КК: 2223)
💳 11-22-33-44-55-66-77
⏰ Прошло: 26 часов
🏆 3 место - Третий приз
👤 Петр (КК: 3334)
💳 22-33-44-55-66-77-88
⏰ Прошло: 30 часов
📊 Всего неподтвержденных: 2
Используйте /redraw 1 для повторного розыгрыша
4. Повторный розыгрыш
Администратор запускает переигровку:
/redraw 1
Что происходит:
- Система находит неподтвержденные выигрыши (старше 24 часов)
- Получает пул участников (исключая текущих победителей)
- Случайно выбирает новых победителей для каждого неподтвержденного места
- Удаляет старых победителей из БД
- Создает новых победителей
- Отправляет уведомления новым победителям (с кнопкой подтверждения)
Результат для администратора:
🔄 Повторный розыгрыш завершен!
🎯 Розыгрыш: Новогодний розыгрыш
📊 Переиграно мест: 2
🏆 1 место - Главный приз
❌ Было: 11-22-33-44-55-66-77
✅ Стало: 99-88-77-66-55-44-33
🏆 3 место - Третий приз
❌ Было: 22-33-44-55-66-77-88
✅ Стало: 12-34-56-78-90-12-34
📨 Новым победителям отправлены уведомления
Новые победители получают то же уведомление с кнопкой подтверждения и 24-часовым лимитом.
📋 Админские команды
/check_unclaimed <lottery_id>
Проверить неподтвержденные выигрыши старше 24 часов.
Пример:
/check_unclaimed 1
Показывает:
- Список всех неподтвержденных выигрышей
- Информацию о победителях
- Сколько времени прошло с момента уведомления
/redraw <lottery_id>
Переиграть розыгрыш для неподтвержденных выигрышей.
Пример:
/redraw 1
Требования:
- Должны быть неподтвержденные выигрыши старше 24 часов
- Должны быть доступные участники (не победители)
🗄️ Изменения в базе данных
Таблица winners
Добавлено новое поле:
claimed_at(TIMESTAMP) - время подтверждения выигрыша победителем
Миграция
Файл: migrations/versions/004_add_claimed_at.py
Применить:
alembic upgrade head
🔧 Технические детали
Обработчик подтверждения
Файл: main.py
Callback: confirm_win_{winner_id}
Функция: confirm_winner_response()
Логика:
- Проверяет существование выигрыша
- Проверяет, что подтверждает владелец
- Устанавливает
is_claimed = Trueиclaimed_at = now() - Обновляет сообщение победителя
- Уведомляет всех администраторов
Система уведомлений
Функция: notify_winners_async()
Изменения:
- Добавлена кнопка "✅ Подтвердить получение приза"
- Добавлено предупреждение о 24-часовом лимите
- Добавлена кнопка "📞 Связаться с администратором"
Повторный розыгрыш
Файл: src/handlers/redraw_handlers.py
Команды:
check_unclaimed_winners()- проверкаredraw_lottery()- переигровка
Алгоритм:
- Получает всех победителей розыгрыша
- Фильтрует неподтвержденных (is_claimed=False, is_notified=True, >24ч)
- Получает пул участников (исключая победителей)
- Для каждого неподтвержденного:
- Выбирает случайного участника
- Удаляет старого победителя
- Создает нового победителя
- Отправляет уведомление
📊 Состояния выигрыша
Таймлайн жизни выигрыша:
1. Розыгрыш проведен
├─ is_notified: False
├─ is_claimed: False
└─ claimed_at: NULL
2. Уведомление отправлено
├─ is_notified: True
├─ is_claimed: False
└─ claimed_at: NULL
3А. Победитель подтвердил (успех)
├─ is_notified: True
├─ is_claimed: True
└─ claimed_at: 2025-11-16 13:00:00
3Б. Прошло 24 часа (неудача)
├─ is_notified: True
├─ is_claimed: False
├─ claimed_at: NULL
└─ ⏰ time_passed > 24h → переигровка
4. После переигровки (новый победитель)
├─ Старый победитель удален
├─ Создан новый победитель
├─ is_notified: True (после отправки)
├─ is_claimed: False
└─ claimed_at: NULL → снова 24 часа
⚠️ Важные моменты
Безопасность
- Проверка владельца: Только владелец счета может подтвердить выигрыш
- Повторное подтверждение: Если выигрыш уже подтвержден, показывается соответствующее сообщение
- Права администратора: Только админы могут запускать
/redraw
Ограничения
- 24-часовой лимит: Жестко закодирован, но легко изменить в коде
- Пул участников: Если все участники уже победители, переигровка невозможна
- Уникальность: Один счет не может выиграть дважды в одном розыгрыше
Отказоустойчивость
- Уведомления: Если не удается отправить - продолжает работу
- Транзакции: Все изменения в БД атомарны
- Логирование: Все действия записываются в лог
🎯 Типичные сценарии
Сценарий 1: Все подтвердили
1. Розыгрыш → 3 победителя
2. Все 3 нажали кнопку подтверждения
3. Админ: /check_unclaimed 1
→ "✅ Все победители подтвердили выигрыш"
4. Приз передается всем победителям
Сценарий 2: Один не подтвердил
1. Розыгрыш → 3 победителя
2. 2 подтвердили, 1 игнорирует
3. Через 25 часов админ: /check_unclaimed 1
→ "⚠️ 1 неподтвержденный выигрыш"
4. Админ: /redraw 1
5. Система переигрывает 1 место
6. Новый победитель получает уведомление
7. У нового победителя снова 24 часа
Сценарий 3: Множественная переигровка
1. Розыгрыш → 5 победителей
2. 3 подтвердили, 2 игнорируют
3. Через 25 часов: /redraw 1
4. 2 новых победителя выбраны
5. Один из новых тоже игнорирует
6. Через 25 часов: /redraw 1 снова
7. Выбран еще один новый победитель
📈 Статистика и мониторинг
Проверка статуса
/winner_status 1
Покажет:
- ✅ Подтвержденные выигрыши (с is_claimed=True)
- ⏳ Ожидающие подтверждения (с is_claimed=False)
- 📨 Статус уведомления (is_notified)
SQL запросы для админа
Найти все неподтвержденные старше 24 часов:
SELECT w.*, l.title
FROM winners w
JOIN lotteries l ON w.lottery_id = l.id
WHERE w.is_notified = TRUE
AND w.is_claimed = FALSE
AND w.created_at < NOW() - INTERVAL '24 hours';
Статистика по подтверждениям:
SELECT
lottery_id,
COUNT(*) as total_winners,
SUM(CASE WHEN is_claimed THEN 1 ELSE 0 END) as confirmed,
SUM(CASE WHEN NOT is_claimed THEN 1 ELSE 0 END) as unconfirmed
FROM winners
WHERE is_notified = TRUE
GROUP BY lottery_id;
🚀 Использование
Для администратора
- После розыгрыша: Ничего не делать - система отправит уведомления
- Через 24-30 часов: Проверить
/check_unclaimed <id> - Если есть неподтвержденные: Запустить
/redraw <id> - Повторить при необходимости
Для победителя
- Получить уведомление с кнопкой
- Нажать "✅ Подтвердить"
- Дождаться связи с админом
- Получить приз
💡 Рекомендации
Оптимальные настройки
- Лимит подтверждения: 24 часа (можно увеличить до 48ч)
- Частота проверки: 1-2 раза в день
- Уведомления: Включить push-уведомления в боте
Коммуникация с пользователями
После розыгрыша отправьте общее сообщение:
🎉 Розыгрыш завершен!
Если вы выиграли, вам придет сообщение с кнопкой подтверждения.
⏰ У вас будет 24 часа чтобы подтвердить выигрыш!
Если не подтвердите - приз будет переигран.
🔮 Возможные улучшения
- Напоминания: Отправка напоминания за 2 часа до истечения срока
- Гибкий лимит: Разные лимиты для разных типов призов
- История: Логирование всех переигровок
- Статистика: Процент подтверждений, среднее время подтверждения
- Автоматизация: Cron-задача для автоматической переигровки
✅ Преимущества системы
- 🤖 Полная автоматизация: Минимум ручной работы для админа
- ⏱️ Справедливость: Четкий дедлайн для всех
- 🔄 Эффективность: Призы не "зависают" у неактивных победителей
- 📊 Прозрачность: Полная история всех действий
- 🛡️ Безопасность: Только владелец может подтвердить
- 💬 UX: Простая кнопка вместо сложной верификации
📞 Поддержка
Если что-то пошло не так:
- Проверьте логи бота
- Проверьте состояние БД (claimed_at, is_notified, is_claimed)
- Используйте
/winner_status <id>для диагностики - При критических ошибках - используйте
/verify_winnerдля ручного подтверждения