6.4 KiB
Обзор архитектуры Dzentra
Статус: Current; Build 060.30.3
Dzentra развивается как модульный монолит: приложение собирается одним Composition Root, но ответственность разделена между пакетами и связывается через явные контракты.
Каноническое подробное описание готовой Market Data вертикали находится в архитектуре Trades Feed. Эта страница служит верхнеуровневой картой всего приложения и не дублирует lifecycle и recovery-сценарии.
Composition Root и текущие связи
src.bootstrap загружает настройки, выполняет базовый init_schema() с
PostgreSQL I/O, собирает опциональный Market Data pool/repository graph
без I/O и управляет общим lifecycle Telegram, Trade Runtime и Market
Data Storage.
Схема запуска и основных взаимодействий:
main.py → bootstrap
├→ init_schema() → src.storage → PostgreSQL
├→ Telegram polling → trading / integrations
└→ optional Trade Runtime
├→ market_data/acquisition → Consistency / Recovery
└→ optional market_data/storage → PostgreSQL
trading / integrations / notifications / runtime_events
→ существующие связи модульного монолита
Это карта исполнения, а не утверждение о полностью однонаправленном
import graph. В исторических пакетах сохраняются перекрёстные связи между
trading, integrations и notifications. Новая Market Data вертикаль
имеет более строгие protocol/composition boundaries. Пакеты не должны
самостоятельно запускать общий Application lifecycle.
Основные пакеты app/src
| Пакет | Ответственность |
|---|---|
bootstrap |
Composition Root, startup, graceful shutdown и feature-flag wiring |
core |
Settings, logging и общие базовые компоненты приложения |
telegram |
Routers, handlers, keyboards и Telegram UI |
trading |
Торговая бизнес-логика, журнал и существующие runtime-компоненты |
integrations |
Клиенты и адаптеры внешних API вне канонической Market Data вертикали |
market_data |
Acquisition, persistent Storage, Historical Access и deterministic Replay |
runtime_events |
Внутренние runtime-события и их публикация |
notifications |
Доставка и маршрутизация уведомлений |
storage |
Смешанный общий/исторический PostgreSQL foundation, migrations и in-memory caches |
shared |
Общие вспомогательные компоненты без владения lifecycle |
Market Data
Пакет market_data разделён на четыре независимые области:
| Область | Назначение |
|---|---|
acquisition |
WebSocket/REST ingestion, validation, Consistency, Recovery и Production Runtime Trades |
storage |
Канонические Trade/Quote/Candle repositories, persistent Trade checkpoint, partitions и Retention |
access |
Read-only Historical Access к сохранённым данным |
replay |
Ограниченный deterministic Replay через явно создаваемую one-shot session |
WebSocket Runtime, Consistency/Recovery и persistence wiring завершены только для Trades. Существующие REST-потоки Quotes/Candles продолжают обслуживать Trading/UI. Quote и Candle repositories/readers реализованы, но persistent writer consumers к ним пока не подключены.
Historical Access, Replay, Retention и создание месячных партиций не являются фоновыми задачами приложения и выполняются только явным вызывающим кодом.
Две Storage-границы
Историческое имя src/storage охватывает несколько разных обязанностей:
session.py,schema.pyи repositories журнала/balance snapshots обслуживают базовую схему приложения;instrument_store.pyиquote_store.pyпредоставляют in-memory caches;postgres_pool.pyиmigrations.pyявляются общей PostgreSQL-инфраструктурой, которую использует новая Market Data вертикаль.
src/market_data/storage владеет каноническими persistent Market Data
contracts и repositories. Поэтому src/storage нельзя считать целиком
устаревшим или неиспользуемым. Подробная карта ownership приведена в
Storage README.
Runtime и данные
Краткая цепочка принятой Trades-вертикали:
Dzengi WebSocket + REST Recovery
↓
Canonical Trade → Consistency
↓
optional atomic Trade + checkpoint write
↓
next startup: Hydration → Startup Recovery → buffered live processing
explicit caller → Historical Access / Replay
PostgreSQL доступен обычному Bootstrap даже при выключенных Trade Stream и Market Data Storage, поскольку базовые таблицы журнала и balance snapshots инициализируются всегда.