Skip to content

Развертывание

Поддерживаемый путь

Текущая версия проекта после squashed migrations поддерживает deployment через fresh-install.

Шаги

cp .env.example .env
docker compose down -v
docker compose up -d --build

Проверки

docker compose ps
docker compose logs --tail=200 worker

Проверьте, что worker успешно применил миграции и запустился без ошибок.

Примечание

Upgrade-in-place со старых БД до squash-версии не поддерживается.

Каноничный порядок заполнения таблиц (bootstrap + schedules)

Этот раздел является единственным источником истины по последовательности запуска data pipelines.

1. Prerequisites / readiness gates

docker compose up -d --build
docker compose ps
docker compose logs --tail=200 worker

Ожидаемое состояние: - postgres и temporal в healthy; - worker в started/up; - в логах worker есть успешный старт и нет ошибки Namespace default is not found.

Если при старте worker сработала гонка с Temporal namespace (Namespace default is not found), перезапустите worker и продолжайте:

docker compose restart worker
docker compose logs --tail=200 worker

2. Manual bootstrap (правильная последовательность)

Шаг 1. SyncExchangesWorkflow (обязательно): актуализирует метаданные exchanges и фиксирует базовое состояние каталога бирж перед последующими sync-шагами.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncExchangesWorkflow \
  --workflow-id sync-exchanges-bootstrap-$(date +%s)

Шаг 2. SyncNetworksCatalogWorkflow (обязательно): заполняет networks_catalog и связанные идентификаторы/эндпоинты/метрики.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncNetworksCatalogWorkflow \
  --workflow-id sync-networks-catalog-bootstrap-$(date +%s) \
  --input '{"force_full_refresh":false,"soft_delete_grace_days":30,"metrics_required":false}'

Шаг 3. SyncExchangeCoinsWorkflow (обязательно): заполняет exchange_assets*, global_assets*, asset_mapping_quarantine.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncExchangeCoinsWorkflow \
  --workflow-id sync-exchange-coins-bootstrap-$(date +%s) \
  --input '{"force_full_refresh":false,"soft_delete_grace_days":30}'

Шаг 4. SyncGateLaunchpoolWorkflow (обязательно для launchpool аналитики): заполняет fct_gate_launchpool_* с использованием уже созданного mapping-контура из шага 3.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncGateLaunchpoolWorkflow \
  --workflow-id sync-gate-launchpool-bootstrap-$(date +%s) \
  --input '{"page":1,"page_size":1000,"status":0}'

Шаг 5. EnsureGateLaunchpoolScheduleWorkflow (после успешного шага 4): включает регулярный 5-минутный ingestion.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type EnsureGateLaunchpoolScheduleWorkflow \
  --workflow-id ensure-gate-launchpool-schedule-bootstrap-$(date +%s) \
  --input '{"schedule_id":"sync-gate-launchpool-5m","cron":"*/5 * * * *","timezone":"UTC","task_queue":"default","page":1,"page_size":1000,"status":0}'

Expected result: schedule sync-gate-launchpool-5m создан/обновлен idempotent-образом.

Шаг 6. SyncBybitLaunchpoolWorkflow (manual-only): снимает snapshot Bybit Launchpool в отдельные таблицы fct_bybit_launchpool_*.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncBybitLaunchpoolWorkflow \
  --workflow-id sync-bybit-launchpool-bootstrap-$(date +%s) \
  --input '{"current":1}'

Шаг 7. SyncBingXLaunchpoolWorkflow (manual-only): снимает snapshot BingX Launchpool в отдельные таблицы fct_bingx_launchpool_*.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncBingXLaunchpoolWorkflow \
  --workflow-id sync-bingx-launchpool-bootstrap-$(date +%s) \
  --input '{"include_details":true}'

Шаг 8. SyncBingXXPoolWorkflow (manual-only): снимает snapshot BingX XPool в отдельные таблицы fct_bingx_xpool_*.

