Административный API
NOTE
Статус: Mixed (HEAD
5e4ce54, 2026-05-06). Большая часть admin-сценариев уже live в виде handler’ов в соответствующих BC под нерасстроенным namespace. Отдельногоadmin-apiruntime’а нет — admin-handlers регистрируются в общий api-server’е через GroupRegistrar’ы соответствующих BC. См. секцию «Routing convention» ниже.
Этот README описывает зонтичный admin-API контракт Tracium. Читайте его, когда нужно понять, под каким префиксом живут admin-handler’ы, как они авторизуются и где искать их в коде.
Назначение
HTTP API для административного UI и внутренних операторских сценариев: модерация, управление dictionary, коннекторами, price rules, credentials и visibility policies.
Статус документа
- Тип знания:
current service(без выделенного runtime’а — admin handlers живут в api-server’е через BC GroupRegistrar’ы) - Статус реализации: ~30+ admin endpoint’ов реализовано в catalog / cabinet/apikeys / credentials / matching / taxonomy. Roadmap-фактическая реализация идёт BC-by-BC, под двойным префиксом (
/admin/*legacy +/api/v1/admin/*canonical). - Текущее место кода:
backend/internal/core/*/api/http/*_admin_handler.go+backend/internal/core/cabinet/apikeys/api/http/admin/registrar.go+backend/internal/core/credentials/api/http/handler.go::RegisterAdmin+backend/internal/core/taxonomy/api/http/admin_handler.go+backend/internal/core/matching/api/http/moderation_handler.go. - Что читать дальше: интерактивный контракт — Swagger UI (переключатель Public / Admin), исходники —
../../20-architecture/schemas/api/index.md,../../20-architecture/schemas/api/admin-api.openapi.yaml(AS-SHIPPED, строго линтуется),admin-api-target.openapi.yaml(TARGET, design-reference),../public-api/README.md,../../20-architecture/adr/INDEX.md.
Routing convention (transition state, 2026-05-06)
Admin endpoints на 2026-05-06 живут под двумя параллельными префиксами:
| Префикс | Назначение | Статус |
|---|---|---|
/api/v1/admin/<bc>/... | Canonical — целевой namespace, документируется в admin-api.openapi.yaml, строго линтуется CI-job backend-openapilint | новый, активно растёт |
/admin/<bc>/... (без /api/v1/) | Legacy — внутренний admin UI (frontend web/admin/) и сторонние интеграции | deprecated for new code; существующие routes сохраняются для совместимости |
Многие handler’ы регистрируют оба alias’а на один и тот же http.HandlerFunc для плавной миграции UI:
// backend/internal/core/catalog/canonical/api/http/dispute_moderation_handler.go
mux.Handle("GET /admin/dispute-moderation", auth(handler))
mux.Handle("GET /api/v1/admin/canonical/dispute-moderation", auth(handler))Часть BC ещё не мигрировала на /api/v1/admin/* (только legacy):
| BC | Файл | Замечание |
|---|---|---|
catalog/canonical (trust suppliers) | trust_admin_handler.go | только /admin/trust/* |
catalog/characteristic (policy) | policy_admin_handler.go | только /admin/characteristics/{id}/policy |
catalog/units (dimensions) | dimension_admin_handler.go | только /admin/units + /admin/units/{id}/dimension |
taxonomy | admin_handler.go + canonical_identity_handler.go | весь BC, /admin/taxonomy/* + /admin/canonical/{id}/external-identities |
Эти routes не отражены в admin-api.openapi.yaml (lint их игнорирует через skipping route with unknown prefix). При расширении BC миграция — отдельная задача.
Правило для новых endpoint’ов
- Все новые admin handlers регистрируются только под
/api/v1/admin/<bc>/.... - Соответствующая операция добавляется в
admin-api.openapi.yamlи переносится из target spec’и. make backend-openapilintобязан пройти локально перед merge.
Область действия
Входит:
- Endpoints для административных операций.
- Модерация очередей и ручных решений.
- Управление dictionary, price rules, credentials и visibility policies.
- Search explain API и служебные сценарии для операторов.
Не входит:
- Клиентские внешние endpoints.
- Бизнес-логика ядра:
admin-apiвызывает соответствующие внутренние сервисы, а не дублирует их.
Публичный контракт
Вход
- HTTP:
/api/v1/admin/...(canonical) + legacy/admin/...(см. routing convention выше). Источник истины —../../20-architecture/schemas/api/admin-api.openapi.yaml. - Авторизация через JWT-cookie (system role +
aud:"system") — nginxauth_requestк auth-service. Bearer-токеныtrk_*для admin не принимаются.
Реализованные группы endpoints (HEAD 5e4ce54):
| Группа | Префикс | BC |
|---|---|---|
| Canonical products + assignments | /api/v1/admin/catalog/canonical-products/* | catalog/canonical |
| Disputes + moderation | /api/v1/admin/canonical/disputes/*, /api/v1/admin/canonical/dispute-moderation/* | catalog/canonical |
| Characteristics, manufacturers, units | /api/v1/admin/catalog/(characteristics|manufacturers|units)/* | catalog/{characteristic,manufacturer,unit} |
| Charnorm characteristics | /api/v1/admin/charnorm/characteristics/* | catalog/canonical |
| Matching moderation | /api/v1/admin/matching/moderation/* | matching |
| Offers read | /api/v1/admin/offers/supplier-offers | offers |
| Credentials (system pool) | /api/v1/admin/credentials/* | credentials |
| Customer api-keys | /api/v1/admin/customers/{id}/api-keys | cabinet/apikeys (D14) |
Legacy-only (см. таблицу в Routing convention): trust, characteristic policy, unit dimensions, taxonomy.
Admin UI /canonical показывает для canonical products две временные метки:
created_at как момент первого появления canonical product в базе и
updated_at как последнее обновление read model.
Примечание по canonical analogs: если embedding-вектор у якорного товара еще
не построен или embedding-gateway недоступен, admin analogs endpoint деградирует
в rule/text/facts ranking вместо 503 embedding_pending. Такой ответ помечается
fallback model id и остается пригодным для операторской проверки аналогов во
время первичного наполнения каталога.
Roadmap (target spec, не реализовано): identity-profiles, visibility-policies, price-rules, plans, search explain, organizations.
Выход
- Вызовы во внутренние сервисы каталога, поиска, pricing, matching, visibility и ingestion.
- Аудитные записи и доменные события через outbox/Kafka в целевом состоянии.
Внутренняя архитектура
В целевом состоянии это тонкий orchestration-слой над внутренними сервисами и доменными модулями. Он отвечает за авторизацию, аудит, маршрутизацию административных команд и чтение агрегированных административных представлений.
Сейчас отдельная реализация отсутствует; ориентир по раскладке модулей — ../../20-architecture/module-layout.md.
Зависимости
- Все ядерные сервисы: catalog, search, pricing, matching, visibility, ingestion.
- PostgreSQL для управляющих таблиц и аудита.
- Kafka/outbox для событий и аудита.
- OIDC issuer для административной авторизации.
Хранилище
- Читает и пишет управляющие таблицы, связанные с dictionary, credentials, policy и moderation.
- Точный состав схем должен фиксироваться в
20-architecture/schemas/по мере появления реализации.
Конфигурация
Целевые переменные окружения:
| Env var | Default | Описание |
|---|---|---|
ADMIN_API_HTTP_PORT | 8080 | HTTP-порт |
ADMIN_API_AUTH_OIDC_ISSUER | — | OIDC issuer URL |
ADMIN_API_AUTH_REQUIRED_ROLES | admin,moderator,security | роли для доступа |
ADMIN_API_AUDIT_SAMPLING | 1.0 | доля запросов, попадающих в audit |
Локальный запуск
Отдельного процесса admin-api в репозитории нет — admin-handler’ы живут в общем api-server’е. Доступны через тот же контур:
make local-prod-upFrontend admin UI — web/admin/ (Next.js); поднимается через тот же контур, доступен на https://admin.tracium.dev:4444.
Тестирование
- Unit + integration:
go test ./internal/core/{catalog,cabinet,credentials,matching,offers,taxonomy}/api/http/...(с-tags=integrationдля PG). - Contract:
make backend-openapilintстрого проверяет paritetadmin-api.openapi.yaml↔ зарегистрированныхmux.Handle*в коде. - Frontend admin tests:
cd web/admin && pnpm vitest run. - Общая стратегия — в
../../50-processes/testing-strategy.md.
Наблюдаемость
В целевом состоянии сервис должен публиковать метрики с префиксом admin_api_, включая:
admin_api_requests_total{endpoint,status,role}admin_api_moderation_decisions_total{type,decision}admin_api_break_glass_requests_total{stage}
Сейчас доступны только базовые логи compose-окружения и health/readiness минимального API.
Открытые вопросы / TODO
- Migrate legacy
/admin/*→/api/v1/admin/*для trust/policy/units-dimension/taxonomy. Включить вadmin-api.openapi.yaml. Удалить legacy alias после migration UI consumers. - Identity-profiles — admin CRUD над
IdentityProfile(ADR-0007). - Visibility policies admin CRUD — сейчас в
discovery/visibility/infra/http/, expose под admin spec’ом. - Price-rules admin CRUD — pricing BC handlers.
- Audit-events + retention — после ship’а audit BC.