# Research: Альтернативные варианты организации чатов в Telegram

## Сравнительная таблица

| Вариант | Friction для юзера | Техническая сложность | Ограничения | Статус |
|---------|-------------------|----------------------|-------------|--------|
| **1. Виртуальные чаты в DM** | Нет | Низкая | Нет | ✅ РЕКОМЕНДУЕТСЯ |
| **2. Threads / Reply Threads** | Высокая | Средняя | Требует группу, бот не создаёт темы | ❌ |
| **3. Multiple Bot Instances** | Высокая | Средняя | Нужно добавлять каждый | ❌ |
| **4. Inline Mode** | Нет | Низкая | Stateless, не для диалогов | ❌ |
| **5. Бот создаёт приватные группы** | Очень высокая | Очень высокая | Bot API не создаёт группы | ❌ |
| **6. Telegram Web App (TWA)** | Нет | Высокая | Нужен web-сервер | ⚠️ Phase 2 |
| **7. Forum Topics (исходный)** | Высокая | Средняя | Пользователь создаёт группу вручную | ⚠️ Оставить как опцию |

---

## Вариант 1: Виртуальные чаты в DM (РЕКОМЕНДУЕТСЯ)

### Как выглядит для пользователя

```
/start
→ [➕ Новый чат]  [📋 Мои чаты]  [⚙️ Настройки]

Нажимает "Новый чат"
→ "✅ Чат #1 создан! Начните писать..."

User: "Расскажи про Python"
→ "[Чат #1] Python — это язык программирования..."

Нажимает "Мои чаты"
→ 1️⃣ Чат #1 (Python)
  2️⃣ Чат #2 (Математика)  — 2 часа назад
  3️⃣ Исследование рынка   — вчера

Нажимает на "Чат #2"
→ "Вы в Чате #2. Последние сообщения: ..."
→ Продолжает разговор
```

### Технические детали (aiogram 3.x)

#### FSM состояния

```python
from aiogram.fsm.state import State, StatesGroup

class UserStates(StatesGroup):
    main_menu = State()
    in_chat = State()
    selecting_chat = State()
```

#### Хранение активного чата в StateData

```python
# При создании чата
await state.set_state(UserStates.in_chat)
await state.update_data(active_chat_id=chat_id)

# При получении сообщения
data = await state.get_data()
chat_id = data["active_chat_id"]
```

#### Список чатов с инлайн-кнопками

```python
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton

@router.message(Command("list"))
async def cmd_list(message: Message, state: FSMContext):
    chats = db.get_user_chats(message.from_user.id)

    buttons = [
        [InlineKeyboardButton(
            text=f"📄 {chat.title or f'Чат #{chat.id[:6]}'}",
            callback_data=f"select:{chat.id}"
        )]
        for chat in chats
    ]
    await message.answer("📋 Ваши чаты:", reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons))

@router.callback_query(F.data.startswith("select:"))
async def switch_chat(callback: CallbackQuery, state: FSMContext):
    chat_id = callback.data.split(":")[1]
    await state.update_data(active_chat_id=chat_id)
    await state.set_state(UserStates.in_chat)
    await callback.message.edit_text(f"✅ Переключился в чат. Пишите...")
```

#### Схема БД

```sql
CREATE TABLE chats (
    chat_id TEXT PRIMARY KEY,     -- UUID
    user_id INTEGER NOT NULL,
    title TEXT,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

CREATE TABLE messages (
    id INTEGER PRIMARY KEY,
    chat_id TEXT NOT NULL,
    user_id INTEGER NOT NULL,
    direction TEXT,               -- 'user' / 'bot'
    content TEXT NOT NULL,
    created_at TIMESTAMP,
    FOREIGN KEY(chat_id) REFERENCES chats(chat_id)
);
```

### Ограничения

- История только в нашей БД, не в Telegram нативно
- Нет шаринга чата с другими пользователями

### Примеры в реальных ботах

- **ChatGPT Telegram боты** — именно этот паттерн, `/new` → новый разговор, `/history` → список
- **StudyGPT** — каждый урок = отдельный "чат" с контекстом
- **Notion Bot** — список "проектов" с переключением

### Оценка

