Files
dzentra_bot/docs/migrations/build_060_10.md

32 KiB
Raw Blame History

Build 060.10 — WebSocket Trade Schema Validation

Engineering Migration Report


Контроль документа

Свойство Значение
Build 060.10
Название WebSocket Trade Schema Validation
Статус Completed
Проект Dzentra
Подсистема Market Data Acquisition
Компонент Trades Feed
Версия 1.0

Цель Build

После завершения Build 060.9 система получила транспортную модель WebSocket Trade (DzengiWebSocketTradeEvent), описывающую одно событие биржи на транспортном уровне.

Следующим обязательным этапом развития WebSocket-конвейера является реализация слоя структурной проверки входящих сообщений.

Build 060.10 вводит механизм Schema Validation для сообщений Dzengi WebSocket канала internal.trade.

Основная задача Build — гарантировать, что последующие этапы обработки получают структурно корректный документ, содержащий все обязательные элементы транспортного контракта.

Данный Build ограничивается исключительно проверкой структуры сообщения и не затрагивает:

  • Parser;
  • Value Validation;
  • Mapper;
  • Adapter;
  • Runtime;
  • Routing;
  • Trades Feed.

Предпосылки

К моменту начала Build архитектура Dzentra уже содержала завершённые уровни Schema Validation для остальных типов WebSocket-событий.

WebSocket Quote

Raw WebSocket Quote
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketQuoteDocument
        │
        ▼
Quote Parser

WebSocket OHLC

Raw WebSocket OHLC
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketOhlcDocument
        │
        ▼
OHLC Parser

После завершения Build 060.9 появилась транспортная модель:

DzengiWebSocketTradeEvent

Однако между необработанным JSON-документом и Parser отсутствовал слой, отвечающий за структурную проверку сообщения.

В результате WebSocket-конвейер обработки сделок оставался незавершённым и отличался от уже реализованных конвейеров Quote и OHLC.


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

В архитектуре Dzentra каждый уровень Pipeline имеет строго определённую область ответственности.

Schema Validation располагается между транспортным JSON-документом и Parser и отвечает исключительно за проверку структуры сообщения.

На данном уровне выполняется:

  • проверка структуры корневого объекта;
  • проверка обязательных элементов транспортной оболочки;
  • проверка структуры объекта payload;
  • проверка наличия обязательных полей транспортного события.

Schema Validation принципиально не выполняет:

  • преобразование типов;
  • преобразование числовых значений;
  • проверку диапазонов;
  • проверку бизнес-семантики;
  • создание транспортной модели;
  • преобразование в каноническую модель Trade.

Такое разделение позволяет каждому уровню Pipeline выполнять одну строго определённую задачу и исключает смешивание ответственности между компонентами.


Результаты архитектурного аудита

Перед началом реализации был выполнен аудит существующей подсистемы Validation.

Подтверждено наличие полностью реализованных компонентов:

  • ValidatedWebSocketQuoteDocument;
  • ValidatedWebSocketOhlcDocument;
  • validate_dzengi_websocket_quote_schema();
  • validate_dzengi_websocket_ohlc_schema().

Также подтверждено существование полной иерархии ошибок обработки Trade:

  • TradeTransportError;
  • TradeSchemaError;
  • TradeParseError;
  • TradeValueError;
  • TradeMappingError.

Одновременно подтверждено отсутствие собственного уровня Schema Validation для WebSocket Trade.

Таким образом Build 060.10 полностью соответствует утверждённой дорожной карте серии 060 и закрывает второй этап WebSocket-ветки обработки сделок.


Архитектурное решение

По итогам аудита было принято решение не проектировать отдельную архитектуру для Trade.

Вместо этого реализован третий экземпляр уже существующего архитектурного шаблона.

В систему добавлены:

ValidatedWebSocketTradeDocument

validate_dzengi_websocket_trade_schema(...)

Архитектура всех WebSocket-конвейеров стала полностью симметричной.

Quote

Raw WebSocket
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketQuoteDocument

OHLC

Raw WebSocket
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketOhlcDocument

Trade

Raw WebSocket
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketTradeDocument

