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 — оператор не знает о свежести данных без ручной проверки |