✅ Нулевое трение — ничего настраивать не нужно
✅ Работает в DM — приватно
✅ Стандартный паттерн — пользователи знакомы
✅ Полный контроль над UX
✅ Масштабируется без ограничений
❌ История только в нашей БД (но это нормально)

---

## Вариант 2: Threads / Reply Topics — ОТКЛОНЕНО

### Суть

Telegram поддерживает `message_thread_id` в апдейтах — можно читать из какого треда пришло сообщение и отвечать в него. Но:

- **Бот не может создавать треды** — Bot API этого не умеет
- Работает только в Group/Supergroup, не в DM
- Пользователь должен создавать каждый тред вручную
- Не решает проблему friction — делает хуже

```python
# Читать можно
thread_id = message.message_thread_id  # int или None

# Отвечать можно
await message.answer("ответ", message_thread_id=thread_id)

# Создать тред НЕЛЬЗЯ — метода нет в Bot API
```

---

## Вариант 3: Deep Linking — ОТКЛОНЕНО

Каждый чат = отдельная ссылка вида `https://t.me/bot?start=chatid_xyz`. Пользователь переходит по ссылке, бот предвыбирает чат.

**Проблема:** пользователь не знает что такие ссылки существуют, нет discovery, не масштабируется.

```python
@router.message(Command("start"))
async def cmd_start(message: Message):
    args = message.text.split()
    if len(args) > 1:
        chat_id = args[1]  # из deep link
        # предвыбрать чат
```

---

## Вариант 4: Inline Mode — ОТКЛОНЕНО

Inline mode (`@botname query`) — fundamentally stateless. Один запрос → несколько результатов → пользователь выбирает. Нет истории, нет контекста. Категорически не подходит для многооборотного диалога с AI.

---

## Вариант 5: Бот создаёт приватные группы — ОТКЛОНЕНО

**Telegram Bot API не умеет создавать группы.** Единственный workaround — заранее создать 100+ пустых групп и назначать их пользователям. 1000 пользователей = 1000 лишних групп. Абсурд.

---

## Вариант 6: Telegram Web App (TWA) — Phase 2

### Суть

Кнопка в боте открывает мини-приложение (веб). Там красивый интерфейс со списком чатов, историей, поиском.

### Технические детали

```python
# В боте
from aiogram.types import WebAppInfo, InlineKeyboardButton

web_app_btn = InlineKeyboardButton(
    text="📱 Открыть приложение",
    web_app=WebAppInfo(url="https://lambda.example.com/app")
)
```

```javascript
// В TWA (JavaScript)
const tg = window.Telegram.WebApp;
const user_id = tg.initDataUnsafe.user.id;

// Загрузить список чатов
const chats = await fetch('/api/chats', {
    headers: { 'X-Telegram-Init-Data': tg.initData }
}).then(r => r.json());
```

### Оценка

✅ Красивый интерфейс (история, поиск, форматирование)
✅ Мобильный-friendly
⚠️ Нужен HTTPS web-сервер
⚠️ Сложнее разрабатывать
⚠️ Усложняет деплой

**Вывод: хороший вариант для v2, не для MVP.**

---

## Финальные рекомендации

### Сейчас (MVP)
**Вариант 1 — Виртуальные чаты в DM.** Реализуется за 2-3 дня, нулевое friction, стандартный паттерн.

### Phase 2
**Вариант 6 — TWA** как дополнительный UI поверх той же логики. Бэкенд не меняется — просто добавляется web-интерфейс.

### Опционально (для пользователей которые хотят)
**Forum Topics** — оставить как opt-in возможность. Пользователь сам создаёт группу, добавляет бота — получает "продвинутый режим" с нативными Telegram темами.

---

## Что это означает для архитектуры

`ChatManager` в `core/chat.py` должен работать одинаково для обоих режимов — и виртуальных чатов в DM, и Forum Topics. Разница только в адаптере:

| | Telegram DM (virtual) | Telegram Forum | Matrix |
|-|-----------------------|----------------|--------|
| `chat_id` | UUID | `message_thread_id` | `room_id` |
| Создание | В БД | `create_forum_topic` | `room_create` |
| Отправка | `send_message(chat_id=user_id)` + tag | `send_message(thread_id=...)` | `room_send` |
| `core/` | Не знает разницы | Не знает разницы | Не знает разницы |
