DKC connector

backend/internal/core/ingestion/infra/dkc — четвёртый адаптер supplier-connector контракта (ADR-0024). Первый поставщик с cursor-based incremental sync (revision_number) — закрыт в Cycle 4 (DKC adapter + federated taxonomy, ADR-0050, CLOSED 2026-05-02).

Работает через CursorPipeline (см. pipelines.md), а не bulk. ETIM-7 dictionary импортируется через taxonomy BC. Multi-currency RUB + KZT.

Transport + endpoints

REST/JSON. Endpoints под /v1/:

PathPurpose
POST /v1/auth.access.token/{master_key}Обмен master_key на per-request bearer (TTL 24h, см. cache)
GET /v1/revisions/lastТекущая revision_number (cursor anchor)
GET /v1/revisions/last/sizeРазмер delta для UI hints
GET /v1/revisions/materials?since={rev}Список изменившихся material’ов с заданной revision
GET /v1/catalog/material/{id}Полный material descriptor
GET /v1/catalog/material/{id}/retailPriceРозничная цена (RUB)
GET /v1/catalog/material/{id}/price/kztЦена в тенге
GET /v1/catalog/material/{id}/stocksОстатки по складам
GET /v1/etim/classes, /v1/etim/features, /v1/etim/values, /v1/etim/units, /v1/etim/artClassFeatureMapETIM-7 dictionary export
GET /v1/etim/productFeatureProduct-level ETIM features

Все data-plane запросы несут ?accessToken=<token> в query.

Auth

AuthSchemeMasterKey в cabinet supplier_catalog: customer вводит master_key (выдаётся DKC после подписания соглашения, ротируется раз в 90 дней). Backend хранит как secret JSON {master_key}.

SessionManager делает POST /v1/auth.access.token/<master_key> → получает per-request accessToken с 24h TTL → кэширует в Redis (tracium:dkc:token:<credential_ref>). На каждый Fetch добавляет ?accessToken= в query.

При 401 на data-plane запрос — single retry после re-auth.

Capabilities (dkc/capabilities.go)

AxisValue
TransportREST
Catalog + Characteristics + Prices + Stocktrue
IncrementalSync.Kindrevision_based (revision_number)
ScheduledRefresh (все оси)incremental
MultiCurrencyRUB + KZT (separate endpoints, ParallelCurrencyFetch=false)
Taxonomies.SupportedStandardsETIM-7
Taxonomies.NativeCodingfalse
Taxonomies.ExportsDictionarytrue (DKC публикует ETIM dictionary целиком)

IncrementalSync.Supported=true ⇒ orchestrator маршрутизирует DKC через CursorPipeline (не bulk).

Cursor flow

  1. Read supplier_sync_cursor для dkclast_revision.
  2. GET /v1/revisions/materials?since=last_revision → список changed material IDs.
  3. Per-material: fetch metadata + prices (RUB + KZT) + stocks.
  4. Persist через CursorObservationWriter (write-side identity attribution).
  5. Update supplier_sync_cursor.last_revision к new_revision.

При initial seed (last_revision=null) используется bulk_snapshot_source.go как fallback (один раз для bootstrap).

Federated taxonomy

DKC — первый поставщик-публикант ETIM-7 dictionary. taxonomy BC (см. ../../taxonomy/README.md) импортирует /v1/etim/classes/features/values/units через background job. Manual-protection: canonical_external_identities с locked_by_moderator_at сохраняет ручные правки модератора при re-import.

Auto-classification (LLM-присвоение ETIM-class по canonical assignments) — следующий cycle, infra ready.

Multi-currency (RUB + KZT)

  • DKC отдаёт цену в RUB через /v1/catalog/material/{id}/retailPrice.
  • Цена в KZT — отдельный endpoint /v1/catalog/material/{id}/price/kzt.
  • ParallelCurrencyFetch=false — pipeline делает два последовательных запроса.
  • Конверсия в proposal pipeline через exchange BC (ADR-0042, P6) — RUB как pivot.

Roadmap

  • Auto-classification — LLM-присвоение ETIM-class на основе canonical assignments (infra ready post Cycle 4).
  • Soft-delete classes в taxonomy при re-import — Importer.MarkInactive TODO-маркер.

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