# API, которые использует плеер

Плеер — это **клиент**. Все данные он берёт с серверных API. Этот документ — полный список эндпоинтов которые он дёргает, зачем и от чего ломается если API изменится.

## Базовый URL

В prod:    `https://api.rublox.pro` (alias на `minecraftia-school.ru/api-storys`)
В dev:     `https://dev-api.rublox.pro` (staging, см. [reference-staging-env])
Локально:  `http://localhost:8674` (storys-микросервис)

## Эндпоинты — список

### Игры и лента

| Method | Path | Когда зовётся | Сломается если... |
|---|---|---|---|
| GET | `/kubikon3d/feed?tab=hot\|new\|popular\|topweek` | при заходе на главную | поле `games[]` отсутствует |
| GET | `/kubikon3d/trending` | главная, секция трендов | возвращает не-массив |
| GET | `/kubikon3d/search?q=<query>` | поиск игр | поле `results[]` отсутствует |
| GET | `/kubikon3d/collections` | главная, секции «Хиты», «Новинки» | возвращает не-массив |
| GET | `/kubikon3d/projects/<id>` | при открытии конкретной игры | поле `project_data` отсутствует или поломан JSON-формат |
| GET | `/kubikon3d/my-projects` | страница «Мои игры» | в ответе нет `projects[]` |
| GET | `/kubikon3d/top-authors` | страница «Топ авторов» | возвращает не-массив |
| GET | `/kubikon3d/events` | главная, баннер мероприятий | возвращает не-массив |

### Игровой процесс (telemetry)

| Method | Path | Когда | Что шлёт |
|---|---|---|---|
| POST | `/kubikon3d/play/heartbeat` | каждые 30 сек пока игрок в игре | `{ game_id, play_time_ms }` |
| POST | `/kubikon3d/activity` | при входе/выходе из игры | `{ game_id, action: 'enter'\|'leave' }` |
| POST | `/kubikon3d/perf-log` | при детектировании просадки FPS <20 на 5+ сек | `{ game_id, fps, draw_calls, mem }` |
| POST | `/kubikon3d/bug-reports` | юзер жмёт «Сообщить о баге» | `{ game_id, description, screenshot_b64 }` |
| POST | `/kubikon3d/reports` | юзер репортит игру | `{ game_id, reason, comment }` |

### Скины и аватары (Рублокс-персонажи)

| Method | Path | Когда |
|---|---|---|
| GET | `/kubikon3d/rublox/equipped-skin/<user_id>` | при спавне аватара любого игрока |
| GET | `/kubikon3d/rublox/owned-skins` | страница «Мои скины» |
| POST | `/kubikon3d/rublox/equipped-skin` | юзер сменил скин |
| GET | `/api-storys/rublox/avatars/<user_id>` | список аватаров юзера |
| GET | `/api-storys/rublox/outfit/<user_id>` | детали одежды |
| GET | `/kubikon-assets/characters/skins_manifest.json` | при загрузке плеера, список всех доступных скинов |

### Эмоушены (R15 анимации)

| Method | Path | Когда |
|---|---|---|
| GET | `/api-storys/rublox/emotes/list` | при заходе в игру (для меню эмоушенов) |
| POST | `/api-storys/rublox/emotes/play/<emote_id>` | юзер выбрал эмоушен |

### Модели и ассеты

| Method | Path | Когда |
|---|---|---|
| GET | `/kubikon3d/models/public` | при загрузке игры — список public GLB-моделей |
| GET | `/kubikon3d/models/mine` | в редакторе (плеер запускает превью своих моделей) |
| GET | `/kubikon3d/models/<id>` | при первом упоминании модели в проекте |

### Админка (только видна юзерам с ролью admin)

Все `/kubikon3d/admin/*` доступны только если в JWT юзер имеет роль `admin`. Иначе бэк возвращает 403.

| Method | Path | Что показывает |
|---|---|---|
| GET | `/kubikon3d/admin/dashboard` | сводка: онлайн, активные игры |
| GET | `/kubikon3d/admin/online` | список онлайн-юзеров |
| GET | `/kubikon3d/admin/all-games` | все игры с фильтрами |
| GET | `/kubikon3d/admin/moderation-queue` | очередь премодерации (для review-игр) |
| GET | `/kubikon3d/admin/reports` | репорты на игры |
| GET | `/kubikon3d/admin/bug-reports` | баг-репорты |
| GET | `/kubikon3d/admin/comments` | модерация комментариев |
| GET | `/kubikon3d/admin/chat/messages` | чат-сообщения |
| GET | `/kubikon3d/admin/chat/bans` | список банов в чате |
| GET | `/kubikon3d/admin/authors` | топ авторов с детальной статистикой |

### Multiplayer (Colyseus)

WebSocket-соединение, не HTTP. Адрес: `wss://multiplayer.rublox.pro/<room_id>`. Сейчас работает через `kubikon-realtime` микросервис (VM 110, port 8685, Node.js+Colyseus+Redis).

## Аутентификация

Все приватные эндпоинты ожидают **JWT в заголовке** `Authorization: Bearer <token>`. JWT выдаёт `/api-user/auth/login`. Срок жизни access-токена — 1 час, refresh-токена — 30 дней.

В плеере токен хранится в `localStorage.jwt`, рефрешится автоматически при 401 через `localStorage.refresh_token` → `/api-user/auth/refresh`.

## Изменения API

**До publish:** если меняешь сигнатуру эндпоинта (убираешь поле, переименовываешь, меняешь тип) — это **breaking change**. Объявление за 48 часов в канале `#разработка` на https://team.rublox.pro.

Записывай в `API_CHANGELOG.md` админ-репо (приватный, `minecraftia-school.ru/...`) — это позволяет отследить какие изменения когда были.

## Что делать если эндпоинт пропал

1. Открой issue в репо плеера: «API endpoint /xxx not found».
2. Прикрепи console-лог с ошибкой.
3. Кто-то из core-команды посмотрит в `API_CHANGELOG.md` админ-репо и ответит — это было умышленное изменение или баг.

## Контакты

- Issue tracker: https://git.rublox.pro/rublox/player/issues
- Чат: `#разработка` на https://team.rublox.pro
