Административный API

NOTE

Статус: Mixed (HEAD 5e4ce54, 2026-05-06). Большая часть admin-сценариев уже live в виде handler’ов в соответствующих BC под нерасстроенным namespace. Отдельного admin-api runtime’а нет — 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
taxonomyadmin_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’ов

  1. Все новые admin handlers регистрируются только под /api/v1/admin/<bc>/....
  2. Соответствующая операция добавляется в admin-api.openapi.yaml и переносится из target spec’и.
  3. 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") — nginx auth_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-offersoffers
Credentials (system pool)/api/v1/admin/credentials/*credentials
Customer api-keys/api/v1/admin/customers/{id}/api-keyscabinet/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 varDefaultОписание
ADMIN_API_HTTP_PORT8080HTTP-порт
ADMIN_API_AUTH_OIDC_ISSUEROIDC issuer URL
ADMIN_API_AUTH_REQUIRED_ROLESadmin,moderator,securityроли для доступа
ADMIN_API_AUDIT_SAMPLING1.0доля запросов, попадающих в audit

Локальный запуск

Отдельного процесса admin-api в репозитории нет — admin-handler’ы живут в общем api-server’е. Доступны через тот же контур:

make local-prod-up

Frontend 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 строго проверяет paritet admin-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.

Связанные документы