- Добавлены функции to_local() и fmt_local() - Время рассылок теперь 17:55 вместо 13:55 - Время прочтений в локальном поясе - Время запланированных постов исправлено - Время дайджестов исправлено Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
247 lines
9.3 KiB
Markdown
247 lines
9.3 KiB
Markdown
# Спецификация V3.1 - Умная рассылка + Еженедельный дайджест
|
||
|
||
> Дата: 6 апреля 2026 г.
|
||
> Статус: В разработке
|
||
> Версия: 3.1
|
||
|
||
---
|
||
|
||
## 📢 Умная рассылка с прочтением
|
||
|
||
### Архитектура
|
||
|
||
**Новые таблицы БД:**
|
||
- `broadcast` — рассылки
|
||
- `id` (PK)
|
||
- `message_id` (Telegram message ID)
|
||
- `chat_id`
|
||
- `text` (текст рассылки)
|
||
- `photo_file_id` (опционально)
|
||
- `sent_at` (timestamp)
|
||
- `sent_by` (admin user ID)
|
||
- `total_sent` (количество получателей)
|
||
- `has_read_button` (boolean — показывать ли кнопку "Прочитал")
|
||
- `is_reminder_sent` (было ли напоминание)
|
||
- `created_at`
|
||
|
||
- `broadcast_read` — кто прочитал
|
||
- `id` (PK)
|
||
- `broadcast_id` (FK → broadcast)
|
||
- `user_id` (FK → users)
|
||
- `read_at` (timestamp)
|
||
|
||
### Функционал
|
||
|
||
**В Telegram:**
|
||
- Рассылка с inline-кнопкой "✅ Прочитал"
|
||
- При нажатии — обновляется статус в БД
|
||
- Кнопка меняется на "✅ Прочитано" (неактивная)
|
||
|
||
**В веб-панели:**
|
||
- Список всех рассылок
|
||
- Статистика: отправлено / прочитано / не прочитано
|
||
- Кнопка "Показать кто прочитал"
|
||
- Кнопка "Показать кто НЕ прочитал"
|
||
- Кнопка "⚠️ Отправить напоминание непрочитавшим"
|
||
- Создание новой рассылки с опцией "Добавить кнопку прочтения"
|
||
|
||
### Команды
|
||
- `/broadcast` — создать рассылку (админ)
|
||
- `/broadcast_stats <id>` — статистика по рассылке
|
||
|
||
---
|
||
|
||
## 📰 Еженедельный дайджест
|
||
|
||
### Архитектура
|
||
|
||
**Новые таблицы БД:**
|
||
- `digest` — дайджесты
|
||
- `id` (PK)
|
||
- `period_start` (начало периода, дата)
|
||
- `period_end` (конец периода, дата)
|
||
- `week_number` (номер недели)
|
||
- `year` (год)
|
||
- `content` (JSON с данными дайджеста)
|
||
- `status` — 'draft' | 'pending_approval' | 'approved' | 'rejected' | 'sent'
|
||
- `message_id` (ID сообщения в Telegram, если отправлен)
|
||
- `created_at` (автогенерация)
|
||
- `approved_at`
|
||
- `approved_by` (admin ID)
|
||
- `sent_at`
|
||
- `rejected_by`
|
||
- `rejection_reason` (причина отклонения)
|
||
|
||
### Генерация контента
|
||
|
||
**Автоматический сбор данных (воскресенье 09:00):**
|
||
1. События за неделю (из таблицы events)
|
||
2. Активные опросы (из polls)
|
||
3. Новые объявления (из ads)
|
||
4. Топ-5 активных жильцов (из users по rating)
|
||
5. Запланированные отключения (из schedule на следующую неделю)
|
||
6. Новые верификации (из verification_requests)
|
||
7. Статистика: всего сообщений, активных пользователей
|
||
|
||
**Формирование текста:**
|
||
```python
|
||
digest_text = f"""
|
||
📰 ДАЙДЖЕСТ ДОМА ЗА НЕДЕЛЮ ({period_start} - {period_end})
|
||
|
||
🔔 События:
|
||
{events_list}
|
||
|
||
📊 Опросы:
|
||
{polls_list}
|
||
|
||
📢 Объявления: {ads_count} новых
|
||
|
||
🏆 Активные жильцы:
|
||
{top_users}
|
||
|
||
⏰ На следующей неделе:
|
||
{schedule_list}
|
||
|
||
📈 Статистика:
|
||
• Сообщений в чате: {messages_count}
|
||
• Активных жильцов: {active_users}
|
||
• Новых верификаций: {new_verifications}
|
||
"""
|
||
```
|
||
|
||
### Процесс утверждения
|
||
|
||
**Автоматический workflow:**
|
||
1. **Воскресенье 09:00** — бот генерирует дайджест
|
||
2. Сохраняет в БД со статусом `pending_approval`
|
||
3. **Отправляет АДМИНУ в личку** превью дайджеста:
|
||
```
|
||
📰 Дайджест за неделю готов!
|
||
|
||
[Просмотреть в веб-панели]
|
||
|
||
Статус: ⏳ Ожидает утверждения
|
||
```
|
||
4. Админ заходит в веб-панель, видит:
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ 📰 Дайджест за 30.03 - 06.04 │
|
||
│ Статус: ⏳ Ожидает утверждения │
|
||
├─────────────────────────────────────┤
|
||
│ [Предпросмотр текста] │
|
||
│ │
|
||
│ [✅ Утвердить и отправить] │
|
||
│ [❌ Отклонить] │
|
||
│ [✏️ Редактировать текст] │
|
||
└─────────────────────────────────────┘
|
||
```
|
||
5. **Если утвердил:**
|
||
- Статус → `approved` → `sent`
|
||
- Бот рассылает ВСЕМ верифицированным жильцам
|
||
- В веб-панели: "✅ Отправлен в 14:32"
|
||
- В чат (опционально): "📰 Дайджест за неделю опубликован!"
|
||
|
||
6. **Если отклонил:**
|
||
- Статус → `rejected`
|
||
- Можно указать причину
|
||
- В БД сохраняется (история)
|
||
|
||
### Хранение и архив
|
||
|
||
**В веб-панели раздел "Архив дайджестов":**
|
||
```
|
||
📰 Архив дайджестов
|
||
|
||
Фильтры: [За неделю] [За месяц] [За квартал] [За год] [Все]
|
||
|
||
┌──────┬──────────────┬──────────┬────────────┐
|
||
│ Нед │ Период │ Статус │ Отправлен │
|
||
├──────┼──────────────┼──────────┼────────────┤
|
||
│ #14 │ 30.03-06.04 │ ✅ Отпр │ 06.04 14:32│
|
||
│ #13 │ 23.03-29.03 │ ✅ Отпр │ 29.03 10:15│
|
||
│ #12 │ 16.03-22.03 │ ❌ Откл │ - │
|
||
│ ... │ ... │ ... │ ... │
|
||
└──────┴──────────────┴──────────┴────────────┘
|
||
|
||
[Экспорт в PDF] [Экспорт в CSV]
|
||
```
|
||
|
||
**Генерация дайджеста за период:**
|
||
- Квартальный: сумма недельных дайджестов
|
||
- Полугодовой: агрегация
|
||
- Годовой: полная статистика + тренды
|
||
|
||
### Настройки в веб-панели
|
||
|
||
```
|
||
⚙️ Настройки дайджеста
|
||
|
||
[✓] Включить автоматическую генерацию
|
||
День недели: [Воскресенье ▼]
|
||
Время генерации: [09:00]
|
||
Время отправки (после утверждения): [10:00]
|
||
|
||
Содержимое:
|
||
[✓] События
|
||
[✓] Опросы
|
||
[✓] Объявления
|
||
[✓] Топ активных жильцов
|
||
[✓] Запланированные отключения
|
||
[✓] Статистика чата
|
||
[✓] Новые верификации
|
||
|
||
Дополнительно:
|
||
[✓] Отправлять превью админу
|
||
[ ] Публиковать автоматически (без утверждения)
|
||
[✓] Сохранять в архив
|
||
```
|
||
|
||
---
|
||
|
||
## План реализации
|
||
|
||
### Этап 1: База данных
|
||
- [ ] Модель Broadcast
|
||
- [ ] Модель BroadcastRead
|
||
- [ ] Модель Digest
|
||
- [ ] Миграция БД
|
||
|
||
### Этап 2: Умная рассылка
|
||
- [ ] Handler /broadcast
|
||
- [ ] Inline кнопки "Прочитал"
|
||
- [ ] Callback обработчики
|
||
- [ ] Веб-панель: список рассылок
|
||
- [ ] Веб-панель: статистика
|
||
- [ ] Веб-панель: создание рассылки
|
||
- [ ] Напоминания непрочитавшим
|
||
|
||
### Этап 3: Дайджест
|
||
- [ ] Сервис генерации контента
|
||
- [ ] APScheduler задача (воскресенье 09:00)
|
||
- [ ] Уведомление админу
|
||
- [ ] Веб-панель: утверждение/отклонение
|
||
- [ ] Веб-панель: редактирование текста
|
||
- [ ] Веб-панель: архив дайджестов
|
||
- [ ] Рассылка после утверждения
|
||
- [ ] Настройки дайджеста
|
||
|
||
### Этап 4: Интеграция
|
||
- [ ] Обновить веб-сервер (новые роуты)
|
||
- [ ] Обновить меню админа
|
||
- [ ] Документация
|
||
|
||
---
|
||
|
||
## Технические детали
|
||
|
||
### Используемые технологии
|
||
- SQLAlchemy модели (async)
|
||
- aiogram inline keyboards
|
||
- APScheduler (cron trigger)
|
||
- FastAPI endpoints
|
||
- Jinja2 templates
|
||
|
||
### Совместимость
|
||
- Не ломает существующий функционал
|
||
- Миграция БД обратима
|
||
- Feature flags для включения/выключения
|