docker compose exec -T temporal temporal workflow start \
  --address temporal:7233 --namespace default --task-queue default \
  --type SyncBingXXPoolWorkflow \
  --workflow-id sync-bingx-xpool-bootstrap-$(date +%s) \
  --input '{"include_details":true}'

3. Почему порядок именно такой

  • SyncExchangeCoinsWorkflow резолвит network_key через networks_catalog; без шага 2 растет missing_network_mapping.
  • SyncGateLaunchpoolWorkflow маппит project_coin/subpool_coin через exchange_assets* + exchange_asset_mappings; без шага 3 растет fct_gate_launchpool_quarantine.
  • SyncExchangesWorkflow должен выполняться первым шагом как обязательный этап консистентного bootstrap каталога бирж.
  • Поэтому каноничный порядок bootstrap для core-контура: SyncExchangesWorkflow -> SyncNetworksCatalogWorkflow -> SyncExchangeCoinsWorkflow -> SyncGateLaunchpoolWorkflow.
  • Для Bybit/BingX Launchpool и BingX XPool используются отдельные manual-only pipelines (SyncBybitLaunchpoolWorkflow, SyncBingXLaunchpoolWorkflow, SyncBingXXPoolWorkflow) и отдельные хранилища fct_bybit_launchpool_* / fct_bingx_launchpool_* / fct_bingx_xpool_*; schedule по умолчанию не включается.

4. Проверки после каждого шага

Проверка статуса workflow (должен быть COMPLETED):

docker compose exec -T temporal temporal workflow describe \
  --address temporal:7233 --namespace default \
  --workflow-id <workflow-id>

Минимальные SQL checks:

docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM networks_catalog;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM exchange_assets;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM exchange_asset_networks;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM fct_gate_launchpool_snapshot;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM fct_bybit_launchpool_snapshot;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM fct_bingx_launchpool_snapshot;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT COUNT(*) FROM fct_bingx_xpool_snapshot;"

Мониторинг quarantine:

docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT reason, COUNT(*) FROM asset_mapping_quarantine GROUP BY reason ORDER BY COUNT(*) DESC;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT reason, COUNT(*) FROM fct_gate_launchpool_quarantine GROUP BY reason ORDER BY COUNT(*) DESC;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT reason, COUNT(*) FROM fct_bybit_launchpool_quarantine GROUP BY reason ORDER BY COUNT(*) DESC;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT reason, COUNT(*) FROM fct_bingx_launchpool_quarantine GROUP BY reason ORDER BY COUNT(*) DESC;"
docker exec -i kit-postgres psql -U temporal -d kit -At -c "SELECT reason, COUNT(*) FROM fct_bingx_xpool_quarantine GROUP BY reason ORDER BY COUNT(*) DESC;"

5. Порядок включения расписаний после bootstrap

Включать только после успешного bootstrap шагов 2-4.

Рекомендуемый порядок: 1. sync-gate-launchpool-5m (обязательно) 2. sync-exchange-coins-daily (если используется) 3. sync-networks-catalog-daily (если используется) 4. sync-exchanges-daily (опционально)

Не включайте регулярный launchpool ingestion до успешного выполнения bootstrap для SyncNetworksCatalogWorkflow, SyncExchangeCoinsWorkflow и SyncGateLaunchpoolWorkflow.

6. Документационные сценарии валидации runbook

  1. Fresh-install: пройти шаги runbook от старта сервисов до включения schedule без дополнительных правок.
  2. Повторный bootstrap: повторный запуск шагов не должен приводить к разрушению состояния (идемпотентный смысл).
  3. Race scenario: при Namespace default is not found recovery через restart worker должен возвращать пайплайн в рабочее состояние.
  4. Quality scenario: запуск launchpool до ExchangeCoins является анти-паттерном (рост quarantine); runbook предотвращает это правильным порядком.