Skip to content

Orchestration Audit Report — SoccerPredictAI

Date: 2026-04-24 Auditor: GitHub Copilot (Claude Sonnet 4.6) Scope: Airflow DAGs — scheduling, dependency graph, retrain loop, fail handling Method: анализ airflow/dags/ (5 DAGs)


1. DAG Inventory

1.1 Инвентаризация DAG-ов

DAG id Назначение Schedule Catchup Tags
soccer_etl_livescores_01 Hourly incremental scraping (3 days window) @hourly soccer, etl, api
soccer_etl_livescores_backfill_monthly Исторический backfill (1998 → 2026-02) None (manual) soccer, etl, api
soccer_etl_livescores_manual_trigger Manual trigger (90 days window) None soccer, etl, api
soccer_etl_livescores_02_next_matches Daily: upcoming matches (15 days forward) @daily soccer, etl, api
soccer_etl_export_matches_to_source PostgreSQL → MinIO export (match + match_raw) None (manual) soccer, etl, db, export

1.2 Dependency graph

soccer_etl_livescores_01 (и аналогичные livescores DAGs):

trigger_livescores_etl (HttpOperator: PATCH /sources/livescores/)
wait_livescores_etl_done (HttpSensor: GET /monitoring/task_status/{task_id})

soccer_etl_export_matches_to_source:

table_match.trigger (HttpOperator: GET /sources/export/match)
table_match.wait_done (HttpSensor: GET /monitoring/task_status/{task_id})
table_match_raw.trigger (HttpOperator: GET /sources/export/match_raw)
table_match_raw.wait_done (HttpSensor: GET /monitoring/task_status/{task_id})

✅ Tasks выстроены в правильном порядке — wait before next trigger.


2. Scheduling Audit

2.1 Расписание обновления данных

Поток Расписание Риск
Incoming livescores (3-day window) @hourly ✅ Актуально
Upcoming matches (15 days forward) @daily
Historical backfill Ручной ✅ (одноразово)
PostgreSQL → MinIO export Ручной ⚠️ P1
DVC pipeline (retrain) Нет DAG ⚠️ P0
batch_inference Нет DAG ⚠️ P0

⚠️ Нет Airflow DAG для: - Запуска DVC pipeline (dvc repro) — retrain loop не автоматизирован - Запуска batch_inference для обновления match_features.parquet - Обновления serving artifacts после ретрейна

2.2 Риск freshness

Компонент Последнее обновление Автоматизация
PostgreSQL (scraping) каждый час
MinIO raw parquet только при ручном export
DVC features.parquet только при ручном dvc repro
match_features.parquet только при ручном dvc repro
Model в registry только при ручном dvc repro

Вывод: Инфраструктура scraping автоматизирована. Весь ML pipeline (data export → DVC → model update → serving refresh) требует ручного запуска.


3. Retrain Loop

3.1 Trigger criteria

Критерий Реализован
По расписанию (cron)
По дрейфу данных
По деградации метрик
По количеству новых матчей
Ручной запуск

⚠️ P0: Нет автоматического retrain trigger. Полностью ручной процесс.


4. Fail Handling

4.1 Retries

Все DAGs: retries: 3, retry_delay: timedelta(minutes=5) — ✅ настроено.

4.2 Sensor timeout

# Все HttpSensor:
poke_interval=60
timeout=60 * 60  # 1 час максимум ожидания
mode="reschedule"  # ✅ не блокирует worker slot

✅ Reschedule mode правильно освобождает worker slots.

4.3 Partial failures

При сбое одной из таблиц в etl_export_matches_to_source (table_match vs table_match_raw) — вторая таблица не запустится (sequential dependency). ✅ Правильное поведение.

4.4 Alerting

⚠️ P1: Нет email/Slack alerting при failures. Нет DAG-level alerting configuration.


5. Pipeline → Registry → Serving Gap

[Airflow] автоматически: scraping → PostgreSQL ✅
[Manual]  PostgreSQL → MinIO (export DAG, ручной) ⚠️
[Manual]  MinIO → DVC (dvc repro) ⚠️
[Manual]  DVC → MLflow Registry (register_model stage) ⚠️
[Manual]  Registry → Serving (Celery worker restart) ⚠️

⚠️ P0: Полный разрыв pipeline → registry → serving. После scraping всё дальнейшее требует ручного вмешательства.


6. Findings

ID Severity Описание
OR-01 P0 Нет Airflow DAG для запуска DVC pipeline (retrain loop не автоматизирован)
OR-02 P0 Нет Airflow DAG для запуска batch_inference — serving features устаревают
OR-03 P0 etl_export_matches_to_source (PostgreSQL → MinIO) запускается только вручную — нет автоматического триггера
OR-04 P1 Нет alerting при DAG failures (email/Slack)
OR-05 P1 Нет автоматического retrain criteria (drift, metric degradation, data volume)
OR-06 P2 soccer_etl_livescores_backfill_monthly использует hardcoded даты (1998-01-01 → 2026-02-01) в коде — при новом backfill нужно менять код
OR-07 P2 Нет DAG для мониторинга состояния pipeline — оператор не знает о свежести данных без ручной проверки