Build 060.10 не изменяет существующее поведение Quote и OHLC, а лишь расширяет существующую архитектуру новым типом рыночных данных.


Реализованный документ Schema Validation

В файл

src/market_data/acquisition/validation/schema.py

добавлен новый документ структурной проверки:

@dataclass(frozen=True, slots=True)
class ValidatedWebSocketTradeDocument:
    payload: Mapping[str, object]
    status: object
    destination: object
    correlation_id: object | None

Документ представляет собой неизменяемый результат успешной проверки структуры WebSocket-сообщения.

Экземпляр содержит:

  • транспортную оболочку сообщения;
  • неизменяемый payload;
  • статус сообщения;
  • назначение сообщения;
  • необязательный correlationId.

После создания объект используется исключительно последующими стадиями Pipeline и не предполагает модификации.


Почему используется отдельный документ Validation

ValidatedWebSocketTradeDocument не является транспортной моделью биржи.

Он представляет собой результат успешной структурной проверки входящего JSON-документа.

Документ:

  • не содержит бизнес-логики;
  • не преобразует данные;
  • не выполняет Parsing;
  • не выполняет Value Validation;
  • не выполняет Mapping;
  • не является канонической моделью Trade.

Его единственная задача — гарантировать Parser, что структура сообщения соответствует ожидаемому контракту.

Такое разделение полностью повторяет архитектурный подход, уже применяемый для Quote и OHLC.


Проверяемая структура WebSocket-документа

В рамках Build 060.10 реализована проверка исключительно структуры сообщения.

Ожидаемый контракт WebSocket-события имеет следующий вид:

{
    "status": "OK",
    "destination": "internal.trade",
    "payload": {
        "buyer": false,
        "id": 2134846831,
        "orderId": "00a02503-0079-54c4-0000-000081e62b58",
        "price": 64555.55,
        "size": 0.002,
        "symbol": "BTC/USD_LEVERAGE",
        "ts": 1784218012030
    }
}

Build 060.10 гарантирует наличие обязательных элементов данного контракта, но принципиально не анализирует их содержимое.


Проверяемые элементы транспортной оболочки

На уровне корневого документа выполняется проверка наличия обязательных полей:

status
destination
payload

Кроме того, проверяется, что сам корневой объект является JSON Mapping и содержит только строковые ключи.

Поле

correlationId

не является обязательным.

При наличии оно сохраняется в результирующем документе без какой-либо дополнительной обработки.

Следует отметить, что Build 060.10 проверяет наличие поля

destination

но не проверяет его значение.

В частности, валидатор не сравнивает содержимое поля со строкой

internal.trade

Подобная проверка относится не к структурной корректности сообщения, а к его семантике и поэтому не входит в область ответственности Schema Validation.

Такое разделение полностью соответствует архитектурному принципу Dzentra, согласно которому Schema Validation отвечает исключительно за структуру входящего документа, а не за интерпретацию его содержимого.


Проверяемые элементы payload

После успешной проверки транспортной оболочки выполняется проверка структуры объекта

payload

Payload обязан быть JSON Mapping.

Для объекта выполняется проверка строковых ключей и наличие обязательных элементов транспортного контракта.

Обязательными являются:

id
price
size
symbol
ts
buyer
orderId

Отсутствие любого из перечисленных полей приводит к генерации исключения

TradeSchemaError

с указанием отсутствующих элементов.


Проверка Mapping

Build 060.10 следует архитектурному правилу Dzentra:

любая структура JSON после прохождения Schema Validation должна представлять собой Mapping со строковыми ключами.

Поэтому реализованы две независимые проверки.

Первая проверяет корневой документ:

$

Вторая проверяет вложенный объект:

$.payload

В обоих случаях:

  • объект обязан быть Mapping;
  • каждый ключ обязан иметь тип str.

Подобный подход полностью совпадает с реализацией Quote и OHLC.


Использование MappingProxyType

После успешной проверки содержимое

payload

копируется в

MappingProxyType(dict(payload))

Таким образом создаётся неизменяемое представление транспортного документа.

Использование MappingProxyType решает сразу несколько задач.

Во-первых, предотвращается случайное изменение данных после завершения Schema Validation.

