feat: Система автоматического подтверждения выигрышей с поддержкой множественных счетов
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Основные изменения: ✨ Новые функции: - Система регистрации пользователей с множественными счетами - Автоматическое подтверждение выигрышей через 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
This commit is contained in:
279
docs/ACCOUNT_BASED_CONFIRMATION.md
Normal file
279
docs/ACCOUNT_BASED_CONFIRMATION.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# Подтверждение выигрышей по счетам
|
||||
|
||||
## 🎯 Концепция
|
||||
|
||||
Система подтверждения выигрышей работает **на уровне счетов**, а не пользователей.
|
||||
|
||||
### Основные принципы:
|
||||
|
||||
1. **Один пользователь = Много счетов**
|
||||
- У клиента может быть несколько счетов (11-22-33..., 44-55-66..., и т.д.)
|
||||
- Каждый счет участвует в розыгрыше независимо
|
||||
|
||||
2. **Один счет = Один выигрыш = Одно подтверждение**
|
||||
- Если счет `11-22-33-44-55-66-77` выиграл 1 место - требуется подтверждение
|
||||
- Если счет `44-55-66-77-88-99-00` выиграл 3 место - требуется отдельное подтверждение
|
||||
- Даже если оба счета принадлежат одному клиенту
|
||||
|
||||
3. **Независимое подтверждение**
|
||||
- Каждый выигрышный счет подтверждается отдельной кнопкой
|
||||
- Подтверждение одного счета не влияет на другие
|
||||
- У каждого счета свой 24-часовой лимит
|
||||
|
||||
## 📱 Как это работает для пользователя
|
||||
|
||||
### Сценарий: У клиента 3 счета, выиграли 2
|
||||
|
||||
**Счета клиента:**
|
||||
- `11-22-33-44-55-66-77` ✅ Выиграл 1 место (iPhone 15)
|
||||
- `22-33-44-55-66-77-88` ❌ Не выиграл
|
||||
- `33-44-55-66-77-88-99` ✅ Выиграл 3 место (AirPods Pro)
|
||||
|
||||
**Клиент получает 2 сообщения:**
|
||||
|
||||
### Сообщение 1:
|
||||
```
|
||||
🎉 Поздравляем! Ваш счет выиграл!
|
||||
|
||||
🎯 Розыгрыш: Новогодний розыгрыш
|
||||
🏆 Место: 1
|
||||
🎁 Приз: iPhone 15
|
||||
💳 Выигрышный счет: 11-22-33-44-55-66-77
|
||||
|
||||
⏰ У вас есть 24 часа для подтверждения!
|
||||
|
||||
Нажмите кнопку ниже, чтобы подтвердить получение приза по этому счету.
|
||||
Если вы не подтвердите в течение 24 часов, приз будет разыгран заново.
|
||||
|
||||
ℹ️ Если у вас несколько выигрышных счетов, подтвердите каждый из них отдельно.
|
||||
|
||||
[✅ Подтвердить счет 11-22-33-44-55-66-77]
|
||||
[📞 Связаться с администратором]
|
||||
```
|
||||
|
||||
### Сообщение 2:
|
||||
```
|
||||
🎉 Поздравляем! Ваш счет выиграл!
|
||||
|
||||
🎯 Розыгрыш: Новогодний розыгрыш
|
||||
🏆 Место: 3
|
||||
🎁 Приз: AirPods Pro
|
||||
💳 Выигрышный счет: 33-44-55-66-77-88-99
|
||||
|
||||
⏰ У вас есть 24 часа для подтверждения!
|
||||
|
||||
[✅ Подтвердить счет 33-44-55-66-77-88-99]
|
||||
[📞 Связаться с администратором]
|
||||
```
|
||||
|
||||
### Действия клиента:
|
||||
|
||||
1. **Нажимает первую кнопку** → Счет `11-22-33-44-55-66-77` подтвержден ✅
|
||||
2. **Нажимает вторую кнопку** → Счет `33-44-55-66-77-88-99` подтвержден ✅
|
||||
|
||||
## 🔒 Безопасность
|
||||
|
||||
### Проверка владения счетом
|
||||
|
||||
При нажатии кнопки подтверждения система проверяет:
|
||||
|
||||
```python
|
||||
# Получаем владельца КОНКРЕТНОГО счета
|
||||
owner = await AccountService.get_account_owner(session, winner.account_number)
|
||||
|
||||
# Проверяем что текущий пользователь - владелец ЭТОГО счета
|
||||
if not owner or owner.telegram_id != callback.from_user.id:
|
||||
await callback.answer(
|
||||
f"❌ Счет {winner.account_number} вам не принадлежит",
|
||||
show_alert=True
|
||||
)
|
||||
return
|
||||
```
|
||||
|
||||
### Что НЕ может сделать пользователь:
|
||||
|
||||
❌ Подтвердить чужой счет
|
||||
❌ Подтвердить счет, который ему не принадлежит
|
||||
❌ Подтвердить один счет дважды
|
||||
|
||||
### Что может сделать пользователь:
|
||||
|
||||
✅ Подтвердить только свои счета
|
||||
✅ Подтвердить каждый свой выигрышный счет отдельно
|
||||
✅ Видеть номер счета на каждой кнопке
|
||||
|
||||
## 🎊 После подтверждения
|
||||
|
||||
### Сообщение пользователю:
|
||||
|
||||
```
|
||||
✅ Выигрыш успешно подтвержден!
|
||||
|
||||
🎯 Розыгрыш: Новогодний розыгрыш
|
||||
🏆 Место: 1
|
||||
🎁 Приз: iPhone 15
|
||||
💳 Счет: 11-22-33-44-55-66-77
|
||||
|
||||
🎊 Поздравляем! Администратор свяжется с вами
|
||||
для передачи приза в ближайшее время.
|
||||
|
||||
Спасибо за участие!
|
||||
```
|
||||
|
||||
### Уведомление администратору:
|
||||
|
||||
```
|
||||
✅ Победитель подтвердил получение приза!
|
||||
|
||||
🎯 Розыгрыш: Новогодний розыгрыш
|
||||
🏆 Место: 1
|
||||
🎁 Приз: iPhone 15
|
||||
💳 Подтвержденный счет: 11-22-33-44-55-66-77
|
||||
|
||||
👤 Владелец: Иван Петров (@ivan)
|
||||
🎫 Клубная карта: 2223
|
||||
📱 Телефон: +7 900 123-45-67
|
||||
```
|
||||
|
||||
## 📊 База данных
|
||||
|
||||
### Таблица `winners`
|
||||
|
||||
Каждая запись = один выигрышный счет:
|
||||
|
||||
```sql
|
||||
id | lottery_id | account_number | place | prize | is_claimed | claimed_at
|
||||
---|------------|-----------------------|-------|------------|------------|------------------
|
||||
1 | 5 | 11-22-33-44-55-66-77 | 1 | iPhone 15 | TRUE | 2025-11-16 14:00
|
||||
2 | 5 | 33-44-55-66-77-88-99 | 3 | AirPods | TRUE | 2025-11-16 14:05
|
||||
3 | 5 | 55-66-77-88-99-00-11 | 2 | MacBook | FALSE | NULL
|
||||
```
|
||||
|
||||
### Ключевые поля:
|
||||
|
||||
- `account_number` - конкретный выигрышный счет
|
||||
- `is_claimed` - подтвержден ли ЭТОТ счет
|
||||
- `claimed_at` - когда ЭТОТ счет был подтвержден
|
||||
|
||||
## 🔄 Повторный розыгрыш
|
||||
|
||||
Если счет не подтвержден в течение 24 часов:
|
||||
|
||||
1. **Админ проверяет**: `/check_unclaimed 5`
|
||||
```
|
||||
⚠️ Неподтвержденные выигрыши:
|
||||
|
||||
🏆 2 место - MacBook
|
||||
💳 55-66-77-88-99-00-11
|
||||
⏰ Прошло: 26 часов
|
||||
```
|
||||
|
||||
2. **Админ переигрывает**: `/redraw 5`
|
||||
- Удаляется Winner с `account_number = 55-66-77-88-99-00-11`
|
||||
- Выбирается новый случайный счет
|
||||
- Новому владельцу счета отправляется уведомление
|
||||
- Новый владелец получает свои 24 часа
|
||||
|
||||
## 💡 Преимущества подхода
|
||||
|
||||
### ✅ Для пользователей:
|
||||
|
||||
1. **Понятность** - видят конкретный номер счета на кнопке
|
||||
2. **Контроль** - могут подтверждать счета независимо
|
||||
3. **Гибкость** - один счет подтвердил, другой нет (если забыл)
|
||||
|
||||
### ✅ Для администраторов:
|
||||
|
||||
1. **Точность** - знают какой именно счет подтвержден
|
||||
2. **Прозрачность** - видят все действия по каждому счету
|
||||
3. **Справедливость** - переиграть можно конкретный неподтвержденный счет
|
||||
|
||||
### ✅ Для системы:
|
||||
|
||||
1. **Масштабируемость** - неограниченное количество счетов у одного пользователя
|
||||
2. **Независимость** - каждый счет живет своей жизнью
|
||||
3. **Целостность** - нет конфликтов между разными выигрышами
|
||||
|
||||
## 🔍 Примеры использования
|
||||
|
||||
### Пример 1: Один пользователь, два выигрыша
|
||||
|
||||
```
|
||||
Клиент: Иван Петров (КК: 2223)
|
||||
Счета:
|
||||
- 11-22-33-44-55-66-77 → Выиграл 1 место ✅ Подтвержден
|
||||
- 22-33-44-55-66-77-88 → Выиграл 3 место ✅ Подтвержден
|
||||
|
||||
Результат: Иван получит 2 приза
|
||||
```
|
||||
|
||||
### Пример 2: Частичное подтверждение
|
||||
|
||||
```
|
||||
Клиент: Мария Сидорова (КК: 3334)
|
||||
Счета:
|
||||
- 33-44-55-66-77-88-99 → Выиграл 2 место ✅ Подтвержден
|
||||
- 44-55-66-77-88-99-00 → Выиграл 4 место ❌ Не подтвержден (> 24ч)
|
||||
|
||||
Результат:
|
||||
- Мария получит приз за 2 место
|
||||
- 4 место будет переиграно
|
||||
```
|
||||
|
||||
### Пример 3: Полная неявка
|
||||
|
||||
```
|
||||
Клиент: Петр Иванов (КК: 5556)
|
||||
Счета:
|
||||
- 55-66-77-88-99-00-11 → Выиграл 1 место ❌ Не подтвержден
|
||||
- 66-77-88-99-00-11-22 → Выиграл 2 место ❌ Не подтвержден
|
||||
|
||||
Результат: Оба места будут переиграны отдельно
|
||||
```
|
||||
|
||||
## 📝 Технические детали
|
||||
|
||||
### Callback данные
|
||||
|
||||
```python
|
||||
# Формат: confirm_win_{winner_id}
|
||||
callback_data = f"confirm_win_{winner.id}"
|
||||
|
||||
# winner.id - уникальный ID записи в таблице winners
|
||||
# Каждый счет-выигрыш имеет свой winner_id
|
||||
```
|
||||
|
||||
### Проверка при подтверждении
|
||||
|
||||
```python
|
||||
# 1. Получаем winner по ID
|
||||
winner = await session.get(Winner, winner_id)
|
||||
|
||||
# 2. Проверяем что счет принадлежит пользователю
|
||||
owner = await AccountService.get_account_owner(session, winner.account_number)
|
||||
if owner.telegram_id != current_user_id:
|
||||
return "Не ваш счет"
|
||||
|
||||
# 3. Подтверждаем ЭТОТ счет
|
||||
winner.is_claimed = True
|
||||
winner.claimed_at = datetime.now(timezone.utc)
|
||||
await session.commit()
|
||||
```
|
||||
|
||||
## 🎓 Выводы
|
||||
|
||||
Подход "счет = выигрыш" обеспечивает:
|
||||
|
||||
- 🎯 **Точность** - подтверждается конкретный счет, а не абстрактный выигрыш
|
||||
- 🔒 **Безопасность** - только владелец счета может подтвердить
|
||||
- 📊 **Масштабируемость** - неограниченное количество счетов и выигрышей
|
||||
- 👥 **Справедливость** - каждый счет обрабатывается независимо
|
||||
- 💡 **Прозрачность** - всегда понятно какой именно счет подтверждается
|
||||
|
||||
---
|
||||
|
||||
## 📞 См. также
|
||||
|
||||
- `AUTO_CONFIRM_SYSTEM.md` - Полная документация системы подтверждения
|
||||
- `REGISTRATION_SYSTEM.md` - Система регистрации счетов
|
||||
- `ADMIN_GUIDE.md` - Руководство администратора
|
||||
318
docs/ADMIN_COMMANDS.md
Normal file
318
docs/ADMIN_COMMANDS.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# Админские команды - Руководство
|
||||
|
||||
## 🎯 Управление счетами
|
||||
|
||||
### `/add_account` - Добавить счет пользователю
|
||||
|
||||
Привязывает счет к зарегистрированному пользователю по клубной карте.
|
||||
|
||||
**Формат:**
|
||||
```
|
||||
/add_account <club_card> <account_number>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
**Что происходит:**
|
||||
- Система проверяет существование пользователя с указанной клубной картой
|
||||
- Создает новую запись счета в таблице `accounts`
|
||||
- Отправляет уведомление владельцу о добавлении счета
|
||||
- Счет становится активным и может участвовать в розыгрышах
|
||||
|
||||
**Возможные ошибки:**
|
||||
- "Пользователь с клубной картой X не найден" - пользователь не зарегистрирован
|
||||
- "Счет уже существует" - этот номер счета уже привязан к другому пользователю
|
||||
|
||||
---
|
||||
|
||||
### `/remove_account` - Деактивировать счет
|
||||
|
||||
Делает счет неактивным (не удаляет из БД).
|
||||
|
||||
**Формат:**
|
||||
```
|
||||
/remove_account <account_number>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
/remove_account 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
**Что происходит:**
|
||||
- Устанавливает флаг `is_active = False`
|
||||
- Счет остается в БД, но не может участвовать в новых розыгрышах
|
||||
- История участия сохраняется
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Управление выигрышами
|
||||
|
||||
### `/verify_winner` - Подтвердить выигрыш
|
||||
|
||||
Подтверждает выигрыш по коду верификации пользователя.
|
||||
|
||||
**Формат:**
|
||||
```
|
||||
/verify_winner <verification_code> <lottery_id>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
/verify_winner AB12CD34 1
|
||||
```
|
||||
|
||||
**Процесс верификации:**
|
||||
1. Пользователь сообщает администратору свой код верификации
|
||||
2. Администратор проверяет, что пользователь является победителем указанного розыгрыша
|
||||
3. Система устанавливает флаг `is_claimed = True` для выигрыша
|
||||
4. Отправляется уведомление победителю о подтверждении
|
||||
|
||||
**Что происходит:**
|
||||
- Поиск пользователя по коду верификации
|
||||
- Проверка наличия выигрыша в указанном розыгрыше
|
||||
- Установка флага `is_claimed = True`
|
||||
- Отправка подтверждающего сообщения победителю
|
||||
|
||||
**Возможные ошибки:**
|
||||
- "Розыгрыш не найден" - неверный lottery_id
|
||||
- "Выигрыш не найден" - неверный код или пользователь не победитель
|
||||
- "Выигрыш уже был подтвержден" - повторная попытка подтверждения
|
||||
|
||||
---
|
||||
|
||||
### `/winner_status` - Статус победителей
|
||||
|
||||
Показывает всех победителей розыгрыша и их статус подтверждения.
|
||||
|
||||
**Формат:**
|
||||
```
|
||||
/winner_status <lottery_id>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
/winner_status 1
|
||||
```
|
||||
|
||||
**Отображаемая информация:**
|
||||
- 🏆 Место и приз
|
||||
- 👤 Имя и клубная карта победителя
|
||||
- 💳 Номер счета (если участвовал через счет)
|
||||
- ✅ Статус подтверждения (подтвержден / ожидает)
|
||||
- 📨 Статус уведомления (отправлено / нет)
|
||||
|
||||
**Статусы:**
|
||||
- ✅ - Выигрыш подтвержден (`is_claimed = True`)
|
||||
- ⏳ - Ожидает подтверждения (`is_claimed = False`)
|
||||
- 📨 - Уведомление отправлено (`is_notified = True`)
|
||||
- 📭 - Уведомление не отправлено (`is_notified = False`)
|
||||
|
||||
---
|
||||
|
||||
## 👤 Информация о пользователе
|
||||
|
||||
### `/user_info` - Информация о пользователе
|
||||
|
||||
Показывает полную информацию о пользователе по клубной карте.
|
||||
|
||||
**Формат:**
|
||||
```
|
||||
/user_info <club_card>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
/user_info 2223
|
||||
```
|
||||
|
||||
**Отображаемая информация:**
|
||||
- 🎫 Клубная карта
|
||||
- 👤 Имя и Telegram username
|
||||
- 📞 Телефон (если указан)
|
||||
- 🔑 Код верификации
|
||||
- 📅 Дата регистрации
|
||||
- 💳 Список всех счетов (активные и неактивные)
|
||||
- 🏆 История выигрышей
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Автоматические уведомления
|
||||
|
||||
При проведении розыгрыша (`/conduct` через кнопку) система автоматически:
|
||||
|
||||
1. **Определяет владельцев счетов-победителей**
|
||||
- Ищет запись в таблице `accounts`
|
||||
- Находит владельца через `owner_id`
|
||||
|
||||
2. **Создает токен верификации**
|
||||
- Генерирует уникальный токен для каждого выигрыша
|
||||
- Устанавливает срок действия 24 часа
|
||||
- Сохраняет в таблице `winner_verifications`
|
||||
|
||||
3. **Отправляет уведомление победителю**
|
||||
```
|
||||
🎉 Поздравляем! Ваш счет выиграл!
|
||||
|
||||
🎯 Розыгрыш: Название розыгрыша
|
||||
🏆 Место: 1
|
||||
🎁 Приз: Приз первого места
|
||||
💳 Счет: 11-22-33-44-55-66-77
|
||||
|
||||
🔑 Ваш код верификации: AB12CD34
|
||||
|
||||
Для получения приза свяжитесь с администратором
|
||||
и предоставьте этот код.
|
||||
```
|
||||
|
||||
4. **Устанавливает флаг уведомления**
|
||||
- `is_notified = True` в таблице `winners`
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Система верификации
|
||||
|
||||
### Как это работает:
|
||||
|
||||
1. **При регистрации пользователя:**
|
||||
- Генерируется уникальный 8-символьный код (например, `AB12CD34`)
|
||||
- Сохраняется в `users.verification_code`
|
||||
- Пользователь может посмотреть свой код через `/my_code`
|
||||
|
||||
2. **При выигрыше:**
|
||||
- Владельцу счета отправляется сообщение с его кодом верификации
|
||||
- Создается токен в таблице `winner_verifications`
|
||||
|
||||
3. **При подтверждении выигрыша:**
|
||||
- Администратор запрашивает код у победителя
|
||||
- Вводит команду `/verify_winner AB12CD34 1`
|
||||
- Система проверяет соответствие кода и наличие выигрыша
|
||||
- Устанавливает `is_claimed = True`
|
||||
|
||||
### Преимущества:
|
||||
|
||||
- 🔒 **Безопасность**: Только владелец знает свой код
|
||||
- ✅ **Проверка**: Невозможно подтвердить чужой выигрыш
|
||||
- 📊 **Отслеживание**: Полная история подтверждений
|
||||
- ⏱️ **Контроль**: Токены имеют срок действия
|
||||
|
||||
---
|
||||
|
||||
## 📊 Типичные сценарии
|
||||
|
||||
### Сценарий 1: Новый пользователь с двумя счетами
|
||||
|
||||
```
|
||||
1. Пользователь: /start → "Зарегистрироваться"
|
||||
2. Пользователь: Вводит клубную карту "2223"
|
||||
3. Пользователь: Вводит телефон или пропускает
|
||||
4. Система: Показывает код верификации "AB12CD34"
|
||||
|
||||
5. Админ: /add_account 2223 11-22-33-44-55-66-77
|
||||
6. Админ: /add_account 2223 88-99-00-11-22-33-44
|
||||
|
||||
7. Пользователь: /my_accounts
|
||||
→ Видит оба счета
|
||||
```
|
||||
|
||||
### Сценарий 2: Проведение розыгрыша и подтверждение
|
||||
|
||||
```
|
||||
1. Админ: Создает розыгрыш через интерфейс
|
||||
2. Счета участвуют автоматически
|
||||
3. Админ: Нажимает "Провести розыгрыш"
|
||||
|
||||
4. Система: Автоматически отправляет уведомления:
|
||||
"🎉 Поздравляем! Ваш счет выиграл!
|
||||
💳 Счет: 11-22-33-44-55-66-77
|
||||
🔑 Ваш код верификации: AB12CD34"
|
||||
|
||||
5. Победитель: Связывается с админом, называет код "AB12CD34"
|
||||
|
||||
6. Админ: /verify_winner AB12CD34 1
|
||||
7. Система: Подтверждает выигрыш, отправляет уведомление победителю
|
||||
```
|
||||
|
||||
### Сценарий 3: Проверка статуса всех победителей
|
||||
|
||||
```
|
||||
1. Админ: /winner_status 1
|
||||
|
||||
Результат:
|
||||
🏆 Победители розыгрыша 'Новогодний розыгрыш':
|
||||
|
||||
✅ 1 место - Главный приз
|
||||
👤 Иван (КК: 2223)
|
||||
💳 11-22-33-44-55-66-77
|
||||
✅ Подтвержден
|
||||
|
||||
⏳ 2 место - Второй приз
|
||||
👤 Петр (КК: 3334)
|
||||
💳 22-33-44-55-66-77-88
|
||||
⏳ Ожидает подтверждения
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Техническая информация
|
||||
|
||||
### Таблицы базы данных:
|
||||
|
||||
**accounts** - Счета пользователей
|
||||
- `account_number` - Номер счета (формат XX-XX-XX-XX-XX-XX-XX)
|
||||
- `owner_id` - ID владельца (FK → users.id)
|
||||
- `is_active` - Активен ли счет
|
||||
- `created_at` - Дата создания
|
||||
|
||||
**winner_verifications** - Токены верификации выигрышей
|
||||
- `winner_id` - ID выигрыша (FK → winners.id)
|
||||
- `verification_token` - Уникальный токен
|
||||
- `is_verified` - Подтвержден ли
|
||||
- `verified_at` - Время подтверждения
|
||||
- `expires_at` - Срок действия (24 часа)
|
||||
|
||||
**winners** - Победители (расширенная)
|
||||
- Добавлены поля: `is_notified`, `is_claimed`
|
||||
|
||||
**users** - Пользователи (расширенная)
|
||||
- Добавлены поля: `club_card_number`, `phone`, `is_registered`, `verification_code`
|
||||
|
||||
---
|
||||
|
||||
## 📝 Полезные команды для пользователей
|
||||
|
||||
- `/start` - Главное меню / регистрация
|
||||
- `/my_code` - Показать свой код верификации
|
||||
- `/my_accounts` - Список моих счетов
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Важные замечания
|
||||
|
||||
1. **Код верификации** - строго конфиденциальная информация
|
||||
2. **Один счет** = один владелец (нельзя передать счет другому)
|
||||
3. **Деактивация счета** - не удаляет историю участия
|
||||
4. **Токены верификации** - действуют 24 часа
|
||||
5. **Уведомления** - отправляются автоматически только если пользователь зарегистрирован
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Решение проблем
|
||||
|
||||
**Пользователь не получил уведомление о выигрыше:**
|
||||
- Проверить `/winner_status <lottery_id>` - должна быть отметка 📨
|
||||
- Возможно, пользователь заблокировал бота
|
||||
- Проверить telegram_id пользователя через `/user_info`
|
||||
|
||||
**Не получается подтвердить выигрыш:**
|
||||
- Проверить код верификации: `/user_info <club_card>`
|
||||
- Убедиться что lottery_id верный
|
||||
- Проверить что выигрыш еще не подтвержден
|
||||
|
||||
**Счет не добавляется:**
|
||||
- Убедиться что пользователь зарегистрирован
|
||||
- Проверить формат номера счета (7 пар цифр через дефис)
|
||||
- Проверить что счет уникален (не добавлен другому пользователю)
|
||||
439
docs/AUTO_CONFIRM_SYSTEM.md
Normal file
439
docs/AUTO_CONFIRM_SYSTEM.md
Normal file
@@ -0,0 +1,439 @@
|
||||
# Система автоматического подтверждения и повторного розыгрыша
|
||||
|
||||
## 🎯 Обзор системы
|
||||
|
||||
Реализована полная система автоматического подтверждения выигрышей с возможностью повторного розыгрыша для неподтвержденных призов.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Как это работает
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
**Что происходит:**
|
||||
|
||||
1. **Система находит неподтвержденные выигрыши** (старше 24 часов)
|
||||
2. **Получает пул участников** (исключая текущих победителей)
|
||||
3. **Случайно выбирает новых победителей** для каждого неподтвержденного места
|
||||
4. **Удаляет старых победителей** из БД
|
||||
5. **Создает новых победителей**
|
||||
6. **Отправляет уведомления** новым победителям (с кнопкой подтверждения)
|
||||
|
||||
**Результат для администратора:**
|
||||
|
||||
```
|
||||
🔄 Повторный розыгрыш завершен!
|
||||
|
||||
🎯 Розыгрыш: Новогодний розыгрыш
|
||||
📊 Переиграно мест: 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`
|
||||
|
||||
Применить:
|
||||
```bash
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Технические детали
|
||||
|
||||
### Обработчик подтверждения
|
||||
|
||||
**Файл:** `main.py`
|
||||
|
||||
**Callback:** `confirm_win_{winner_id}`
|
||||
|
||||
**Функция:** `confirm_winner_response()`
|
||||
|
||||
**Логика:**
|
||||
1. Проверяет существование выигрыша
|
||||
2. Проверяет, что подтверждает владелец
|
||||
3. Устанавливает `is_claimed = True` и `claimed_at = now()`
|
||||
4. Обновляет сообщение победителя
|
||||
5. Уведомляет всех администраторов
|
||||
|
||||
### Система уведомлений
|
||||
|
||||
**Функция:** `notify_winners_async()`
|
||||
|
||||
**Изменения:**
|
||||
- Добавлена кнопка "✅ Подтвердить получение приза"
|
||||
- Добавлено предупреждение о 24-часовом лимите
|
||||
- Добавлена кнопка "📞 Связаться с администратором"
|
||||
|
||||
### Повторный розыгрыш
|
||||
|
||||
**Файл:** `src/handlers/redraw_handlers.py`
|
||||
|
||||
**Команды:**
|
||||
- `check_unclaimed_winners()` - проверка
|
||||
- `redraw_lottery()` - переигровка
|
||||
|
||||
**Алгоритм:**
|
||||
1. Получает всех победителей розыгрыша
|
||||
2. Фильтрует неподтвержденных (is_claimed=False, is_notified=True, >24ч)
|
||||
3. Получает пул участников (исключая победителей)
|
||||
4. Для каждого неподтвержденного:
|
||||
- Выбирает случайного участника
|
||||
- Удаляет старого победителя
|
||||
- Создает нового победителя
|
||||
- Отправляет уведомление
|
||||
|
||||
---
|
||||
|
||||
## 📊 Состояния выигрыша
|
||||
|
||||
### Таймлайн жизни выигрыша:
|
||||
|
||||
```
|
||||
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 часа
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Важные моменты
|
||||
|
||||
### Безопасность
|
||||
|
||||
1. **Проверка владельца**: Только владелец счета может подтвердить выигрыш
|
||||
2. **Повторное подтверждение**: Если выигрыш уже подтвержден, показывается соответствующее сообщение
|
||||
3. **Права администратора**: Только админы могут запускать `/redraw`
|
||||
|
||||
### Ограничения
|
||||
|
||||
1. **24-часовой лимит**: Жестко закодирован, но легко изменить в коде
|
||||
2. **Пул участников**: Если все участники уже победители, переигровка невозможна
|
||||
3. **Уникальность**: Один счет не может выиграть дважды в одном розыгрыше
|
||||
|
||||
### Отказоустойчивость
|
||||
|
||||
1. **Уведомления**: Если не удается отправить - продолжает работу
|
||||
2. **Транзакции**: Все изменения в БД атомарны
|
||||
3. **Логирование**: Все действия записываются в лог
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Типичные сценарии
|
||||
|
||||
### Сценарий 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 часов:**
|
||||
|
||||
```sql
|
||||
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';
|
||||
```
|
||||
|
||||
**Статистика по подтверждениям:**
|
||||
|
||||
```sql
|
||||
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;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Использование
|
||||
|
||||
### Для администратора
|
||||
|
||||
1. **После розыгрыша**: Ничего не делать - система отправит уведомления
|
||||
2. **Через 24-30 часов**: Проверить `/check_unclaimed <id>`
|
||||
3. **Если есть неподтвержденные**: Запустить `/redraw <id>`
|
||||
4. **Повторить** при необходимости
|
||||
|
||||
### Для победителя
|
||||
|
||||
1. **Получить уведомление** с кнопкой
|
||||
2. **Нажать "✅ Подтвердить"**
|
||||
3. **Дождаться связи с админом**
|
||||
4. **Получить приз**
|
||||
|
||||
---
|
||||
|
||||
## 💡 Рекомендации
|
||||
|
||||
### Оптимальные настройки
|
||||
|
||||
- **Лимит подтверждения**: 24 часа (можно увеличить до 48ч)
|
||||
- **Частота проверки**: 1-2 раза в день
|
||||
- **Уведомления**: Включить push-уведомления в боте
|
||||
|
||||
### Коммуникация с пользователями
|
||||
|
||||
После розыгрыша отправьте общее сообщение:
|
||||
|
||||
```
|
||||
🎉 Розыгрыш завершен!
|
||||
|
||||
Если вы выиграли, вам придет сообщение с кнопкой подтверждения.
|
||||
|
||||
⏰ У вас будет 24 часа чтобы подтвердить выигрыш!
|
||||
|
||||
Если не подтвердите - приз будет переигран.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Возможные улучшения
|
||||
|
||||
1. **Напоминания**: Отправка напоминания за 2 часа до истечения срока
|
||||
2. **Гибкий лимит**: Разные лимиты для разных типов призов
|
||||
3. **История**: Логирование всех переигровок
|
||||
4. **Статистика**: Процент подтверждений, среднее время подтверждения
|
||||
5. **Автоматизация**: Cron-задача для автоматической переигровки
|
||||
|
||||
---
|
||||
|
||||
## ✅ Преимущества системы
|
||||
|
||||
- 🤖 **Полная автоматизация**: Минимум ручной работы для админа
|
||||
- ⏱️ **Справедливость**: Четкий дедлайн для всех
|
||||
- 🔄 **Эффективность**: Призы не "зависают" у неактивных победителей
|
||||
- 📊 **Прозрачность**: Полная история всех действий
|
||||
- 🛡️ **Безопасность**: Только владелец может подтвердить
|
||||
- 💬 **UX**: Простая кнопка вместо сложной верификации
|
||||
|
||||
---
|
||||
|
||||
## 📞 Поддержка
|
||||
|
||||
Если что-то пошло не так:
|
||||
|
||||
1. Проверьте логи бота
|
||||
2. Проверьте состояние БД (claimed_at, is_notified, is_claimed)
|
||||
3. Используйте `/winner_status <id>` для диагностики
|
||||
4. При критических ошибках - используйте `/verify_winner` для ручного подтверждения
|
||||
72
docs/CLEAR_DATABASE.md
Normal file
72
docs/CLEAR_DATABASE.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Очистка базы данных - Краткое руководство
|
||||
|
||||
## 🎯 Быстрый старт
|
||||
|
||||
```bash
|
||||
make clear-db
|
||||
```
|
||||
|
||||
Система попросит подтверждение, введите `yes`.
|
||||
|
||||
## ✅ Результат
|
||||
|
||||
База данных будет полностью очищена:
|
||||
- ✅ Удалены все пользователи
|
||||
- ✅ Удалены все розыгрыши
|
||||
- ✅ Удалены все счета
|
||||
- ✅ Удалены все участия
|
||||
- ✅ Удалены все победители
|
||||
- ✅ Сброшены счетчики ID (начнутся с 1)
|
||||
|
||||
## 📊 Статистика очистки
|
||||
|
||||
Скрипт покажет сколько строк удалено из каждой таблицы:
|
||||
|
||||
```
|
||||
✅ winner_verifications - удалено 0 строк
|
||||
✅ winners - удалено 2 строк
|
||||
✅ participations - удалено 1 строк
|
||||
✅ accounts - удалено 2 строк
|
||||
✅ lotteries - удалено 1 строк
|
||||
✅ users - удалено 2 строк
|
||||
```
|
||||
|
||||
## ⚠️ ВНИМАНИЕ
|
||||
|
||||
**Данные удаляются БЕЗ ВОЗМОЖНОСТИ ВОССТАНОВЛЕНИЯ!**
|
||||
|
||||
Перед запуском на production всегда делайте бэкап:
|
||||
|
||||
```bash
|
||||
pg_dump -h 192.168.0.102 -U bot_user -d bot_db > backup.sql
|
||||
```
|
||||
|
||||
## 🔧 Альтернативные способы
|
||||
|
||||
### Через Python напрямую
|
||||
|
||||
```bash
|
||||
source .venv/bin/activate
|
||||
python scripts/clear_database.py
|
||||
```
|
||||
|
||||
### Через SQL (только данные, без сброса ID)
|
||||
|
||||
```sql
|
||||
DELETE FROM winner_verifications;
|
||||
DELETE FROM winners;
|
||||
DELETE FROM participations;
|
||||
DELETE FROM accounts;
|
||||
DELETE FROM lotteries;
|
||||
DELETE FROM users;
|
||||
```
|
||||
|
||||
## 📖 Подробная документация
|
||||
|
||||
См. `scripts/README_CLEAR_DB.md` для полной документации.
|
||||
|
||||
## 🆘 Восстановление из бэкапа
|
||||
|
||||
```bash
|
||||
psql -h 192.168.0.102 -U bot_user -d bot_db < backup.sql
|
||||
```
|
||||
152
docs/QUICK_GUIDE.md
Normal file
152
docs/QUICK_GUIDE.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Быстрая шпаргалка - Команды администратора
|
||||
|
||||
## 🚀 Основные команды
|
||||
|
||||
### Добавление счетов
|
||||
|
||||
**Один счет (быстро):**
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
**Несколько счетов (пакетом):**
|
||||
```
|
||||
/add_account
|
||||
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 88-99-00-11-22-33-44
|
||||
3334 12-34-56-78-90-12-34
|
||||
```
|
||||
|
||||
### Управление счетами
|
||||
|
||||
```
|
||||
/remove_account 11-22-33-44-55-66-77 # Деактивировать
|
||||
/user_info 2223 # Информация о пользователе
|
||||
```
|
||||
|
||||
### Работа с розыгрышами
|
||||
|
||||
```
|
||||
/winner_status 1 # Статус победителей
|
||||
/verify_winner AB12CD34 1 # Подтвердить выигрыш
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Типичные сценарии
|
||||
|
||||
### Новый клиент (полный цикл)
|
||||
|
||||
1. Клиент регистрируется: `/start` → "Зарегистрироваться"
|
||||
2. Админ добавляет счета:
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
3. Выбрать розыгрыш из списка
|
||||
4. Готово!
|
||||
|
||||
### Массовое добавление (10+ счетов)
|
||||
|
||||
```
|
||||
/add_account
|
||||
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 22-33-44-55-66-77-88
|
||||
3334 33-44-55-66-77-88-99
|
||||
3334 44-55-66-77-88-99-00
|
||||
5556 55-66-77-88-99-00-11
|
||||
```
|
||||
|
||||
→ Выбрать розыгрыш → Готово!
|
||||
|
||||
### Проведение розыгрыша
|
||||
|
||||
1. В боте: "Розыгрыши" → Выбрать → "Провести розыгрыш"
|
||||
2. Победители получат уведомления автоматически
|
||||
3. Проверить: `/winner_status 1`
|
||||
|
||||
### Подтверждение победителя
|
||||
|
||||
1. Победитель сообщает код: `AB12CD34`
|
||||
2. Админ: `/verify_winner AB12CD34 1`
|
||||
3. Система подтверждает и уведомляет победителя
|
||||
|
||||
---
|
||||
|
||||
## 💡 Полезные советы
|
||||
|
||||
- **Формат счета:** `XX-XX-XX-XX-XX-XX-XX` (7 пар цифр)
|
||||
- **Клубная карта:** Любые цифры (например: 2223, 5556)
|
||||
- **Код верификации:** Генерируется автоматически при регистрации
|
||||
- **Отмена операции:** `/cancel` во время ввода данных
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Частые ошибки
|
||||
|
||||
| Ошибка | Причина | Решение |
|
||||
|--------|---------|---------|
|
||||
| "Пользователь не найден" | Клубная карта не зарегистрирована | Попросить зарегистрироваться через /start |
|
||||
| "Счет уже существует" | Номер занят другим пользователем | Проверить номер или деактивировать старый |
|
||||
| "Неверный формат" | Формат счета неправильный | Использовать XX-XX-XX-XX-XX-XX-XX |
|
||||
| Нет розыгрышей | Нет активных розыгрышей | Создать розыгрыш через админ-панель |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Проверка данных
|
||||
|
||||
### Проверить пользователя:
|
||||
```
|
||||
/user_info 2223
|
||||
```
|
||||
|
||||
Увидите:
|
||||
- Все счета пользователя
|
||||
- Код верификации
|
||||
- Историю выигрышей
|
||||
|
||||
### Проверить победителей:
|
||||
```
|
||||
/winner_status 1
|
||||
```
|
||||
|
||||
Увидите:
|
||||
- Список всех победителей
|
||||
- Статус подтверждения (✅/⏳)
|
||||
- Информацию о владельцах
|
||||
|
||||
---
|
||||
|
||||
## 📞 Пользовательские команды
|
||||
|
||||
Клиенты используют:
|
||||
- `/start` - Главное меню / регистрация
|
||||
- `/my_code` - Показать код верификации
|
||||
- `/my_accounts` - Список счетов
|
||||
- "Мой счет" (через меню) - Подробная информация
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Быстрый старт (за 1 минуту)
|
||||
|
||||
```bash
|
||||
# 1. Клиент регистрируется
|
||||
Клиент → /start → "Зарегистрироваться" → Вводит данные
|
||||
|
||||
# 2. Админ добавляет счета
|
||||
/add_account
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 88-99-00-11-22-33-44
|
||||
|
||||
# 3. Выбрать розыгрыш
|
||||
Нажать "🎯 Новогодний розыгрыш"
|
||||
|
||||
# 4. Провести розыгрыш
|
||||
"Розыгрыши" → Выбрать → "Провести"
|
||||
|
||||
# 5. Подтвердить победителя
|
||||
/verify_winner AB12CD34 1
|
||||
|
||||
✅ Готово!
|
||||
```
|
||||
261
docs/REGISTRATION_SYSTEM.md
Normal file
261
docs/REGISTRATION_SYSTEM.md
Normal file
@@ -0,0 +1,261 @@
|
||||
# Система регистрации и верификации выигрышей
|
||||
|
||||
## Архитектура
|
||||
|
||||
### Модели данных
|
||||
|
||||
#### 1. User (Расширенная)
|
||||
- `club_card_number` - номер клубной карты (уникальный идентификатор клиента)
|
||||
- `phone` - телефон для связи
|
||||
- `is_registered` - прошел ли полную регистрацию
|
||||
- `verification_code` - секретный код для подтверждения выигрыша (генерируется автоматически)
|
||||
|
||||
#### 2. Account (Новая)
|
||||
- `account_number` - номер счета в формате XX-XX-XX-XX-XX-XX-XX
|
||||
- `owner_id` - владелец счета (связь с User через club_card_number)
|
||||
- `is_active` - активен ли счет
|
||||
|
||||
#### 3. WinnerVerification (Новая)
|
||||
- `winner_id` - связь с Winner
|
||||
- `verification_token` - токен для подтверждения выигрыша
|
||||
- `is_verified` - подтвержден ли выигрыш
|
||||
- `expires_at` - срок действия токена (24 часа)
|
||||
|
||||
## Процессы
|
||||
|
||||
### 1. Регистрация пользователя
|
||||
|
||||
**Инициатор:** Обычный пользователь через бота
|
||||
|
||||
**Шаги:**
|
||||
1. Пользователь отправляет `/start`
|
||||
2. Бот проверяет `is_registered`
|
||||
3. Если `False` - запрашивает:
|
||||
- Номер клубной карты
|
||||
- Телефон (опционально)
|
||||
4. Генерируется `verification_code` (8-символьный уникальный код)
|
||||
5. Код показывается пользователю: "Ваш код верификации: **AB12CD34**. Сохраните его!"
|
||||
6. `is_registered = True`
|
||||
|
||||
### 2. Создание счета администратором
|
||||
|
||||
**Инициатор:** Администратор
|
||||
|
||||
**Формат команды:**
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
**Процесс:**
|
||||
1. Админ отправляет команду с номером КК и счетом
|
||||
2. Бот находит пользователя по `club_card_number = 2223`
|
||||
3. Создается запись в таблице `accounts`:
|
||||
```python
|
||||
Account(
|
||||
account_number="11-22-33-44-55-66-77",
|
||||
owner_id=user.id,
|
||||
is_active=True
|
||||
)
|
||||
```
|
||||
4. Пользователю отправляется уведомление:
|
||||
```
|
||||
✅ К вашему профилю добавлен счет:
|
||||
11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
### 3. Проведение розыгрыша с уведомлением победителей
|
||||
|
||||
**Процесс:**
|
||||
1. Администратор проводит розыгрыш
|
||||
2. Выбирается случайный счет (например, `11-22-33-44-55-66-77`)
|
||||
3. Система ищет владельца счета:
|
||||
```python
|
||||
account = Account.query.filter_by(account_number="11-22-33-44-55-66-77").first()
|
||||
user = account.owner if account else None
|
||||
```
|
||||
4. Создается запись `Winner` и `WinnerVerification`:
|
||||
```python
|
||||
winner = Winner(
|
||||
lottery_id=lottery.id,
|
||||
user_id=user.id if user else None,
|
||||
account_number="11-22-33-44-55-66-77",
|
||||
place=1,
|
||||
prize="iPhone 15"
|
||||
)
|
||||
|
||||
verification = WinnerVerification(
|
||||
winner_id=winner.id,
|
||||
verification_token=generate_token(),
|
||||
expires_at=now + 24hours
|
||||
)
|
||||
```
|
||||
|
||||
5. Если `user` найден - отправляется личное сообщение:
|
||||
```
|
||||
🎉 ПОЗДРАВЛЯЕМ!
|
||||
|
||||
Вы выиграли 1 место в розыгрыше "Новогодний розыгрыш"!
|
||||
🏆 Приз: iPhone 15
|
||||
|
||||
📋 Ваш выигрышный счет: 11-22-33-44-55-66-77
|
||||
|
||||
✅ Для подтверждения выигрыша:
|
||||
1. Свяжитесь с администратором @admin_username
|
||||
2. Сообщите ваш код верификации: AB12CD34
|
||||
3. Администратор подтвердит ваш выигрыш в системе
|
||||
|
||||
⏰ Срок подтверждения: 24 часа
|
||||
```
|
||||
|
||||
### 4. Верификация выигрыша администратором
|
||||
|
||||
**Сценарий:**
|
||||
1. Победитель связывается с админом в личных сообщениях
|
||||
2. Сообщает код верификации: `AB12CD34`
|
||||
3. Админ проверяет код в боте:
|
||||
```
|
||||
/verify_winner AB12CD34 1
|
||||
```
|
||||
где `1` - ID розыгрыша
|
||||
|
||||
4. Система:
|
||||
- Находит пользователя по `verification_code = "AB12CD34"`
|
||||
- Проверяет, что у него есть выигрыш в розыгрыше #1
|
||||
- Помечает `winner.is_claimed = True`
|
||||
- Обновляет `verification.is_verified = True`
|
||||
|
||||
5. Победителю отправляется:
|
||||
```
|
||||
✅ Ваш выигрыш подтвержден!
|
||||
|
||||
Администратор свяжется с вами для получения приза.
|
||||
```
|
||||
|
||||
## Дополнительные механизмы безопасности
|
||||
|
||||
### 1. Двухфакторная верификация (опционально)
|
||||
Можно добавить отправку одноразового кода на телефон победителя.
|
||||
|
||||
### 2. Ограничение по времени
|
||||
Токены верификации действуют 24 часа. После истечения срока требуется повторная генерация.
|
||||
|
||||
### 3. Логирование
|
||||
Все действия с выигрышами логируются:
|
||||
- Создание выигрыша
|
||||
- Отправка уведомления
|
||||
- Подтверждение администратором
|
||||
- Получение приза
|
||||
|
||||
## API для админа
|
||||
|
||||
### Команды бота
|
||||
|
||||
#### `/add_account <club_card> <account_number>`
|
||||
Добавить счет к профилю клиента
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
#### `/remove_account <account_number>`
|
||||
Деактивировать счет
|
||||
```
|
||||
/remove_account 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
#### `/verify_winner <verification_code> <lottery_id>`
|
||||
Подтвердить выигрыш победителя
|
||||
```
|
||||
/verify_winner AB12CD34 1
|
||||
```
|
||||
|
||||
#### `/winner_status <lottery_id>`
|
||||
Показать статус всех победителей розыгрыша
|
||||
```
|
||||
/winner_status 1
|
||||
|
||||
Результаты:
|
||||
1 место - @username (КК: 2223) ✅ Подтвержден
|
||||
2 место - Счет: 33-44-55-66-77-88-99 ⏳ Ожидает подтверждения
|
||||
3 место - @user2 (КК: 4445) ❌ Не подтвержден (истек срок)
|
||||
```
|
||||
|
||||
## Аналитика и отчеты
|
||||
|
||||
### Запросы для аналитики
|
||||
|
||||
```sql
|
||||
-- Победители по клубным картам
|
||||
SELECT
|
||||
u.club_card_number,
|
||||
u.first_name,
|
||||
COUNT(w.id) as total_wins,
|
||||
SUM(CASE WHEN w.is_claimed THEN 1 ELSE 0 END) as claimed_wins
|
||||
FROM users u
|
||||
JOIN winners w ON w.user_id = u.id
|
||||
GROUP BY u.id;
|
||||
|
||||
-- Счета с наибольшим количеством участий
|
||||
SELECT
|
||||
a.account_number,
|
||||
u.club_card_number,
|
||||
COUNT(p.id) as participation_count
|
||||
FROM accounts a
|
||||
JOIN users u ON u.id = a.owner_id
|
||||
JOIN participations p ON p.account_id = a.id
|
||||
GROUP BY a.id, u.id
|
||||
ORDER BY participation_count DESC;
|
||||
|
||||
-- Невостребованные выигрыши
|
||||
SELECT
|
||||
l.title,
|
||||
w.place,
|
||||
w.prize,
|
||||
w.account_number,
|
||||
u.club_card_number
|
||||
FROM winners w
|
||||
JOIN lotteries l ON l.id = w.lottery_id
|
||||
LEFT JOIN users u ON u.id = w.user_id
|
||||
WHERE w.is_claimed = false
|
||||
AND w.created_at < NOW() - INTERVAL '24 hours';
|
||||
```
|
||||
|
||||
## Миграция существующих данных
|
||||
|
||||
Если у вас уже есть данные в старой схеме:
|
||||
|
||||
```python
|
||||
# Миграция старых account_number из users в таблицу accounts
|
||||
async def migrate_accounts():
|
||||
users = await session.execute(select(User).where(User.account_number != None))
|
||||
for user in users.scalars():
|
||||
account = Account(
|
||||
account_number=user.account_number,
|
||||
owner_id=user.id,
|
||||
is_active=True
|
||||
)
|
||||
session.add(account)
|
||||
user.account_number = None # Очищаем старое поле
|
||||
await session.commit()
|
||||
```
|
||||
|
||||
## Тестирование
|
||||
|
||||
### Сценарий 1: Полный цикл выигрыша
|
||||
|
||||
1. Регистрация пользователя (КК: 2223)
|
||||
2. Админ добавляет счет: `/add_account 2223 11-22-33-44-55-66-77`
|
||||
3. Счет участвует в розыгрыше
|
||||
4. Счет выигрывает 1 место
|
||||
5. Пользователю приходит уведомление с кодом
|
||||
6. Пользователь связывается с админом, сообщает код
|
||||
7. Админ подтверждает: `/verify_winner AB12CD34 1`
|
||||
8. Выигрыш получен ✅
|
||||
|
||||
### Сценарий 2: Выигрыш незарегистрированного счета
|
||||
|
||||
1. Админ добавляет счет без владельца
|
||||
2. Счет участвует и выигрывает
|
||||
3. Бот показывает в публичном объявлении: "Счет 11-22-33-44-55-66-77 выиграл!"
|
||||
4. Владелец счета регистрируется в боте
|
||||
5. Админ привязывает счет к владельцу
|
||||
6. Дальше стандартная процедура верификации
|
||||
424
docs/UPDATE_LOG.md
Normal file
424
docs/UPDATE_LOG.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# Обновления системы - 16.11.2025
|
||||
|
||||
## ✅ Исправленные ошибки
|
||||
|
||||
### 1. Ошибка "User object has no attribute 'account_number'"
|
||||
**Проблема:** В старой системе поле `account_number` было в таблице `users`, но после миграции оно перенесено в отдельную таблицу `accounts`.
|
||||
|
||||
**Решение:**
|
||||
- Обновлена функция `show_my_account()` в `main.py`
|
||||
- Теперь использует `AccountService.get_user_accounts()` для получения всех счетов пользователя
|
||||
- Показывает список всех счетов с их статусом (активен/неактивен)
|
||||
|
||||
**Новый функционал в "Мой счет":**
|
||||
```
|
||||
💳 Ваши счета
|
||||
|
||||
🎫 Клубная карта: 2223
|
||||
🔑 Код верификации: AB12CD34
|
||||
|
||||
Счета (2):
|
||||
|
||||
1. 11-22-33-44-55-66-77
|
||||
✅ Активен
|
||||
|
||||
2. 88-99-00-11-22-33-44
|
||||
✅ Активен
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆕 Новый функционал
|
||||
|
||||
### 1. Улучшенная команда `/add_account`
|
||||
|
||||
#### Режим 1: Быстрое добавление одного счета
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
#### Режим 2: Интерактивное добавление (один или несколько)
|
||||
```
|
||||
/add_account
|
||||
```
|
||||
|
||||
Затем отправьте данные:
|
||||
|
||||
**Один счет:**
|
||||
```
|
||||
2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
**Несколько счетов (пакетное добавление):**
|
||||
```
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 88-99-00-11-22-33-44
|
||||
3334 12-34-56-78-90-12-34
|
||||
5556 99-88-77-66-55-44-33
|
||||
```
|
||||
|
||||
**Формат:** `клубная_карта номер_счета` (через пробел, каждый счет с новой строки)
|
||||
|
||||
---
|
||||
|
||||
### 2. Автоматическое добавление счетов в розыгрыш
|
||||
|
||||
После успешного добавления счетов система **автоматически предлагает** добавить их в активный розыгрыш:
|
||||
|
||||
```
|
||||
✅ Счет успешно добавлен!
|
||||
|
||||
🎫 Клубная карта: 2223
|
||||
💳 Счет: 11-22-33-44-55-66-77
|
||||
👤 Владелец: Иван
|
||||
|
||||
📨 Владельцу отправлено уведомление
|
||||
|
||||
➕ Добавить счета в розыгрыш?
|
||||
|
||||
Выберите розыгрыш из списка:
|
||||
[🎯 Новогодний розыгрыш]
|
||||
[🎯 Летний розыгрыш]
|
||||
[❌ Пропустить]
|
||||
```
|
||||
|
||||
**Процесс:**
|
||||
1. Администратор добавляет счета командой `/add_account`
|
||||
2. Система показывает список активных розыгрышей
|
||||
3. Администратор выбирает розыгрыш или пропускает
|
||||
4. Счета автоматически добавляются в выбранный розыгрыш
|
||||
|
||||
**Преимущества:**
|
||||
- ✅ Экономия времени - не нужно вручную добавлять каждый счет
|
||||
- ✅ Меньше ошибок - система проверяет дубликаты
|
||||
- ✅ Удобство - всё в одном процессе
|
||||
- ✅ Гибкость - можно пропустить добавление
|
||||
|
||||
---
|
||||
|
||||
### 3. Пакетное добавление счетов
|
||||
|
||||
**Сценарий использования:**
|
||||
У вас есть список новых клиентов с их счетами. Вместо добавления каждого по отдельности:
|
||||
|
||||
```
|
||||
/add_account
|
||||
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 88-99-00-11-22-33-44
|
||||
3334 12-34-56-78-90-12-34
|
||||
3334 99-88-77-66-55-44-33
|
||||
5556 11-11-11-11-11-11-11
|
||||
```
|
||||
|
||||
**Результат:**
|
||||
```
|
||||
📊 Результаты добавления счетов
|
||||
|
||||
✅ Успешно добавлено: 5
|
||||
|
||||
• 2223 → 11-22-33-44-55-66-77
|
||||
👤 Иван
|
||||
• 2223 → 88-99-00-11-22-33-44
|
||||
👤 Иван
|
||||
• 3334 → 12-34-56-78-90-12-34
|
||||
👤 Петр
|
||||
• 3334 → 99-88-77-66-55-44-33
|
||||
👤 Петр
|
||||
• 5556 → 11-11-11-11-11-11-11
|
||||
👤 Мария
|
||||
|
||||
➕ Добавить счета в розыгрыш?
|
||||
```
|
||||
|
||||
**Обработка ошибок:**
|
||||
Если какие-то счета невалидны, система покажет:
|
||||
```
|
||||
❌ Ошибки: 2
|
||||
|
||||
• Строка 3 (9999 123-456): Пользователь с клубной картой 9999 не найден
|
||||
• Строка 5 (2223 11-22-33): Неверный формат номера счета
|
||||
```
|
||||
|
||||
Остальные счета будут добавлены успешно.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Обновленный процесс работы
|
||||
|
||||
### Полный цикл: Регистрация → Счета → Розыгрыш
|
||||
|
||||
**Шаг 1: Клиент регистрируется**
|
||||
```
|
||||
Клиент: /start
|
||||
Клиент: Нажимает "Зарегистрироваться"
|
||||
Клиент: Вводит клубную карту "2223"
|
||||
Клиент: Вводит телефон или пропускает
|
||||
Система: Показывает код верификации "AB12CD34"
|
||||
```
|
||||
|
||||
**Шаг 2: Администратор добавляет счета**
|
||||
```
|
||||
Админ: /add_account
|
||||
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 88-99-00-11-22-33-44
|
||||
|
||||
Система: Добавляет оба счета
|
||||
Система: Отправляет уведомления владельцу
|
||||
Система: Предлагает добавить в розыгрыш
|
||||
```
|
||||
|
||||
**Шаг 3: Администратор выбирает розыгрыш**
|
||||
```
|
||||
Админ: Нажимает "🎯 Новогодний розыгрыш"
|
||||
|
||||
Система: Добавляет оба счета в розыгрыш
|
||||
Система: Показывает результат:
|
||||
✅ Добавлено счетов: 2
|
||||
```
|
||||
|
||||
**Шаг 4: Клиент проверяет свои счета**
|
||||
```
|
||||
Клиент: /start → "Мой счет"
|
||||
|
||||
Видит:
|
||||
💳 Ваши счета
|
||||
🎫 Клубная карта: 2223
|
||||
🔑 Код верификации: AB12CD34
|
||||
|
||||
Счета (2):
|
||||
1. 11-22-33-44-55-66-77 ✅ Активен
|
||||
2. 88-99-00-11-22-33-44 ✅ Активен
|
||||
```
|
||||
|
||||
**Шаг 5: Проведение розыгрыша**
|
||||
```
|
||||
Админ: Нажимает "Провести розыгрыш"
|
||||
|
||||
Система: Выбирает победителей
|
||||
Система: Находит владельцев счетов-победителей
|
||||
Система: Отправляет уведомления с кодами верификации
|
||||
```
|
||||
|
||||
**Шаг 6: Подтверждение выигрыша**
|
||||
```
|
||||
Победитель: Связывается с админом, называет код "AB12CD34"
|
||||
|
||||
Админ: /verify_winner AB12CD34 1
|
||||
|
||||
Система: Подтверждает выигрыш
|
||||
Система: Отправляет уведомление победителю
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Примеры использования
|
||||
|
||||
### Пример 1: Добавление счетов для одного пользователя
|
||||
```
|
||||
/add_account
|
||||
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 22-33-44-55-66-77-88
|
||||
2223 33-44-55-66-77-88-99
|
||||
```
|
||||
|
||||
Результат: Все 3 счета добавлены пользователю с клубной картой 2223
|
||||
|
||||
### Пример 2: Добавление счетов для разных пользователей
|
||||
```
|
||||
/add_account
|
||||
|
||||
2223 11-22-33-44-55-66-77
|
||||
3334 22-33-44-55-66-77-88
|
||||
5556 33-44-55-66-77-88-99
|
||||
7778 44-55-66-77-88-99-00
|
||||
```
|
||||
|
||||
Результат: Каждый счет добавлен соответствующему пользователю
|
||||
|
||||
### Пример 3: Быстрое добавление с немедленным участием
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
[Выбрать розыгрыш]
|
||||
[Нажать "🎯 Новогодний розыгрыш"]
|
||||
```
|
||||
|
||||
Результат: Счет добавлен и сразу участвует в розыгрыше
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Технические детали
|
||||
|
||||
### Новая FSM структура в admin_account_handlers.py
|
||||
|
||||
```python
|
||||
class AddAccountStates(StatesGroup):
|
||||
waiting_for_data = State() # Ожидание данных счетов
|
||||
choosing_lottery = State() # Выбор розыгрыша
|
||||
```
|
||||
|
||||
### Новые callback handlers
|
||||
|
||||
- `add_to_lottery_{lottery_id}` - Добавить счета в розыгрыш
|
||||
- `skip_lottery_add` - Пропустить добавление в розыгрыш
|
||||
|
||||
### Обновленные функции
|
||||
|
||||
1. **add_account_command()** - Точка входа, поддерживает оба режима
|
||||
2. **process_single_account()** - Обработка одного счета из команды
|
||||
3. **process_accounts_data()** - Обработка пакета счетов
|
||||
4. **show_lottery_selection()** - Показать выбор розыгрыша
|
||||
5. **add_accounts_to_lottery()** - Добавить счета в выбранный розыгрыш
|
||||
|
||||
### Проверки безопасности
|
||||
|
||||
- ✅ Проверка существования пользователя по клубной карте
|
||||
- ✅ Проверка уникальности номера счета
|
||||
- ✅ Проверка формата номера (XX-XX-XX-XX-XX-XX-XX)
|
||||
- ✅ Проверка дубликатов при добавлении в розыгрыш
|
||||
- ✅ Проверка прав администратора
|
||||
|
||||
---
|
||||
|
||||
## 📊 Сравнение: До и После
|
||||
|
||||
### Старый процесс (до обновления):
|
||||
```
|
||||
1. /add_account 2223 11-22-33-44-55-66-77
|
||||
2. [Ждем подтверждения]
|
||||
3. Вручную находим розыгрыш
|
||||
4. Вручную добавляем счет в розыгрыш
|
||||
5. Повторяем для каждого счета
|
||||
```
|
||||
|
||||
**Время на 10 счетов:** ~5-7 минут
|
||||
|
||||
### Новый процесс (после обновления):
|
||||
```
|
||||
1. /add_account
|
||||
2. Вставляем 10 строк с данными
|
||||
3. Выбираем розыгрыш из списка
|
||||
4. Готово!
|
||||
```
|
||||
|
||||
**Время на 10 счетов:** ~30 секунд
|
||||
|
||||
**Экономия времени: 90%!**
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Отладка и решение проблем
|
||||
|
||||
### Проблема: Не показываются розыгрыши после добавления счетов
|
||||
|
||||
**Причина:** Нет активных розыгрышей
|
||||
|
||||
**Решение:** Создайте активный розыгрыш через админ-панель
|
||||
|
||||
### Проблема: Ошибка "Пользователь не найден"
|
||||
|
||||
**Причина:** Клубная карта не зарегистрирована
|
||||
|
||||
**Решение:**
|
||||
1. Попросите пользователя зарегистрироваться через /start
|
||||
2. Или проверьте правильность клубной карты через /user_info
|
||||
|
||||
### Проблема: "Счет уже существует"
|
||||
|
||||
**Причина:** Этот номер счета уже привязан к другому пользователю
|
||||
|
||||
**Решение:**
|
||||
1. Проверьте номер счета
|
||||
2. Если ошибка - деактивируйте старый: /remove_account <номер>
|
||||
3. Добавьте заново
|
||||
|
||||
### Проблема: Счет не добавился в розыгрыш
|
||||
|
||||
**Причина:** Счет уже участвует в этом розыгрыше
|
||||
|
||||
**Решение:** Это нормально, система предотвращает дубликаты
|
||||
|
||||
---
|
||||
|
||||
## 📚 Команды для администратора (обновленный список)
|
||||
|
||||
### Управление счетами:
|
||||
- `/add_account` - Добавить счета (интерактивно или пакетом)
|
||||
- `/add_account <club_card> <account>` - Быстрое добавление одного счета
|
||||
- `/remove_account <account>` - Деактивировать счет
|
||||
- `/user_info <club_card>` - Информация о пользователе
|
||||
|
||||
### Управление розыгрышами:
|
||||
- Создание через интерфейс (кнопка "Создать розыгрыш")
|
||||
- Проведение через интерфейс (кнопка "Провести розыгрыш")
|
||||
- `/winner_status <lottery_id>` - Статус победителей
|
||||
|
||||
### Верификация:
|
||||
- `/verify_winner <code> <lottery_id>` - Подтвердить выигрыш
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Рекомендации по использованию
|
||||
|
||||
### Для массового добавления счетов:
|
||||
|
||||
1. **Подготовьте данные в текстовом файле**
|
||||
```
|
||||
2223 11-22-33-44-55-66-77
|
||||
2223 88-99-00-11-22-33-44
|
||||
3334 12-34-56-78-90-12-34
|
||||
...
|
||||
```
|
||||
|
||||
2. **Скопируйте и вставьте в бота**
|
||||
```
|
||||
/add_account
|
||||
[Вставить все строки]
|
||||
```
|
||||
|
||||
3. **Выберите розыгрыш**
|
||||
|
||||
4. **Проверьте результаты**
|
||||
|
||||
### Для одиночных счетов:
|
||||
|
||||
Используйте быстрый режим:
|
||||
```
|
||||
/add_account 2223 11-22-33-44-55-66-77
|
||||
```
|
||||
|
||||
### Для новых пользователей:
|
||||
|
||||
1. Сначала попросите зарегистрироваться
|
||||
2. Затем добавьте счета
|
||||
3. Счета автоматически будут доступны в розыгрышах
|
||||
|
||||
---
|
||||
|
||||
## ✅ Чек-лист для администратора
|
||||
|
||||
При добавлении новых пользователей:
|
||||
|
||||
- [ ] Пользователь прошел регистрацию (/start → Зарегистрироваться)
|
||||
- [ ] Пользователь получил код верификации
|
||||
- [ ] Добавлены все счета через /add_account
|
||||
- [ ] Счета добавлены в активный розыгрыш
|
||||
- [ ] Пользователю отправлены уведомления
|
||||
- [ ] Проверено через /user_info <club_card>
|
||||
|
||||
При проведении розыгрыша:
|
||||
|
||||
- [ ] Все счета добавлены и активны
|
||||
- [ ] Розыгрыш настроен (призы, описание)
|
||||
- [ ] Нажата кнопка "Провести розыгрыш"
|
||||
- [ ] Победители получили уведомления
|
||||
- [ ] Проверен статус через /winner_status <id>
|
||||
|
||||
При подтверждении выигрышей:
|
||||
|
||||
- [ ] Победитель сообщил код верификации
|
||||
- [ ] Код проверен командой /verify_winner
|
||||
- [ ] Победитель получил подтверждение
|
||||
- [ ] Приз передан победителю
|
||||
Reference in New Issue
Block a user