# Интерфейсы сервиса 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 ` (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 = `` + путь. | Метод | Путь | Назначение | | --- | --- | --- | | 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 | Источник пользователей и компаний для миграции/синхронизации |