Wire the web-scraper as a third update fallback, add regression tests

AutoUpdateAndLearn.update_data() now falls back to LottoWebUpdater
(lotto.de scraping) when the API chain (Lottoland/GitHub/lottoAPI)
returns no new data, matching the pattern already in production on
the Eurojackpot sibling project. Required installing beautifulsoup4
into the venv - its absence would have crashed the entire update
script the moment the fallback import was added, not just the
fallback path itself, so this needed verifying before wiring it in.

Also adds tests/test_popularity_score.py (pytest): regression coverage
for the popularity/EV score against known overplayed combinations
(1-2-3-4-5-6, 5-10-15-20-25-30) and the Superzahl EV ordering. Verified
against the pre-fix code (commit 8c2089d) that these tests would
actually have caught the sum-extremity bug fixed in e05f1f1 - this
had previously only been caught by manual spot-checking.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
cbazzaandClaude Sonnet 5 committed 2026-09-12 10:08:45 +02:00
1 parent 73a6b43ec9
commit ec7290ece5
4 files changed
+135 -14

No files matched your search

+22 -4
View File
@@ -63,7 +63,7 @@ Alle Pfade relativ zum Projekt-Root.
| Komponente | Datei | Rolle |
| --- | --- | --- |
| `LottoAPIUpdater` | `scripts/utils/update_from_api.py` | Holt neue Ziehungen über `fetch_from_all_apis()`: Lottoland zuerst (liefert die neueste Ziehung meist noch am Ziehungstag), GitHub-Archiv für die Historie/als Fallback (kann tagelang hinterherhinken). `auto_update_and_learn.py` nutzt seit August 2026 `api_name='all'`, davor fest `api_name='github'` — daher wiederholt verspätete Ziehungen in der Vergangenheit. |
| `LottoAPIUpdater` | `scripts/utils/update_from_api.py` | Holt neue Ziehungen über `fetch_from_all_apis()`: Lottoland zuerst (liefert die neueste Ziehung meist noch am Ziehungstag), GitHub-Archiv für die Historie/als Fallback (kann tagelang hinterherhinken). `auto_update_and_learn.py` nutzt seit August 2026 `api_name='all'`, davor fest `api_name='github'` — daher wiederholt verspätete Ziehungen in der Vergangenheit. Liefert die API-Kette nichts Neues, greift automatisch `LottoWebUpdater` (lotto.de-Scraping) als dritter Fallback. |
| `AutoUpdateAndLearn` | `scripts/automation/auto_update_and_learn.py` | Orchestriert den 4-Schritte-Workflow: Daten aktualisieren → neue Ziehung prüfen → letzte Tipps evaluieren → Learning-Update (Retraining). |
| `FeatureEngineer` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | Baut 20 Features (Frequenzen, Gaps, Momentum, Trends, Beziehungen, Zyklen) aus den Rohdaten. |
| `AIMLEngine` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | RandomForest-Modelle, ein Modell pro Zahl (1–49). Cached unter `data/ultimate_ml_models/`. |
@@ -126,17 +126,28 @@ spiegeln nicht den tatsächlichen Zeitplan wider:
| --- | --- | --- |
| `com.lotto.update` | `scripts/automation/com.lotto.update.plist` | Mi + Sa, 20:00 Uhr |
| `com.lotto.weekly` | `scripts/automation/com.lotto.weekly.plist` | Di + Fr, 21:00 Uhr |
| `com.lotto.watchdog` | `scripts/automation/com.lotto.watchdog.plist` | täglich, 21:30 Uhr |
Logs: `logs/update_stdout.log` (Update+Learning), `logs/stdout.log`
(Tipp-Generierung).
(Tipp-Generierung), `logs/watchdog_stdout.log` (Watchdog).
`scripts/utils/watchdog.py` prüft, ob die letzte Ziehung in den Daten älter
als 5 Tage ist bzw. die Modelle hinter der neuesten Ziehung zurückliegen, und
schickt bei einem Treffer einen Telegram-Alarm über `LottoNotifier.send_alert()`.
Grund: `StartCalendarInterval`-Jobs, die launchd wegen Schlafmodus verpasst,
werden nicht automatisch nachgeholt — ohne diesen Check fiel das erst bei der
nächsten manuellen Nachfrage auf (so geschehen am 15.08.2026).
Backups (`data/backups/`) werden bei jedem Update automatisch erstellt und
auf die letzten 30 rotiert (`LottoAPIUpdater._prune_old_backups`).
## 5. Bekannte Schwachstellen / offene Punkte
- **`update_from_web.py`** (lotto.de-Scraper) ist als dritter Fallback
implementiert, aber nirgends in der automatisierten Pipeline eingebunden.
- **Utility-Skripte** in `scripts/utils/` (`health_check.py`, `validate_csv.py`,
`verify_draws.py`, `model_evaluator.py`) existieren, sind aber nicht in die
Cron-Automatisierung eingebunden; manuelle Ausführung bei Bedarf.
- Kein automatisiertes Retry/Catch-up für komplett verpasste launchd-Läufe
(nur Alarmierung via Watchdog) — Nachholen bleibt manuell.
## 6. Code-Graph
@@ -149,3 +160,10 @@ liegt unter `graphify-out/`:
Bei größeren strukturellen Änderungen: `/graphify --update` zum
inkrementellen Neuaufbau.
## 7. Tests
`tests/test_popularity_score.py` (pytest) prüft den Popularity/EV-Score
gegen bekannte Vielspieler-Kombinationen und deckt Regressionen wie den
Sum-Extremity-Bug (Abschnitt 3) sowie die volle Superzahl-Abdeckung über
einen 10er-Batch ab. Ausführen mit `pytest tests/`.