Во-вторых, исключается влияние внешнего кода на результаты проверки структуры.

В-третьих, последующие уровни Pipeline получают гарантированно неизменяемый документ.

Parser, Value Validation и Mapper могут безопасно использовать полученные данные, не опасаясь их изменения между этапами обработки.


Почему не используется транспортная модель

Build 060.10 принципиально не создаёт экземпляр

DzengiWebSocketTradeEvent

Это является обязанностью Parser.

Schema Validation лишь подтверждает корректность структуры сообщения.

Создание транспортной модели переносится на следующий Build.

Подобное разделение ответственности уже используется в существующих WebSocket-конвейерах Quote и OHLC.


Граница ответственности Build

Build 060.10 отвечает исключительно за структурную корректность документа.

В его обязанности входит:

  • проверка структуры корневого объекта;
  • проверка транспортной оболочки;
  • проверка структуры payload;
  • проверка обязательных полей;
  • формирование неизменяемого документа Validation.

Build не выполняет:

  • Parsing;
  • преобразование JSON в транспортную модель;
  • преобразование типов;
  • Decimal-конвертацию;
  • проверку диапазонов;
  • проверку timestamp;
  • проверку символа;
  • проверку стороны сделки;
  • Mapping;
  • создание канонической модели Trade.

Каждая из перечисленных задач относится к отдельному архитектурному уровню и будет реализована в следующих Build.


Использование TradeSchemaError

Для всех ошибок структуры используется уже существующее исключение

TradeSchemaError

Build не вводит новых типов исключений.

Это сохраняет единый подход ко всей подсистеме Validation и полностью соответствует существующей архитектуре обработки ошибок.


Целевой конвейер обработки WebSocket Trade

После завершения Build 060.10 конвейер обработки принимает следующий вид.

Raw WebSocket Object
        │
        ▼
WebSocket Trade Schema Validation
        │
        ▼
ValidatedWebSocketTradeDocument
        │
        ▼
Build 060.11 — WebSocket Trade Parser
        │
        ▼
DzengiWebSocketTradeEvent
        │
        ▼
Build 060.12 — WebSocket Trade Value Validation
        │
        ▼
Validated Trade Transport Event
        │
        ▼
Build 060.13 — WebSocket Trade Mapper
        │
        ▼
Trade

Таким образом Build 060.10 завершает второй архитектурный уровень WebSocket-конвейера обработки сделок.


Соотношение с транспортной моделью

Build 060.9 и Build 060.10 реализуют два различных архитектурных уровня.

Build 060.9

вводит транспортную модель

DzengiWebSocketTradeEvent

которая описывает уже разобранное WebSocket-событие.

Build 060.10

вводит документ

ValidatedWebSocketTradeDocument

который представляет собой результат проверки структуры исходного JSON-документа.

Таким образом последовательность обработки становится следующей.

Raw JSON
        │
        ▼
ValidatedWebSocketTradeDocument
        │
        ▼
DzengiWebSocketTradeEvent
        │
        ▼
Trade

Каждый объект относится к собственному архитектурному уровню и не дублирует ответственность другого.


Изменённые файлы

В рамках Build были изменены только два файла.

Schema Validation

src/market_data/acquisition/validation/schema.py

Добавлены:

ValidatedWebSocketTradeDocument

validate_dzengi_websocket_trade_schema(...)

_validate_websocket_trade_payload(...)

_require_websocket_trade_mapping(...)

При этом существующие валидаторы Quote и OHLC, импорты и поведение файла не изменялись.


Unit-тесты

tests/unit/market_data/acquisition/validation/test_websocket_trade_schema.py

Добавлен полный набор unit-тестов нового уровня Schema Validation.


Добавленные тесты

В рамках Build реализовано двадцать unit-тестов, полностью покрывающих функциональность нового валидатора.

Проверка успешной валидации

Тест

test_validate_websocket_trade_schema_returns_immutable_document

проверяет:

  • успешную проверку корректного документа;
  • создание ValidatedWebSocketTradeDocument;
  • использование MappingProxyType;
  • сохранение обязательных полей.

Проверка correlationId

Тест

