Files
icq/PRD.md
T

182 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD: Семейный мессенджер ICQ (XMPP) на nixg.ru
> Версия: 0.2 · Дата: 2026-08-28 · Статус: в разработке (Этапы 1-2 выполнены ✅, Этап 3 бот — следующий)
> ⚠️ Актуальный домен: **nixg.ru** (JID user@nixg.ru). В тексте ниже старый домен chat.nixg.ru
> из ранней версии PRD — при реализации везде используется nixg.ru (см. WALKTHROUGH.md).
>
> **Практический разбор всего сделанного: [WALKTHROUGH.md](WALKTHROUGH.md)** —
> пошаговое описание с командами, почему выбрана такая архитектура, и все «засады».
>
> **Текущее состояние и план: [STATUS.md](STATUS.md)** — учётные данные, что работает,
> проблема пустой страницы + план исправления (точка входа для новой сессии).
## 1. Обзор (Executive Summary)
Разворачиваем собственный федеративный мессенджер для семьи на базе протокола
**XMPP**. Сервер (Prosody) живёт на **bigbox** в каталоге `/opt/icq`, наружу
выставляется через **vps02** (Caddy + WireGuard). Домен: **chat.nixg.ru**.
Федерализация — обязательное требование: общение с любым XMPP-сервером в мире
(email-подобная модель s2s).
Дополнительно: **бот-книгоискатель**, который по запросу находит и скачивает
книги из сетевых библиотек (OPDS-каталоги) и присылает файл прямо в чат.
## 2. Цели (Goals)
- Личный, принадлежащий нам мессенджер для семьи (родители, дети).
- Федеративность: связь с пользователями любых XMPP-серверов.
- Клиенты под iOS и Android из официальных сторов (Snikket / Monal / Conversations).
- Сквозное шифрование (OMEMO) по умолчанию.
- Работает через наш туннель и не зависит от публичных мессенджеров.
- Бот, автоматизирующий скачивание книг из сетевых библиотек.
## 3. Не-цели (Non-Goals)
- Не пытаемся «слямзить» протокол Telegram/MTProto — это закрытый централизованный
протокол, серверная часть не существует и не появится. Федеративность = XMPP.
- Не строим свой клиент — используем готовые (Element/Snikket/Monal/Conversations).
- Пока не делаем мост в Telegram/WhatsApp (mautrix) — только если понадобится позже.
## 4. Архитектура
### 4.1 Компоненты
```
[Клиенты: iOS/Android (Snikket/Monal/Conversations)]
│ c2s (5222, TLS)
▼
[bigbox] Prosody (XMPP-сервер, Docker, /opt/icq)
│ s2s (5269, TLS) — федерация с другими серверами
│ http_upload (XEP-0363) — передача файлов (книги бота)
▼
[Бот-книгоискатель] slixmpp на bigbox, логинится как bot@chat.nixg.ru
│ OPDS (HTTP)
▼
[Сетевые библиотеки: Флибуста и др.]
```
### 4.2 Сеть (доступность)
- **bigbox** — внутренний сервер (без публичного IP), Docker Compose.
- **vps02** — публичный вход: Caddy (TLS, reverse-proxy WebSocket/HTTP) + WireGuard
туннель до bigbox.
- **Порты:** 443 (клиенты, веб) + 5222 (прямые клиенты) + 5269 (федерация s2s).
- Форвард 5222/5269 с vps02 на bigbox через WireGuard (socat или iptables).
### 4.3 DNS (важно для федерации)
```
A chat.nixg.ru → публичный IP vps02
SRV _xmpp-client._tcp.chat.nixg.ru → chat.nixg.ru:5222
SRV _xmpp-server._tcp.chat.nixg.ru → chat.nixg.ru:5269
```
Без SRV-записей другие XMPP-серверы не смогут нас найти (федерация не заработает).
Входящая федерация требует открытого 5269 на vps02.
### 4.4 TLS / сертификаты
- 443: Caddy выпускает сам (Let's Encrypt, http-01).
- 5222/5269: dns-01 (домен у нас, DNS контролируем) → e.g. через Caddy/acme.sh.
- Сертификат должен покрывать имена `chat.nixg.ru` (+ возможно `conference.chat.nixg.ru` для MUC).
## 5. Стек технологий
| Слой | Технология | Почему |
|------|-----------|--------|
| Протокол | XMPP (RFC 6120/6121) | Федеративный, открытый, XML — как email |
| Сервер | Prosody (Lua, Docker) | Лёгкий, гибкий, модули (http_upload, muc), удобен за реверс-прокси |
| Внешний доступ | Caddy на vps02 + WireGuard | TLS автоматически, reverse-proxy, WG-туннель до bigbox |
| Клиенты iOS | Monal / Snikket | Федерация + OMEMO + push (APNs) |
| Клиенты Android | Conversations / Snikket | Федерация + OMEMO + push (FCM) |
| Бот | Python + slixmpp | Зрелая живая библиотека XMPP |
| Поиск книг | OPDS (Atom/XML каталоги) | Стандарт сетевых библиотек (Флибуста и др.) |
| Передача файлов | XMPP HTTP Upload (XEP-0363) | Отправка книг в чат |
| Развёртывание | Docker Compose в /opt/icq | Изоляция, простота, переносимость |
Примечание: Snikket как *сервер* не берём (спроектирован под прямой 443, капризен
за реверс-прокси), но его *клиенты* хороши — используем их.
## 6. Функциональные требования
### 6.1 Обязательные (Must have)
- FR-1: Регистрация/вход по JID (user@chat.nixg.ru) с паролем.
- FR-2: Личные сообщения 1-на-1, статусы присутствия (presence).
- FR-3: Групповые чаты (MUC, конференции).
- FR-4: Сквозное шифрование OMEMO.
- FR-5: Передача файлов (HTTP Upload) — фото, документы.
- FR-6: Федерация s2s — общение с пользователями других серверов.
- FR-7: Админка/панель управления сервером (Prosody admin + командная строка).
- FR-8: Клиенты iOS и Android из официальных сторов.
### 6.2 Желательные (Should have)
- FR-9: Push-уведомления на iOS/Android (APNs/FCM) — через push-шлюз (Snikket/Conversations могут ходить на свой или публичный).
- FR-10: Бот-книгоискатель (slixmpp + OPDS).
- FR-11: Бэкапы базы/конфигов (в наш общий бэкап /opt/hermes).
- FR-12: Логирование и мониторинг (доступность).
### 6.3 Мосты в Telegram и WhatsApp (Bridges)
- FR-13: Мост в **Telegram** (mautrix-telegram) — общение с контактами Telegram из нашего клиента.
- Двусторонняя переписка: наш пользователь ↔ контакт в Telegram.
- Возможность отправлять/принимать файлы, реакции (по возможностям моста).
- Авторизация через Telegram (логин/QR/MTProto), управление через панель бота моста.
- FR-14: Мост в **WhatsApp** (mautrix-whatsapp) — общение с контактами WhatsApp из нашего клиента.
- Двусторонняя переписка: наш пользователь ↔ контакт в WhatsApp.
- Авторизация через QR-код WhatsApp Web.
- Передача файлов, голосовых (по возможностям моста).
- FR-15: Общий мост-хостинг (mautrix с Postgres/базой), регистрация в Prosody как компоненты.
- OQ-5: Какие мосты деплоим сразу (оба), какие позже? Сначала Telegram, потом WhatsApp (обычно надёжнее).
## 7. Бот-книгоискатель (детально)
### 7.1 Сценарий
1. Пользователь пишет боту `book@chat.nixg.ru`: «Пушкин Капитанская дочка».
2. Бот ищет по OPDS-каталогам (Флибуста и др.).
3. Находит, скачивает (epub/fb2), присылает файлом через HTTP Upload.
4. (Опц.) Ограничение размера, только легальные источники.
### 7.2 Требования
- FR-B1: Приём запросов через личные сообщения.
- FR-B2: Поиск по OPDS (Atom feed).
- FR-B3: Скачивание и отправка файла в чат (XEP-0363).
- FR-B4: Логирование запросов.
- FR-B5: Анти-флуд / ограничения.
## 8. Открытые вопросы (Open Questions)
- OQ-1: Какая библиотека OPDS основная? Флибуста (нужны ли регистрация/логин)?
- OQ-2: ~~Snikket-клиенты работают только со Snikket-серверами?~~ (нет — возьмём Monal + Conversations)
- OQ-3: Нужен ли мост Telegram (mautrix-telegram) сразу или позже?
- OQ-4: ~~Нужен ли веб-клиент (Converse.js) на 443 через Caddy?~~ **✅ СДЕЛАНО 2026-08-28** —
https://chat.nixg.ru, Converse.js v14, локальные ассеты, WebSocket wss://chat.nixg.ru/xmpp-websocket.
## 9. Roadmap (этапы)
1. **Этап 1 — Фундамент (✅ ЗАВЕРШЁН 2026-08-28):** Docker Compose Prosody на bigbox (/opt/icq),
базовые модули, DNS на chat.nixg.ru + SRV (A, _xmpp-client, _xmpp-server — внесены на Jino),
Caddy на vps02 (443, reverse-proxy), форвард 5222/5269 через WG (iptables DNAT + FORWARD + MASQUERADE),
группа безопасности Timeweb (TCP 5222/5269), веб-клиент Converse.js v14 на 443.
Проверено: 5222/5269 открыты извне, webchat отдаётся, WebSocket 101 Switching Protocols.
Подробности: [WALKTHROUGH.md](WALKTHROUGH.md).
2. **Этап 2 — Семья и федерация:** MUC (есть), OMEMO, **HTTP Upload (XEP-0363)** — установить
community-модуль mod_http_upload из prosody-modules (в docker-образе Prosody 0.11.9 его НЕТ),
добавление внешнего контакта (проверка s2s), настоящие сертификаты dns-01 для 5222/5269.
Приглашение семьи. Клиенты iOS/Android.
3. **Этап 3 — Бот:** slixmpp-бот с OPDS-поиском, HTTP Upload.
4. **Этап 4 — Полировка:** push, бэкапы, мониторинг, (опц.) мосты mautrix.
## 10. Принятые решения (Decisions)
- D-1: Протокол = XMPP (не Telegram/MTProto).
- D-2: Сервер = Prosody (не Snikket-сервер, не Ejabberd).
- D-3: Размещение = bigbox (/opt/icq), внешний вход = vps02 (Caddy + WG).
- D-4: Домен = chat.nixg.ru.
- D-5: Бот = Python slixmpp + OPDS + HTTP Upload.
## 11. Риски
- R-1: Флибуста меняет зеркала/требует VPN/логин — бот должен уметь переключать источники.
- R-2: Push на iOS (APNs) сложен для self-hosted — упираемся в публичный push-шлюз.
- R-3: Ограничение 5269 у провайдера vps02 — проверить заранее.
- R-4: Семейные пользователи малознакомы с XMPP-клиентами — подготовить инструкцию.