# 📊 Опросы и голосования — v1.1

**Версия:** v1.1
**Дата:** 26 февраля 2026 г.
**Статус:** ✅ Реализовано

---

## 📋 Описание

Система создания и проведения опросов в чате дома. Позволяет администраторам создавать голосования с inline-кнопками, жильцы голосуют анонимно, результаты отображаются в реальном времени.

---

## 🎯 Возможности

- ✅ Создание опросов с 2-10 вариантами ответов
- ✅ Inline-кнопки для голосования
- ✅ Подсчёт голосов в реальном времени
- ✅ Отображение результатов в процентах
- ✅ Визуальная шкала (████░░░░░░)
- ✅ Закрытие опроса админом
- ✅ Защита от повторного голосования (1 человек = 1 голос)
- ✅ Только админы могут создавать опросы

---

## 📱 Команды

### Для администраторов:

| Команда | Описание | Пример |
|---------|----------|--------|
| `/poll_create "Вопрос" "Вариант 1" "Вариант 2"` | Создать опрос | `/poll_create "За какой цвет?" "Бежевый" "Зелёный"` |
| `/poll_create` (в диалоге) | Пошаговое создание | Бот спросит вопрос, потом варианты |
| `/poll_end <ID>` | Закрыть опрос | `/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*