test_validate_websocket_trade_schema_preserves_correlation_id

подтверждает корректное сохранение необязательного поля correlationId.


Проверка копирования payload

Тест

test_validate_websocket_trade_schema_copies_payload

подтверждает, что изменения исходного словаря после Validation не влияют на содержимое результирующего документа.


Проверка структуры корневого объекта

Тест

test_validate_websocket_trade_schema_rejects_non_mapping_root

подтверждает генерацию TradeSchemaError, если корневой объект не является JSON Mapping.


Проверка обязательных полей транспортной оболочки

Параметризованный тест

test_validate_websocket_trade_schema_rejects_missing_root_field

проверяет отсутствие:

  • status;
  • destination;
  • payload.

Проверка структуры payload

Тест

test_validate_websocket_trade_schema_rejects_non_mapping_payload

проверяет, что поле payload обязано быть JSON Mapping.


Проверка обязательных полей Trade

Параметризованный тест

test_validate_websocket_trade_schema_rejects_missing_payload_field

проверяет отсутствие каждого обязательного элемента:

  • id;
  • price;
  • size;
  • ts;
  • symbol;
  • buyer;
  • orderId.

Проверка сообщения об ошибке

Тест

test_validate_websocket_trade_schema_reports_all_missing_fields

подтверждает, что исключение содержит полный список отсутствующих полей.


Отсутствие проверки значений

Тест

test_validate_websocket_trade_schema_does_not_validate_values

подтверждает архитектурный принцип Build.

Schema Validation проверяет исключительно структуру и принципиально не анализирует содержимое полей.


Дополнительные поля

Тест

test_validate_websocket_trade_schema_allows_additional_fields

подтверждает, что неподтверждённые Production поля не вызывают ошибку Validation.

В частности проверяется возможность присутствия

clientOrderId

и других дополнительных элементов.


Проверка строковых ключей

Реализованы отдельные тесты проверки строковых ключей для:

  • корневого объекта;
  • объекта payload.

Это полностью соответствует архитектуре существующих WebSocket Schema Validation.


Результаты тестирования

Выполнен целевой запуск нового набора unit-тестов.

python -m pytest \
  tests/unit/market_data/acquisition/validation/test_websocket_trade_schema.py \
  -q

Результат:

20 passed in 0.02s

Все проверки новой функциональности успешно завершены.


Регрессионное тестирование

После завершения реализации выполнен полный запуск подсистемы Validation.

python -m pytest \
  tests/unit/market_data/acquisition/validation \
  -q

Результат:

302 passed in 0.10s

Регрессий существующей функциональности не обнаружено.


Проверка компиляции

Выполнена проверка компиляции изменённых файлов.

python -m compileall \
  src/market_data/acquisition/validation/schema.py \
  tests/unit/market_data/acquisition/validation/test_websocket_trade_schema.py

Компиляция завершилась успешно.

Синтаксические ошибки отсутствуют.


Проверка Git diff

Выполнена финальная проверка изменений.

git diff --check

Ошибок не обнаружено.

Это подтверждает отсутствие:

  • trailing whitespace;
  • конфликтов окончания строк;
  • ошибок форматирования diff.

Scope Build 060.10

В рамках данного Build реализовано только:

WebSocket Trade Schema Validation

Build не включает:

  • WebSocket Trade Parser;
  • WebSocket Trade Value Validation;
  • WebSocket Trade Mapper;
  • WebSocket Trade Adapter;
  • Runtime Integration;
  • Unified Routing;
  • Trades Feed.

Это полностью соответствует принципу атомарной реализации Build.


Архитектурный результат

После завершения Build система содержит завершённый уровень Schema Validation для всех поддерживаемых WebSocket-событий.

Quote

Raw WebSocket
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketQuoteDocument

OHLC

Raw WebSocket
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketOhlcDocument

Trade

Raw WebSocket
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketTradeDocument

Архитектура стала полностью симметричной.


Состояние WebSocket Trade Pipeline

После завершения Build 060.10 конвейер имеет следующий вид.

Raw WebSocket Trade Document
        │
        ▼
ValidatedWebSocketTradeDocument
        │
        ▼
