# Контракт API платформы (черновик для бэкенда)

Наш API, спроектирован с нуля. К эндпоинтам halleg не привязан: отчёты переезжают целиком, halleg выводится из эксплуатации.
Из halleg взяты только слаги отчётов и список того, какие данные каждому отчёту нужны (`reports.json → data_needs`).

Статус: моки для демки. Примеры ответов в `examples/`, они же данные фронтенда. Когда бэкенд другой команды подключится,
этот файл становится заданием: форма ответов согласована, меняется только источник.

## Общее

- Все ответы JSON, кодировка UTF-8, даты ISO 8601 с таймзоной. Рабочая таймзона данных IST (Asia/Kolkata), как в каноне метрик.
- Аутентификация: сессионная cookie после SSO (Google Workspace, вопрос 1 к CTO) или логин-пароль (резерв, вопрос 2). В моках сессия = выбранный пользователь.
- **Права проверяет бэкенд на каждом вызове данных.** Фронт скрывает недоступное, но это удобство, а не защита.
- Ошибки: `401` нет сессии, `403` нет права на отчёт, `404` нет такого отчёта или метрики. Тело `{ "error": "forbidden", "report": "trader-kpi" }`.
- Подписи приходят на трёх языках (`name.en/uk/ru`), язык выбирает фронт. Данные отчётов не переводятся.

## Эндпоинты

### Сессия и права

| Метод и путь | Что отдаёт | Пример |
|---|---|---|
| `GET /api/v1/me` | текущий пользователь, отдел, роли и **итоговый список доступных отчётов** (объединение по ролям) | `examples/me.json` |
| `POST /api/v1/logout` | завершение сессии | |

Единственный источник правды о правах для фронта. Каталог, навигация и кнопки экспорта строятся из `me.reports`.

### Каталог

| Метод и путь | Что отдаёт | Пример |
|---|---|---|
| `GET /api/v1/reports` | все отчёты, **доступные текущему пользователю**, с группой, отделом, подписями, флагом `admin_only` | `examples/reports.json` |
| `GET /api/v1/reports/{slug}` | карточка отчёта: то же плюс `metrics` (id метрик) и `legend_notes` | `examples/report-trader-operational.json` |
| `GET /api/v1/reports/{slug}/data?…` | данные отчёта. Параметры зависят от отчёта. Для `parametrized` ролей бэкенд сам подставляет текущего пользователя | не мокается на этом шаге |
| `GET /api/v1/reports/{slug}/export?format=xlsx&…` | выгрузка. Те же права и те же фильтры, что у данных. Формируется на сервере | |

Экспорт идёт через бэкенд, не собирается из DOM. Пока прав внутри отчёта нет, правило одно: нет доступа к отчёту, нет и выгрузки.
Когда появятся права на колонки, серверный экспорт их соблюдёт без переделки фронта.

### Реестр метрик

| Метод и путь | Что отдаёт | Пример |
|---|---|---|
| `GET /api/v1/metrics?q=&status=&report=` | список метрик. `q` ищет по `name` и `synonyms` («Налив» → PayIn Volume). `report` даёт легенду отчёта | `examples/metrics.json` |
| `GET /api/v1/metrics/{id}` | полная запись: определение, формула, единицы, синонимы, где используется, отклонения, примечания, версии | `examples/metric-payin-volume.json` |
| `GET /api/v1/metrics/{id}/versions` | история определений | |
| `PUT /api/v1/metrics/{id}` | новая версия определения. Право `can_edit_metrics`. Тело без `definition` отклоняется | |

Подсказка у числа в отчёте это `GET /api/v1/metrics/{id}`, отрисованная коротко. Легенда отчёта это `GET /api/v1/metrics?report={slug}`.
Оба читают одну запись, расхождений между тремя представлениями быть не может.

### Администрирование доступа

| Метод и путь | Что отдаёт | Пример |
|---|---|---|
| `GET /api/v1/admin/access-matrix` | матрица «роль × отчёт» и список отделов | `examples/access-matrix.json` |
| `GET /api/v1/admin/users` | пользователи с отделом, ролями, статусом | `examples/admin-users.json` |
| `PUT /api/v1/admin/users/{id}/roles` | назначить роли. Пишет `AccessGrant` | |
| `POST /api/v1/admin/users/{id}/block` | ручная блокировка «сейчас» | |
| `PUT /api/v1/admin/roles/{id}` | набор отчётов роли | |
| `GET /api/v1/admin/access-log?user=&report=` | журнал выдачи прав | |

Все с правом `can_manage_access`.

### Статистика использования

| Метод и путь | Что отдаёт |
|---|---|
| `GET /api/v1/admin/usage?from=&to=&group_by=report|user|day` | посещения и уникальные пользователи |

Пишется тем же middleware, что проверяет права. Историю с halleg просим одной выгрузкой, чтобы дашборд не стартовал с пустого экрана.

### Интеграция с CRM (входящие)

| Метод и путь | Что делает |
|---|---|
| `POST /api/v1/hooks/crm/employee` | событие `terminated` → `blocked`; `transferred` → снять роли старого отдела, поставить роль по умолчанию нового |

Поле сопоставления сотрудника (почта или табельный номер) и задержка CRM: вопросы 6 и 7 к CTO.

## Что здесь не решено

- Форма `…/data` для каждого отчёта. Список потребностей в `reports.json → data_needs`, сами ответы halleg мы не видели (запрошены примеры).
- Способ идентификации сессии после SSO.
- Пагинация в `metrics` и `admin/users`: при 106 пользователях и ~90 метриках пока не нужна.
