# 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_.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_.{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 '' -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_.{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.