# Distribution API (ПИ) **ПИ** — не отдельный Docker-сервис, а внешний HTTP-срез поверх данных ЦА. Общий контекст: [docs/architecture-overview.md](../../docs/architecture-overview.md). --- ## Общими чертами 1. В UI «ПИ» (`/consumers`) создаётся подписчик. 2. Ему выдаётся API-ключ (в БД хранится только SHA-256 hash). 3. Клиент читает события: ```http GET /api/v1/events Authorization: Bearer ``` 4. ЦА отдаёт события с учётом фильтров consumer (регионы, темы, дата). ```mermaid flowchart LR Client[External system] V1[GET /api/v1/events] Cons[Consumer + Filter] Events[(events)] Client -->|Bearer key| V1 V1 --> Cons Cons --> Events ``` --- ## Подробнее ### Код | Часть | Путь | |-------|------| | Роут | `centers/analytics/api/app/routers/v1.py` | | Модели | `Consumer`, `ConsumerFilter` в `models.py` | | Фильтрация | `services/filtering.py` | | Admin CRUD | `routers/admin.py` — `/admin/consumers`, `…/rotate-key` | | UI | `frontend/src/views/ConsumersView.vue` | | Seed | `seed.py` — consumer `test-pi` из `TEST_PI_API_KEY` | ### Аутентификация - Заголовок: `Authorization: Bearer `. - Сравнение с `consumers.api_key_hash` (SHA-256). - Неактивный consumer → отказ. ### Фильтры подписчика Типичные ограничения (через `ConsumerFilter`): - список регионов; - список тем; - `date_from` (нижняя граница даты события). Точный набор полей — в модели/схемах admin API; при изменении фильтров обновляйте UI consumers и `filtering.py`. ### Admin операции | Метод | Путь | Действие | |-------|------|----------| | GET | `/admin/consumers` | Список | | POST | `/admin/consumers` | Создать (+ ключ в ответе один раз) | | PATCH | `/admin/consumers/{id}` | Обновить | | POST | `/admin/consumers/{id}/rotate-key` | Новый ключ | ### Локальный тест После `docker compose up` (если не меняли seed): ```bash curl -s -H "Authorization: Bearer test-pi-api-key-change-me" \ "http://localhost:8080/api/v1/events" | head ``` В проде обязательно смените `TEST_PI_API_KEY` и ротируйте ключи. ### Что ПИ не делает - не пишет в БД; - не ставит parse jobs; - не ходит в Redis / ЦП. Только чтение уже ingest'нутых событий через контракт `/api/v1`.