Backend / REST API v2.1

API: Групповые чаты

Создание групп, управление участниками, система ролей, выход, синхронизация событий и ключей. Префикс: /groups. Файл: srv/app/api/endpoints/groups.py

✨ Обновлено в v2.1.0
• Система ролей (admin/member)
• Передача прав администратора
• Удаление участников администратором
• Автоудаление пустых групп
• Валидация размера группы (макс. 256 участников)
• Атомарные операции с epoch (устранены race conditions)
• Health check и maintenance эндпоинты

Обзор эндпоинтов

МетодПутьAuthРольОписание
POST/groups/createBearer—Создать новую групповую сессию
GET/groups/meBearer—Список активных групп текущего пользователя
GET/groups/{id}/membersBearer—Список участников конкретной группы
POST/groups/{id}/leaveBearer—Выйти из группы по собственному желанию
POST/groups/{id}/addBearer👑 AdminДобавить новых участников (с валидацией эпохи)
POST/groups/{id}/transfer-ownershipBearer👑 AdminПередать права администратора другому участнику
POST/groups/{id}/remove-memberBearer👑 AdminУдалить участника из группы
GET/groups/{id}/sync_eventsBearer—Синхронизация коммитов и событий эпох
GET/groups/healthBearer—Проверка здоровья системы групп
POST/groups/maintenance/cleanupBearer🔧 SuperОчистка старых данных (только admin)

Система ролей

Каждый участник группы имеет одну из двух ролей:

👑 Admin (Администратор)

  • Может добавлять новых участников в группу
  • Может удалять участников из группы
  • Может передавать права администратора другому участнику
  • Создатель группы автоматически получает роль admin
  • При выходе админа права автоматически передаются следующему по времени вступления

👤 Member (Участник)

  • Может читать и отправлять сообщения в группу
  • Может просматривать список участников
  • Может выйти из группы
  • Не может добавлять/удалять участников

Лимиты и валидация

ПараметрЗначениеОписание
MAX_GROUP_SIZE256Максимальное количество участников в группе
MAX_MEMBERS_PER_ADD50Максимальное количество участников за одно добавление
MIN_GROUP_SIZE2Минимальное количество участников для создания

POST /groups/create

Инициализирует новую зашифрованную группу. Создатель группы автоматически становится её администратором. Метод проверяет наличие открытых ключей у всех участников перед созданием и отправляет WebSocket-событие group_created всем приглашенным участникам.

Request Body (JSON)
{
  "title": "Проект Альфа",     // Название группы (опционально)
  "user_ids": [4, 7, 12],      // Список приглашаемых ID пользователей (обязательно)
  "encrypted_keys": {          // Зашифрованные ключи для каждого пользователя (опционально)
    "4": "eyJDcnlwdG9LZXkiOi...",
    "7": "eyJDcnlwdG9LZXkiOi...",
    "12": "eyJDcnlwdG9LZXkiOi..."
  }
}
Response 200 OK
{
  "id": 1,
  "title": "Проект Альфа",
  "created_at": "2026-07-14T10:25:26.123456",
  "epoch": 1                  // Начальная эпоха
}
Error 400 Bad Request
{
  "detail": "Users without public keys: [4, 7]"
}
// или
{
  "detail": "Превышен максимальный размер группы. Максимум: 256 участников"
}
// или
{
  "detail": "Группа должна содержать минимум 2 участника"
}

GET /groups/me

Возвращает список всех групп, в которых текущий пользователь имеет статус active. Сортируется по времени создания в порядке убывания.

Response 200 OK
[
  {
    "id": 1,
    "title": "Проект Альфа",
    "created_at": "2026-07-14T10:25:26.123456",
    "epoch": 3
  }
]

GET /groups/{group_id}/members

Возвращает список участников группы с их публичными метаданными, статусом активности и ролью. Доступно только активным членам этой группы.

Response 200 OK
[
  {
    "user_id": 1,
    "status": "active",        // active, left, evicted
    "role": "admin",           // admin или member
    "username": "alice",
    "name": "Алиса",
    "surname": "Смит",
    "avatar_file_id": "media-uuid-123",
    "last_online": "2026-07-14T10:01:00",
    "online": true
  },
  {
    "user_id": 4,
    "status": "active",
    "role": "member",
    "username": "bob",
    "name": "Боб",
    "surname": "Джонс",
    "avatar_file_id": null,
    "last_online": "2026-07-14T09:45:00",
    "online": false
  }
]

POST /groups/{group_id}/leave

Пользователь выходит из группы по собственному желанию. Его членский статус переводится в left, а эпоха группы увеличивается на 1. Если выходит администратор, права автоматически передаются следующему участнику. Если выходит последний участник, группа удаляется автоматически.

Response 200 OK
{
  "status": "ok",
  "detail": "Вы успешно покинули группу"
}
// или (если последний участник)
{
  "status": "ok",
  "detail": "Вы успешно покинули группу. Группа удалена, так как все участники вышли."
}
⚠️ Важно: При выходе администратора из группы права автоматически передаются следующему по времени вступления активному участнику. Новый админ получает WebSocket-уведомление group_admin_changed.

POST /groups/{group_id}/add Admin Only

Добавляет новых участников в группу. Доступно только администратору. Требует указания expected_epoch для предотвращения race conditions. Атомарно увеличивает epoch группы.

Request Body (JSON)
{
  "user_ids": [15, 20],
  "encrypted_keys": {
    "15": "eyJDcnlwdG9LZXkiOi...",
    "20": "eyJDcnlwdG9LZXkiOi..."
  },
  "expected_epoch": 3          // Текущая эпоха группы
}
Response 200 OK
{
  "status": "ok",
  "added_user_ids": [15, 20],
  "new_epoch": 4
}
Error 403 Forbidden
{
  "detail": "Только администратор группы может добавлять участников"
}