# 📊 Опросы и голосования — v1.1 **Версия:** v1.1 **Дата:** 26 февраля 2026 г. **Статус:** ✅ Реализовано --- ## 📋 Описание Система создания и проведения опросов в чате дома. Позволяет администраторам создавать голосования с inline-кнопками, жильцы голосуют анонимно, результаты отображаются в реальном времени. --- ## 🎯 Возможности - ✅ Создание опросов с 2-10 вариантами ответов - ✅ Inline-кнопки для голосования - ✅ Подсчёт голосов в реальном времени - ✅ Отображение результатов в процентах - ✅ Визуальная шкала (████░░░░░░) - ✅ Закрытие опроса админом - ✅ Защита от повторного голосования (1 человек = 1 голос) - ✅ Только админы могут создавать опросы --- ## 📱 Команды ### Для администраторов: | Команда | Описание | Пример | |---------|----------|--------| | `/poll_create "Вопрос" "Вариант 1" "Вариант 2"` | Создать опрос | `/poll_create "За какой цвет?" "Бежевый" "Зелёный"` | | `/poll_create` (в диалоге) | Пошаговое создание | Бот спросит вопрос, потом варианты | | `/poll_end ` | Закрыть опрос | `/poll_end 5` | | `/polls` | Список активных опросов | `/polls` | ### Для жильцов: | Действие | Описание | |----------|----------| | **Нажать кнопку** | Проголосовать за вариант | | `/polls` | Посмотреть активные опросы | --- ## 🎯 Сценарии использования ### Сценарий 1: Быстрое создание (с аргументами) **Админ пишет в чат:** ``` /poll_create "За какой цвет покрасить подъезд?" "Бежевый" "Зелёный" "Серый" "Белый" ``` **Бот создаёт опрос:** ``` 📊 ОПРОС За какой цвет покрасить подъезд? Голосуйте кнопками ниже! 👇 [🔘 Бежевый] [🔘 Зелёный] [🔘 Серый] [🔘 Белый] ``` **Ответ бота (в личку админу):** ``` ✅ Опрос создан! Вопрос: За какой цвет покрасить подъезд? Вариантов: 4 Для закрытия: /poll_end 1 ``` --- ### Сценарий 2: Пошаговое создание (в диалоге) **1. Админ пишет:** ``` /poll_create ``` **2. Бот просит:** ``` 📊 Создание опроса Отправьте вопрос опроса (или используйте команду с аргументами): /poll_create "За какой цвет покрасить подъезд?" "Бежевый" "Зелёный" "Серый" ``` **3. Админ отправляет:** ``` Когда провести субботник? ``` **4. Бот просит:** ``` 📝 Теперь отправьте варианты ответов через запятую: Вариант 1, Вариант 2, Вариант 3 Или отмените: /cancel ``` **5. Админ отправляет:** ``` 5 марта, 12 марта, 19 марта ``` **6. Бот создаёт опрос** (как в Сценарии 1) --- ### Сценарий 3: Голосование жильца **1. Жилец видит опрос в чате:** ``` 📊 ОПРОС За какой цвет покрасить подъезд? Голосуйте кнопками ниже! 👇 [🔘 Бежевый] [🔘 Зелёный] [🔘 Серый] [🔘 Белый] ``` **2. Жилец нажимает кнопку** `[🔘 Зелёный]` **3. Бот отвечает (в личку):** ``` ✅ Ваш голос учтён! ``` **4. В чат отправляются результаты:** ``` 📊 Результаты голосования █████░░░░░ Бежевый: 3 (15%) ██████████ Зелёный: 10 (50%) ████░░░░░░ Серый: 2 (10%) █████░░░░░ Белый: 5 (25%) 👥 Всего голосов: 20 ``` --- ### Сценарий 4: Повторное голосование **Если жилец передумал и нажал другую кнопку:** 1. Старый голос **автоматически удаляется** 2. Новый голос **учитывается** 3. Результаты **обновляются** **Пример:** - Жилец нажал «Зелёный» → +1 к Зелёному - Через час нажал «Бежевый» → -1 у Зелёного, +1 к Бежевому --- ### Сценарий 5: Закрытие опроса **Админ:** ``` /poll_end 1 ``` **Бот публикует в чат:** ``` 🔒 ОПРОС ЗАКРЫТ Вопрос: За какой цвет покрасить подъезд? ██████████ Бежевый: 5 (25%) ██████████ Зелёный: 10 (50%) ████░░░░░░ Серый: 2 (10%) █████░░░░░ Белый: 3 (15%) 👥 Всего голосов: 20 ``` **Опрос больше не принимает голоса** (кнопки не работают). --- ### Сценарий 6: Просмотр списка опросов **Жилец:** ``` /polls ``` **Бот:** ``` 📊 Активные опросы 1. За какой цвет покрасить подъезд?... (20 голосов) 🟢 Активен 2. Когда провести субботник?... (15 голосов) 🟢 Активен 💡 Для голосования нажмите на кнопку в сообщении с опросом ``` --- ## 🛡️ Защита и ограничения ### Кто может создавать опросы: - ✅ **Только администраторы** - ❌ Обычные пользователи — команда не доступна ### Кто может голосовать: - ✅ **Все жильцы** (даже неверифицированные) - ✅ Один голос от человека - ✅ Можно поменять голос ### Максимум вариантов: - **10 вариантов** (если больше — обрежутся) ### Где работают опросы: - ✅ **В общем чате** (создание и голосование) - ❌ В личке — только справка --- ## 🗄️ База данных ### Таблица `polls`: ```sql CREATE TABLE polls ( poll_id INTEGER PRIMARY KEY AUTOINCREMENT, message_id BIGINT NOT NULL, -- ID сообщения в Telegram chat_id BIGINT NOT NULL, -- ID чата question TEXT NOT NULL, -- Вопрос options TEXT NOT NULL, -- JSON: ["В1", "В2", ...] votes TEXT, -- JSON: {"0": [uid1, uid2], "1": [uid3]} created_by BIGINT NOT NULL, -- ID создателя created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_active BOOLEAN DEFAULT 1, -- Активен ли closed_at TIMESTAMP, -- Дата закрытия FOREIGN KEY (created_by) REFERENCES users(user_id) ) ``` ### Индексы: - `ix_polls_chat_active` — для быстрого поиска по чату - `ix_polls_created_at` — для сортировки по дате --- ## 🧪 Тестирование ### Чек-лист проверки: #### 1. Создание опроса ```bash # В тестовой группе (админ): /poll_create "Тест?" "Да" "Нет" ``` - [ ] Опрос появился в чате - [ ] Кнопки отображаются - [ ] Бот прислал номер опроса #### 2. Голосование ```bash # С другого аккаунта (друг): # Нажать кнопку "Да" ``` - [ ] Голос засчитался - [ ] Результаты показали проценты - [ ] В БД обновилось #### 3. Повторное голосование ```bash # Нажать другую кнопку ``` - [ ] Старый голос снялся - [ ] Новый засчитался - [ ] Всего голосов не изменилось #### 4. Закрытие опроса ```bash # Админ: /poll_end 1 ``` - [ ] Опрос закрыт - [ ] Кнопки не работают - [ ] Финальные результаты показаны #### 5. Список опросов ```bash /polls ``` - [ ] Показывает активные опросы - [ ] Количество голосов верно --- ## 📁 Изменённые файлы | Файл | Изменения | |------|-----------| | `database/models.py` | Добавлена модель `Poll` | | `database/migrate_add_polls.py` | Миграция БД (создание таблицы) | | `handlers/polls.py` | Новый хендлер (создание, голосование, результаты) | | `keyboards/inline.py` | Кнопки для опросов | | `handlers/__init__.py` | Импорт `polls_router` | | `main.py` | Регистрация `polls_router` | --- ## 🚀 Как использовать ### Для админа: 1. **Создать опрос (быстро):** ``` /poll_create "Вопрос?" "Вариант 1" "Вариант 2" "Вариант 3" ``` 2. **Создать опрос (пошагово):** ``` /poll_create ``` Далее следуй инструкциям бота. 3. **Закрыть опрос:** ``` /poll_end 1 ``` (где `1` — номер опроса из ответа бота) 4. **Посмотреть опросы:** ``` /polls ``` ### Для жильца: 1. **Проголосовать:** - Нажать кнопку в сообщении с опросом 2. **Посмотреть результаты:** - После голосования бот покажет результаты - Или `/polls` — список активных --- ## 💡 Советы ### Хорошие вопросы: ✅ «За какой цвет покрасить подъезд?» ✅ «Когда провести субботник?» ✅ «Нужно ли видеонаблюдение?» ### Плохие вопросы: ❌ «Кто хороший?» (субъективно) ❌ «Голосуйте!» (нет вариантов) ### Лучшие практики: - 3-5 вариантов — оптимально - Варианты должны быть взаимно исключающими - Закрывайте опрос когда голосов достаточно --- ## 🔧 Отладка ### Посмотреть опросы в БД: ```bash cd /home/matrixhasyou/domovoy_bot source venv/bin/activate sqlite3 database/domovoy.db SELECT * FROM polls ORDER BY created_at DESC LIMIT 10; ``` ### Логи: ```bash tail -f logs/bot.log | grep poll ``` ### Ошибки: - «Опрос не найден» — проверьте номер - «Опрос уже закрыт» — используйте `/polls` для поиска активных - «Нужно минимум 2 варианта» — добавьте ещё один --- ## ✅ Преимущества | Было | Стало | |------|-------| | Опросы в словах | **Inline-кнопки** | | Ручной подсчёт | **Автоматически** | | Не видно кто голосовал | **Анонимно** | | Нельзя поменять голос | **Можно переголосовать** | | Нет истории | **Сохранение в БД** | --- **Опросы готовы! 🎉** *Следующий шаг: тестирование на тестовой группе и фиксация версии v1.1*