iac/apps/ams-sync/ENDPOINTS.md

100 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Интерфейсы сервиса ams-sync
# Версия: 1.0.0
Документ описывает интерфейсную поверхность сервиса: потребляемый топик Kafka, входящий TCP-healthcheck, исходящие HTTP-запросы к внешним сервисам (Zitadel, sarex-backend) и обращения к БД.
> `ams-sync` — не backend-сервис с REST API, а утилита синхронизации: демон-потребитель Kafka (`run`) плюс набор CLI-команд (`migrate`/`sync`/`diff`). Публичного HTTP API у сервиса нет — единственный входящий сокет отвечает на healthcheck сырой строкой (не HTTP). Поэтому файла `openapi.yaml` для сервиса нет.
## Как устроено взаимодействие
Приложение построено по слоям (adapter → repository → usecase → controller). Исходящие вызовы к внешним сервисам выполняются через `requests` (`requests.Session` с ретраями на `5xx`), к БД — через `psycopg2`. Все HTTP-запросы идут с `verify=False` (без проверки TLS). Базовые хосты берутся из переменных окружения (см. `CONFIGURATION.md`): `ZITADEL_HOST`, `AUTH_HOST`, `USER_SERVER_HOST`.
Аутентификация исходящих запросов:
- **Zitadel** — заголовок `Authorization: Bearer <ZITADEL_SERVICE_ACCESS_TOKEN>` (service-токен из конфига). Для части операций дополнительно проставляется `x-zitadel-orgid`.
- **sarex-backend** — JWT, получаемый под админом (`AUTH_ADMIN_USERNAME`/`AUTH_ADMIN_PASSWORD`) через `POST api/token/`; кешируется и обновляется за 30 секунд до `exp`.
## Входящие интерфейсы
### TCP Healthcheck
Только режим `run`. Сырой TCP-сокет (не HTTP): на каждое подключение отправляет строку `HEALTHCHECK_REPLY` (по умолчанию `healthy`) и закрывает соединение. Слушает `HEALTHCHECK_HOST:HEALTHCHECK_PORT` (по умолчанию `0.0.0.0:8008`). В Helm k8s-пробы настроены на TCP-порт `8008` (по умолчанию отключены).
### Kafka-потребитель
Топик — переменная `AMS_SYNC_TOPIC` (по умолчанию `ams-sync`). Параметры консьюмера (`src/internal/controller/sync_service/controller.py`):
| Параметр | Значение |
| --- | --- |
| `group_id` | `ams_sync_group` |
| `auto_offset_reset` | `earliest` |
| `enable_auto_commit` | `True` |
| десериализация | JSON (`utf-8`) |
Формат сообщения — объект с полями `type` и `body`. Диспетчеризация по `type`:
| `type` сообщения | Тело (`body`) | Обработчик | Действие |
| --- | --- | --- | --- |
| `model_created` | `SarexUserWithPermissions` | при `VERIFY_USERS=True``import_user` UC, иначе `user` UC `create` | Создание пользователя в Zitadel + запись метадаты |
| `model_updated` | `Metadata` | `user` UC `update_metadata` | Обновление метадаты существующего пользователя в Zitadel |
Сообщения без `type` или `body` пропускаются с предупреждением. Ошибки обработки логируются (traceback), сообщение не переотправляется (auto-commit включён).
## Исходящие HTTP-запросы
### Zitadel (`ZITADEL_HOST`)
Адаптеры `users/zitadel/adapter.py` и `organizations/adapter.py`. Итоговый URL = `<ZITADEL_HOST>` + путь.
| Метод | Путь | Назначение |
| --- | --- | --- |
| POST | `/v2/users/new` | Создать пользователя (human) |
| POST | `/management/v1/users/human/_import` | Импортировать пользователя (заголовок `x-zitadel-orgid`) |
| POST | `/admin/v1/import` | Массовый импорт пользователей (bulk, с таймаутом) |
| POST | `/v2/users` | Поиск пользователей (по username / email / org) |
| GET | `/management/v1/users/{id}` | Получить пользователя по id |
| GET | `/management/v1/users/{id}/metadata/{key}` | Получить метадату пользователя по ключу |
| POST | `/v2/users/{id}/metadata` | Массово задать метадату пользователя (значения в base64) |
| POST | `/v2/users/{id}/deactivate` | Деактивировать пользователя |
| DELETE | `/v2/users/{id}` | Удалить пользователя |
| POST | `/v2/organizations/_search` | Найти организацию по имени |
> Пути `/v2/...` частично захардкожены в адаптере, часть базовых путей управляется `ZITADEL_USERS_MANAGEMENT_ENDPOINT` (`management/v1/users`) и `ZITADEL_USERS_ENDPOINT` (`v2/users`). Методы грантов (`grants/adapter.py`) в текущей версии закомментированы.
### sarex-backend — авторизация (`AUTH_HOST`)
Адаптер `auth/http/adapter.py`.
| Метод | Путь | Назначение |
| --- | --- | --- |
| POST | `{AUTH_AUTH_ENDPOINT}` (по умолчанию `api/token/`) | Получить JWT по логину/паролю админа. Возвращает поле `access` |
### sarex-backend — сервис пользователей (`USER_SERVER_HOST`), только CLI
Адаптер `users/http/adapter.py`. Сессия с ретраями на `500/502/503/504` (до 5 попыток).
| Метод | Путь | Назначение |
| --- | --- | --- |
| GET | `{USER_SERVER_USERS_ENDPOINT}/{user_id}/metadata` (по умолчанию `api/core/admin/users/{user_id}/metadata`) | Получить метадату пользователя sarex для синхронизации в Zitadel |
## Обращения к БД sarex-backend (`USER_DB_*`), только CLI
Репозитории `repository/users` и `repository/companies` читают данные напрямую из PostgreSQL sarex-backend (только чтение, серверный курсор `itersize`).
| Операция | Таблицы | Назначение |
| --- | --- | --- |
| Пользователь по id | `base_baseuser` | `migrate --user-id` / `sync --user-id` |
| Все пользователи (итерация) | `base_baseuser` | `migrate` / `sync` / `diff` (bulk) |
| Пользователи компании | `core_companyuser``base_baseuser` | `sync --company-id` (только с непустым email) |
| Компания по id / имени | `core_company` | Вспомогательные запросы |
## Внешние зависимости (инфраструктура)
| Зависимость | Режим | Назначение |
| --- | --- | --- |
| Kafka | `run` | Источник событий пользователей (топик `AMS_SYNC_TOPIC`) |
| Zitadel (AMS) | `run` + CLI | Целевая система управления доступом (создание/обновление/удаление пользователей и метадаты) |
| sarex-backend (auth) | `run` + CLI | Получение JWT под админом |
| sarex-backend (user server) | CLI | Источник метадаты пользователя |
| PostgreSQL sarex-backend | CLI | Источник пользователей и компаний для миграции/синхронизации |