Архитектура верхнего уровня

NOTE

Статус: Target design. Документ описывает целевую архитектуру. Сервисы, модули и контракты, упомянутые ниже, могут ещё не существовать в backend/. Правила маркировки — в 50-processes/documentation-standard.md.

Компоненты системы и потоки данных.

Компонентная схема

┌────────────────────────────────────────────────────────────────────┐
│                     ВНЕШНИЕ ИСТОЧНИКИ                              │
│   [ETM API]        [Supplier B]        [Supplier C]        ...     │
└────────────────────────────────────────────────────────────────────┘
                 │                  │                  │
                 ▼                  ▼                  ▼
┌────────────────────────────────────────────────────────────────────┐
│  CONNECTORS (целевые модули в backend/internal/connectors/*)       │
│  • Плагины к ядру, реализующие connector.Connector                 │
│  • Rate Limiter (Redis), Session Manager, Async Job Poller         │
└────────────────────────────────────────────────────────────────────┘
                              │
                              ▼
                     ┌──────────────────┐
                     │  KAFKA           │
                     │  raw.*           │
                     └──────────────────┘
                              │
              ┌───────────────┼──────────────────┐
              ▼               ▼                  ▼
    ┌──────────────┐  ┌──────────────┐  ┌─────────────────────┐
    │  S3 / MinIO  │  │ NORMALIZE    │  │  CLICKHOUSE PIPELINE│
    │  raw.payload │  │ service      │  │  history (price/stk)│
    └──────────────┘  └──────────────┘  └─────────────────────┘
                              │
                              ▼
                     ┌──────────────────┐
                     │  KAFKA           │
                     │  offer.*         │
                     └──────────────────┘
                              │
                              ▼
                     ┌──────────────────┐
                     │  MATCHING        │
                     │  rules + ML/LLM  │
                     └──────────────────┘
                              │
                              ▼
                     ┌─────────────────────────────────────────┐
                     │  KAFKA                                  │
                     │  canonical.events.v1                    │
                     │  supplier.graph.events.v1               │
                     │  enrichment.job.events.v1               │
                     │  estimate.events.v1                     │
                     └─────────────────────────────────────────┘
                              │
              ┌───────────────┼──────────────────┐
              ▼               ▼                  ▼
  ┌────────────────┐  ┌──────────────┐  ┌──────────────────┐
  │  POSTGRESQL    │  │  ENRICHMENT  │  │  ELASTICSEARCH   │
  │  primary store │  │  service     │  │  search index    │
  │  event_store   │  └──────────────┘  └──────────────────┘
  │  outbox        │  ┌──────────────────────────────┐
  └────────────────┘  │ SUPPLY-CHAIN RECALCULATOR    │
                      │ (consumer of supplier.graph) │
                      └──────────────────────────────┘
           │
           ▼
┌────────────────────────────────────────────────────────────────────┐
│  CORE APPLICATION SERVICES (Go)                                    │
│  • catalog-core  • search  • pricing  • meta-search                │
│  • visibility    • normalization                                   │
└────────────────────────────────────────────────────────────────────┘
           │
           ▼
┌────────────────────────────────────────────────────────────────────┐
│  PUBLIC-API SERVICE (multi-protocol)                               │
│  ┌────────────────┐  ┌────────────────┐  ┌────────────────────┐    │
│  │ REST (ServeMux)│  │ RPC (Connect)  │  │ WS (coder/websocket)│   │
│  └────────────────┘  └────────────────┘  └────────────────────┘    │
│  Применяет Visibility Policy, freshness markers, EnrichmentJob     │
└────────────────────────────────────────────────────────────────────┘
           │
           ▼
┌────────────────────────────────────────────────────────────────────┐
│  CLIENTS                                                           │
│  • Customer Web/Mobile UI       — REST + WS                        │
│  • B2B integrations             — gRPC                             │
│  • Admin UI (Next.js + Hero UI) — REST к admin-api (отдельно)      │
└────────────────────────────────────────────────────────────────────┘

Ключевые потоки

Поток 1: Ingestion от поставщика

Scheduler tick
    → RateLimiter.acquire(supplier_id)
    → Connector.fetch()
    → produce(raw.supplier.<name>.payload)
    ↓
Parser/Normalizer consume
    → save raw to S3
    → parse → SupplierOffer (pre-match)
    → persist in PG (offers table)
    → produce(offer.normalized.v1)
    ↓
Matching Engine consume
    → lookup candidate canonical products (ES + PG)
    → apply rules + ML verification for low confidence
    → update offer.canonical_product_ref, match_confidence
    → produce(matching.decided.v1)
    ↓
If new canonical needed:
    Canonical Service
    → apply CanonicalCreated / CharacteristicAdded events
    → event_store + outbox → canonical.events.v1
    ↓
Projection workers:
    - PG projections (readmodels)
    - ES canonical index update
    - CH history

Поток 2: Мета-поиск / сборка сметы

User uploads estimate
    → parse lines (rule + LLM)
    → for each line:
        - search candidates (ES)
        - score & rank
        - fetch offers of top-N canonical
        - pricing engine(offer, context)
    → optimize (ILP / greedy)
    → produce breakdown + alternatives
    → persist estimate + version
    → response with explanation

Межсервисное взаимодействие внутри одного окружения

  • Все контейнеры и сервисы среды входят в общий docker-compose network tracium.
  • Синхронные вызовы между сервисами идут по internal HTTP/Connect endpoint’ам через DNS-имена контейнеров (catalog-core, pricing, search, postgres, kafka).
  • Host ports публикуются только для внешнего доступа разработчика, reverse proxy и операционной диагностики.
  • Асинхронная межсервисная коммуникация остаётся на Kafka topics.

Модули ядра (краткий перечень)

  • catalog-core — canonical products, characteristics, manufacturers, identity profiles.
  • offers — supplier offers, stock.
  • pricing — Price Rules, Pricing Engine.
  • search — абстракция поиска + ES connector.
  • matching — движок матчинга.
  • enrichment — AI-обогащение.
  • meta-search — сборка смет.
  • admin-api / public-api — HTTP endpoints.

Каждый модуль в ../30-services/<n>/ имеет свой README.

Внешние зависимости

  • PostgreSQL 15+ — primary store, event store, outbox.
  • Kafka — event bus + event sourcing distribution.
  • Elasticsearch 8+ — search.
  • ClickHouse — аналитика, история.
  • Redis — cache, rate limiter, locks.
  • S3 / MinIO — raw payloads, media.
  • Secret backend / KMS — backend для master key и локальных/production secret flows (Vault Transit допустим, но не обязателен).
  • OTel collector + backend (Grafana / Tempo / Loki).

Инструменты доставки

  • GitLab CI/CD — lint, docs build, compose validation, release jobs.
  • Quartz + GitLab Pages — web-публикация актуальной документации.
  • SemVer + Keep a Changelog + git-cliff — версия продукта и release notes.