Parser
        │
        ▼
DzengiWebSocketTradeEvent
        │
        ▼
Value Validation
        │
        ▼
Mapper
        │
        ▼
Trade

Статус реализации компонентов:

Компонент Build Статус
Canonical Trade Model 060.1 ✔ Completed
WebSocket Trade Transport Model 060.9 ✔ Completed
WebSocket Trade Schema Validation 060.10 ✔ Completed
WebSocket Trade Parser 060.11 Pending
WebSocket Trade Value Validation 060.12 Pending
WebSocket Trade Mapper 060.13 Pending
WebSocket Trade Adapter 060.14 Pending
Unified WebSocket Routing 060.15 Pending

Соблюдение архитектурных принципов

В рамках Build полностью сохранены архитектурные инварианты Dzentra.

Локальность изменений

Изменены только:

  • Schema Validation;
  • unit-тесты нового валидатора.

Повторное использование архитектуры

Новая реализация полностью повторяет существующий шаблон Quote и OHLC.

Новая архитектура не создавалась.


Разделение ответственности

Schema Validation отвечает исключительно за проверку структуры сообщения.

Parser, Value Validation, Mapper и Runtime остаются полностью независимыми уровнями.


Отсутствие бизнес-логики

Build не выполняет:

  • Parsing;
  • преобразование типов;
  • Value Validation;
  • Mapping;
  • Runtime Integration.

Это полностью соответствует архитектуре Dzentra.


Обратная совместимость

Существующая обработка Quote, OHLC и REST Trade не изменилась.

Новая функциональность добавлена изолированно и не влияет на ранее реализованные Build.


Критерии завершения Build

Build 060.10 считается завершённым, поскольку выполнены все поставленные задачи.

  • ✔ реализован ValidatedWebSocketTradeDocument;
  • ✔ реализована функция validate_dzengi_websocket_trade_schema();
  • ✔ проверяется структура транспортной оболочки;
  • ✔ проверяется структура payload;
  • ✔ проверяются обязательные поля Trade;
  • ✔ используется TradeSchemaError;
  • ✔ payload становится неизменяемым;
  • ✔ реализовано двадцать unit-тестов;
  • ✔ все целевые тесты успешно проходят;
  • ✔ регрессионное тестирование успешно завершено;
  • ✔ компиляция выполнена без ошибок;
  • git diff --check не выявил замечаний;
  • ✔ изменения не выходят за пределы согласованного scope.

Следующий этап

Следующим этапом дорожной карты является

Build 060.11 — WebSocket Trade Parser

Цель Build:

  • преобразование ValidatedWebSocketTradeDocument;
  • создание транспортной модели DzengiWebSocketTradeEvent;
  • нормализация имён транспортных полей;
  • преобразование JSON-ключей:
    • id → trade_id;
    • ts → timestamp;
    • orderId → order_id;
  • сохранение исходных числовых значений без преобразования типов;
  • отсутствие Value Validation.

После завершения Build 060.11 конвейер примет следующий вид:

Raw WebSocket Object
        │
        ▼
Schema Validation
        │
        ▼
ValidatedWebSocketTradeDocument
        │
        ▼
WebSocket Trade Parser
        │
        ▼
DzengiWebSocketTradeEvent

Build 060.11 по-прежнему не будет выполнять:

  • проверку диапазонов значений;
  • проверку корректности timestamp;
  • проверку корректности цены и объёма;
  • Mapping в каноническую модель Trade;
  • Runtime Integration.

Все перечисленные задачи будут реализованы на последующих этапах дорожной карты серии 060.


Итог

Build 060.10 завершил формирование уровня Schema Validation для WebSocket Trade и сделал архитектуру обработки всех WebSocket-событий Dzentra полностью симметричной.

Новая реализация основана на существующем шаблоне Quote и OHLC, использует единый подход к структурной проверке сообщений, повторно применяет существующую иерархию исключений и не изменяет ранее реализованное поведение системы.

Build ограничен согласованным scope, успешно прошёл целевое и регрессионное тестирование и создаёт необходимый фундамент для следующего этапа — Build 060.11 — WebSocket Trade Parser.