Files
iddaai-be/mds/SESSION_HANDOFF.md
T
fahricansecer 659110c806
Deploy Iddaai Backend / build-and-deploy (push) Successful in 4m32s
Update handoff doc + add backtest checkpoint/resume
2026-05-25 22:29:05 +03:00

306 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SESSION HANDOFF — iddaai sistem durumu
**Son güncelleme**: 2026-05-25 ~23:00 (Windows'tan Mac'e geçiş öncesi)
**Hedef**: Başka makinede / yeni Claude session'ında bu doc tek başına okunup işin nerede kaldığı anlaşılabilmeli.
---
## 🚨 EN SON DURUM (Mac'e geçmeden önce oku)
### Validation backtest ÖLDÜ
- Pencere: 2026-05-01 → 2026-05-14, 1500 maç
- **1200/1500'de SSH tunnel düşünce process sessizce öldü**
- **CSV kayıp** — script eski versiyondu, sadece sonda yazıyordu
- Sebep: localhost:5432 erişimi kayboldu, psycopg2 connection error
### Script DÜZELTILDI (Mac'te kullanılabilir)
`scripts/diagnostic_backtest.py` artık **crash-safe**:
- `--checkpoint-every 100` → her 100 maçta partial CSV diske yazılır
- Crash sonrası tekrar koşulunca **otomatik kaldığı yerden devam**
- Checkpoint dosyası: `reports/_checkpoint_<window-key>.csv`
- `--no-resume` flag fresh başlamak için
### Git push BEKLİYOR
- 36 dosya **commit edildi (local)** — bkz "Bu seansta yapılan KOD değişiklikleri"
- Push **auth hatası** verdi (gitea credentials cached değil)
- **User Mac'te push yapacak** (Gitea Personal Access Token gerekli, repo write yetkisi)
### Mac'te yapılacaklar (öncelikli sırayla)
1. Repo'yu clone et veya OneDrive'dan kopyala (eğer Mac OneDrive senkronize ediyorsa)
2. `git push origin main` ile pending commit'i remote'a yolla
3. SSH tunnel kur (Pi @ 95.70.252.214, port 2222) → DB için tunnel localhost:5432
4. Yeni Claude session'ı başlat, bu dosyayı oku, devam et
5. Backtest tekrar koştur (çoktan eski versiyondu, şimdi crash-safe)
```bash
cd ai-engine
export DATABASE_URL="postgresql://iddaai_user:IddaA1_S4crET!@localhost:5432/iddaai_db?schema=public"
export PYTHONIOENCODING=utf-8
python scripts/diagnostic_backtest.py --start 2026-05-01 --end 2026-05-14 --max-matches 1500
# ölürse, aynı komutu tekrar koş — checkpoint'ten devam eder
```
### Mevcut sağlam veri
Validation kayıp ama elimizde **in-sample backtest** ve **grid search** çıktıları var:
- `reports/diagnostic_backtest_20260525_035649.{csv,json,txt}` — 1000 maç, May 11-24
- `reports/filter_optimization_patch.json` — grid search winners
- Bu data ile in-sample analiz tamamlandı, validation eksik
---
---
## 🎯 Üst-seviye hedef
Sistem **maç başı-1 saat** kullanıcı tetiklemesiyle çalışacak. Bahis uzmanı seviyesinde:
- **main_pick + value_pick** (sistemin önerdiği)
- **Tüm market olasılıkları** (MS, HT, OU05-45, BTTS, OE, DC, HTFT, HCAP, Cards, Corners)
- **Net HT + FT skoru** + **Top-5 olası skor dağılımı**
- **Evidence panel**: lineup impact, son 5 maç, h2h, hakem profili, benzer-oran-band geçmişi
Ürün modeli: hem user kendi bahisini oynar, hem sistem para kazanırsa abonelik satılır.
Hedef ROI: **≥%10**. Günde **3-5 kaliteli bahis**.
Detaylı requirements doc: bu dosyanın altında, "Requirements Spec" bölümü.
---
## 🟢 Şu an arka planda KOŞAN işler
### 1. Validation backtest (LOCAL — bu laptop)
- **Script**: `ai-engine/scripts/diagnostic_backtest.py`
- **Komut**: `python scripts/diagnostic_backtest.py --start 2026-05-01 --end 2026-05-14 --max-matches 1500`
- **Log**: `ai-engine/validation_full.log` (OneDrive senkronize)
- **Çıkış**: bittiğinde `ai-engine/reports/diagnostic_backtest_<timestamp>.{csv,json,txt}`
- **Tahmini bitiş**: 2026-05-25 ~22:00 (yaklaşık)
- **Amaç**: Yeni kodla (calibrator + ev_edge veto + envelope + coherence + BTTS mute) **out-of-sample** doğrulama
- **Risk**: Laptop uyursa ölür. Bitmesini beklemen lazım VEYA partial sonuçla devam.
```powershell
# Status check (kendin)
$log='C:\Users\fahri\OneDrive\المستندات\GitHub\iddaai\iddaai-be\ai-engine\validation_full.log'
Select-String $log 'rate=|Outputs:' | Select-Object -Last 3 | ForEach-Object {$_.Line}
```
### 2. Feeder historical scan (REMOTE — Pi server)
- **Konum**: SSH @ haruncan@95.70.252.214:2222 → docker container `iddaai-be` → pm2
- **PM2 process**: `feeder-historical` (id=1)
- **Log rotation**: pm2-logrotate kurulu (max 30MB/dosya, 3 dosya, gzip)
- **Davranış**: 2026-05-03'ten geriye 2023-06-01'e kadar mackolik'ten odds/lineup patch
- **Otomatik restart**: 502 olunca 30 sn delay sonra restart (max 1000 kez)
- **Beklenen süre**: 24-72 saat
```bash
# Status (kendin SSH'la)
sudo docker exec iddaai-be pm2 list
sudo docker exec iddaai-be pm2 logs feeder-historical --lines 30 --nostream
```
---
## 📝 Bu seansta yapılan KOD değişiklikleri
Hepsi local repo'da, OneDrive senkronize edecek, başka makinede pull etmesen de açtığında orada olacak.
### A. Settlement / data layer
| Dosya | Değişiklik |
|---|---|
| `iddaai-be/prisma.config.ts` | `.env` fallback ekledim (`.env.local` üstüne) — `prisma generate` çalışsın diye |
| `iddaai-be/src/tasks/prediction-settlement.market-resolver.ts` | DC parser ayraçsız "1X/X2/12" kabul ediyor + HT_OU05/HT_OU15/HT_OU25 resolver eklendi |
| `iddaai-be/src/tasks/feature-enrichment.task.ts` **(YENİ)** | Cron 08:15 — eksik football_ai_features row insert + odds_movement SQL backfill |
| `iddaai-be/src/tasks/python-enrichment.task.ts` **(YENİ)** | Cron 08:25 — Python `enrich_ai_features.py` subprocess |
| `iddaai-be/src/tasks/tasks.module.ts` | İki yeni task register |
| `iddaai-be/src/scripts/run-feature-enrichment.ts` **(YENİ)** | Manuel one-shot trigger |
### B. AI engine — betting brain
`iddaai-be/ai-engine/services/betting_brain.py` — büyük revizyon:
- **HARD_MIN_SAMPLES = 50** floor (calibrator bypass <50 sample)
- **`ev_edge < 0.0` HARD VETO** (`negative_ev_edge`)
- **`ev_edge >= 0.20` HARD VETO** (`ev_edge_too_high_trap`)
- **`MUTED_MARKETS = {"BTTS"}`** — backtest no profitable config bulduğu için
- **`MARKET_OPTIMAL_FILTERS`** — MS ve OU25 için grid-search'ten gelen optimal envelope
- **`_score_consistent_markets()`** — skor tahminine uymayan picks elimine
- **`judge()` score coherence filter** — main_pick coherent set'ten seçilir
- **HTFT reversal cross-check** — Man City 1/2 senaryosu
### C. AI engine — model & calibration
| Dosya | Değişiklik |
|---|---|
| `ai-engine/models/calibration.py` | HARD_MIN_SAMPLES floor + sample-weighted blend formülü değişti |
| `ai-engine/models/calibration/*.pkl` | **10 calibrator retrain** (ms_home/draw/away, ou15/25/35, btts, ht_home/draw/away) — 4989-5000 sample her biri |
### D. AI engine — orchestrator feature builder
`ai-engine/services/orchestrator/feature_builder.py`:
- Hardcoded `home_position=10, away_position=10` → real `data.home_position` kullanılıyor
- Cup detection upper'a taşındı, `is_cup_match` UpsetEngine'e geçiyor
- Total teams parametresi UpsetEngine'e geçiyor
`ai-engine/services/orchestrator/data_loader.py`:
- `_estimate_league_position` artık **sezon filtresi** (son 300 gün) kullanıyor
### E. AI engine — scripts (yeni)
| Dosya | Ne yapıyor |
|---|---|
| `ai-engine/scripts/diagnostic_backtest.py` | Per-bet diagnostic backtest (CSV+JSON+TXT output) |
| `ai-engine/scripts/analyze_backtest_csv.py` | Backtest CSV üzerinde root-cause hipotez testleri |
| `ai-engine/scripts/optimize_filters.py` | Grid search per-market optimal threshold |
| `ai-engine/scripts/compare_backtests.py` | İki CSV karşılaştırması verdict ile |
| `ai-engine/scripts/test_score_coherence.py` | Coherence filter smoke test (LAFC senaryosu) |
### F. Social poster modülü (NestJS)
| Dosya | Değişiklik |
|---|---|
| `src/modules/social-poster/social-poster.service.ts` | Cron 15→10 dk, window 10-60, MAX_POSTS_PER_RUN, getHealthStatus() |
| `src/modules/social-poster/image-renderer.service.ts` | SEO filename + metadata sidecar (.json) |
| `src/modules/social-poster/caption-generator.service.ts` | SEO hashtag stratejisi (12 küratör tag) |
| `src/modules/social-poster/social-poster.controller.ts` | `/health` public + `/preview-png/:matchId` + `/run-now` endpoints |
| `mds/SOCIAL_POSTER_SETUP.md` **(YENİ)** | Env vars + API key alma adımları + test komutları |
### G. Modern image rendering (deneme)
| Dosya | Açıklama |
|---|---|
| `src/scripts/render-social-card-v3.ts` | satori + resvg-js ile modern HTML→PNG rendering (Twemoji top + bayrak) |
| `src/modules/social-poster/assets/*.svg` | Twemoji futbol/basket/bayrak SVG'leri |
### H. Yapılan DB değişiklikleri (idempotent — tekrar koşturulursa sorun yok)
| İşlem | Etki |
|---|---|
| `football_ai_features` 4008+ satır backfill | Son 60 günün FT maçları için feature row var artık (calculator_ver=feature_enrichment_task_v1) |
| Python enrichment koştu | h2h, referee, possession, league_avg, implied_* hepsi gerçek değerlerle dolu (181,614+ satır enriched) |
| Calibrator dosyaları yazıldı | `ai-engine/models/calibration/*.pkl` overwritten |
---
## 📂 Önemli dosya konumları (OneDrive synced)
```
iddaai-be/
├── mds/
│ ├── SESSION_HANDOFF.md ← BU DOSYA
│ └── SOCIAL_POSTER_SETUP.md ← social poster env+keys
├── ai-engine/
│ ├── reports/ ← BACKTEST CIKTILARI
│ │ ├── diagnostic_backtest_*.csv,json,txt
│ │ └── filter_optimization_patch.json
│ ├── validation_full.log ← validation backtest canlı log
│ ├── diagnostic_backtest_run.log ← önceki backtest log
│ ├── enrichment_run3.log ← enrichment koşma log
│ └── calibration_run.log ← calibrator retrain log
├── public/predictions/ ← render edilmiş social card PNG/JSON
└── src/scripts/ ← tüm yeni script'ler
```
---
## 🔑 Erişim bilgileri
### Pi sunucu (feeder + prod stack)
- **SSH**: `haruncan@95.70.252.214:2222`
- **Şifre**: `M594xH%$iM&4MM`
- **Plink kullan**: `~/plink.exe -ssh -P 2222 -pw '<password>' -hostkey 'SHA256:iq0YVI/4J897sf9dkksI7QzetpLCD0l57ZMX4UissI8' haruncan@95.70.252.214`
- **Docker**: `iddaai-be`, `iddaai-ai-engine`, `iddaai-fe`, `iddaai-postgres`, `iddaai-redis`, `gitea`
### DB (uzak Postgres @ Pi)
- **SSH tunnel function**: `iddaai-db` PowerShell fonksiyonu (yerel makinedeki profile'da kayıtlı)
- **Tunnel: localhost:5432 → Pi:5432**
- **Connection string**: `postgresql://iddaai_user:IddaA1_S4crET!@localhost:5432/iddaai_db?schema=public`
- **MCP**: Claude'un postgres MCP'si bu tunnel üzerinden çalışıyor (restricted mode, read-only)
---
## 📊 BACKTEST sonuçları geçmişi
### Backtest #1 — In-sample grid search (2026-05-11 → 05-24, 1000 maç)
- **CSV**: `ai-engine/reports/diagnostic_backtest_20260525_035649.csv`
- **TXT**: `ai-engine/reports/diagnostic_backtest_20260525_035649.txt`
- **Toplam playable**: 524 bet
- **Hit rate**: %54.77
- **ROI**: **%16.73** (baseline kötü)
- **Grid-search'ten çıkan optimal filtreler (in-sample)**:
- MS: edge [-5%, +15%], V27 AGREE zorunlu → +%8.23 (21 bet)
- OU25: odds ≥ 1.80, edge ≤ +15% → +%28.91 (20 bet)
- BTTS: tüm config'lerde kayıp → MUTE
- **Aggregate optimize**: 95 bet, ROI +%2.16 (in-sample)
### Backtest #2 — Validation (2026-05-01 → 05-14, KOŞUYOR)
- **Bitince konum**: `ai-engine/reports/diagnostic_backtest_<yeni_timestamp>.{csv,json,txt}`
- **Karşılaştırma çalıştır**: `python scripts/compare_backtests.py` (otomatik en yeni 2'yi alır)
- **Beklenen sonuç**: ROI ≥ 0 → out-of-sample doğrulama BAŞARILI; in-sample overfit değil
---
## ❓ Backtest BİTTİĞİNDE yapılacak (yeni session'da bu kısımdan başla)
### 1. Sonucu oku
```powershell
cd C:\Users\fahri\OneDrive\المستندات\GitHub\iddaai\iddaai-be\ai-engine
Get-ChildItem reports\diagnostic_backtest_*.txt | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | Get-Content
```
### 2. Karşılaştır
```powershell
python scripts\compare_backtests.py
```
Bu otomatik en yeni 2 backtest'i karşılaştırır, **VERDICT** verir:
- ✅ "FILTERS WORK" → ROI pozitif AND improved
- 🟡 "PARTIAL" → improved ama hâlâ negatif
- ❌ "OVERFITTING" → validation ROI collapse
### 3. Karara göre 2 yol
**Eğer ROI ≥ +%2 ve overfit yok:**
- `/sc:design` ile UI/API contract → Sprint 1
- Sprint 1: top-5 skor + evidence panel + "why" cümlesi
- Test edip prod'a aç
**Eğer ROI negatif veya overfit:**
- `analyze_backtest_csv.py` ile loss diagnostic
- Hangi market hâlâ kötü → tighten filter veya mute
- Calibrator recalibrate (özellikle BTTS dışındakiler için yeni sample)
- Tekrar backtest
---
## ⚠️ Bilinen açık problemler / sorular
1. **Coherence filter validate edilmedi production-side** — smoke test 20/20 ama gerçek production data ile karşılaştırma yok
2. **Lineup-overlap last-5 hesabı** — yazılmadı, requirements doc'ta F8 var
3. **Skor top-5 distribution** — Poisson zaten hesaplıyor, surface edilmedi (UI tarafı)
4. **"Why" cümlesi main_pick'te** — boş, doldurulması gerek
5. **Cards/Corners/RED CARD model** — yok, "henüz desteklenmiyor" placeholder ile bırak (kullanıcı onayladı: mevcut market'ler sağlamlaşsın)
6. **Orphan match_id 51 satır** — `prediction_runs` içinde, `matches`'ta yok. Sample noise, geçiştirilebilir.
7. **opening_value feeder bug** — `odds_movement_*` SQL yazıyor ama tüm değerler 0 (opening == closing). Feeder upstream sorun. Düşük öncelik.
---
## 🚦 Yeni Claude session'ında ilk komut
```
Bu projeye yeni bağlandım. Lütfen aşağıdaki dosyayı oku ve bana proje durumunu özet ver:
C:\Users\fahri\OneDrive\المستندات\GitHub\iddaai\iddaai-be\mds\SESSION_HANDOFF.md
Sonra validation backtest'in sonucuna bak:
- C:\Users\fahri\OneDrive\المستندات\GitHub\iddaai\iddaai-be\ai-engine\reports\
içindeki en yeni diagnostic_backtest_*.txt dosyasını oku
- compare_backtests.py script'ini koş, verdict göster
- Verdict'e göre sonraki adımı öner
```
Buradan devam eder. Tüm context bu doc'ta + dosyalarda + DB'de.
---
## 🛠️ Requirements spec (sıkıştırılmış)
**Ürün**: UI-tetikli per-match analiz, bahis uzmanı seviyesi
**Trigger**: User tıklar, on-demand
**Output**: main_pick + value_pick + tüm market olasılıkları + tek HT/FT skoru + top-5 skor dağılımı + evidence panel
**Kapsam**: Mevcut market'ler sağlamlaştırılır, yeni market eklenmez (kullanıcı onayı)
**Quality bar**: Calibration sapması ±2-5pp per market, NaN yok, response <3sn
**Validation**: Out-of-sample backtest (1500 maç, May 1-14) — KOŞUYOR
---
**SON NOT**: Backtest'in TAMAMLANMASINI bekle (~22:00). Laptop'u kapatma. Bittiğinde OneDrive senkronize eder, başka makinede otomatik orada olur. Yeni session'da bu dosyayı oku, sonuçlara bak, devam et.