This commit is contained in:
Executable
+928
@@ -0,0 +1,928 @@
|
||||
# Suggest-Bet-BE - Tek Gerçek Kaynak (OZET.md)
|
||||
|
||||
Son güncelleme: 17 Şubat 2026
|
||||
Kapsam: Bu dosya, projeyi devralmak/geliştirmek için gereken ana teknik bilgileri tek yerde toplar.
|
||||
Kaynak: Doğrudan repo kodu (`prisma/schema.prisma`, `src/*`, `ai-engine/*`) üzerinden derlenmiştir.
|
||||
|
||||
---
|
||||
|
||||
## 1. Ürün Hedefi
|
||||
|
||||
Suggest-Bet-BE, canlı ve geçmiş maç verileri üzerinden AI tahminleri üretir.
|
||||
|
||||
Ana ürün akışı:
|
||||
|
||||
1. Kullanıcı frontend’de `live_matches` tablosundan maçı seçer.
|
||||
2. Backend seçilen maçı AI engine’e gönderir (V20+ tek maç paketi).
|
||||
3. AI engine çoklu market olasılık paketi üretir.
|
||||
4. Kullanıcı bu önerilerden kuponunu manuel kurar.
|
||||
5. Aynı altyapı yaklaşan maç otomasyonları/sosyal medya çıktısı için tekrar kullanılır.
|
||||
|
||||
---
|
||||
|
||||
## 2. Teknoloji Stack
|
||||
|
||||
- Backend API: NestJS + TypeScript
|
||||
- ORM/DB: Prisma + PostgreSQL
|
||||
- Queue: BullMQ
|
||||
- Cache: Redis (`cache-manager-redis-yet`)
|
||||
- AI Engine: Python + FastAPI + XGBoost (+ ensemble logic)
|
||||
- Scheduler: `@nestjs/schedule` Cron
|
||||
- Auth: JWT + refresh token
|
||||
- i18n: `nestjs-i18n`
|
||||
|
||||
---
|
||||
|
||||
## 3. Kod Yapısı (Özet)
|
||||
|
||||
### 3.1 NestJS
|
||||
|
||||
Temel yol: `/Users/piton/Documents/Suggest-Bet-BE/src`
|
||||
|
||||
Önemli modüller:
|
||||
|
||||
- `auth`
|
||||
- `users`
|
||||
- `admin`
|
||||
- `matches`
|
||||
- `predictions`
|
||||
- `coupons`
|
||||
- `analysis`
|
||||
- `feeder`
|
||||
- `health`
|
||||
- `leagues`
|
||||
|
||||
Sistem seviyesinde:
|
||||
|
||||
- `database` (Prisma servisleri)
|
||||
- `tasks` (cron işleri)
|
||||
- `common/queues` (BullMQ global queue config)
|
||||
|
||||
### 3.2 AI Engine
|
||||
|
||||
Temel yol: `/Users/piton/Documents/Suggest-Bet-BE/ai-engine`
|
||||
|
||||
Önemli bileşenler:
|
||||
|
||||
- `main.py` (FastAPI endpointleri)
|
||||
- `services/single_match_orchestrator.py` (ana orchestration)
|
||||
- `models/v20_ensemble.py` (ana tahmin motoru)
|
||||
- `core/calculators/*`
|
||||
- `core/engines/*`
|
||||
- `features/*`
|
||||
- `models/xgboost/*` (model artefact)
|
||||
|
||||
---
|
||||
|
||||
## 4. Veritabanı Şeması - Ne Nerede?
|
||||
|
||||
Kaynak: `/Users/piton/Documents/Suggest-Bet-BE/prisma/schema.prisma`
|
||||
|
||||
### 4.1 Temel Sport Veri Tabloları
|
||||
|
||||
- `countries`: ülke bilgileri
|
||||
- `leagues`: lig bilgileri (`country_id`, `sport`)
|
||||
- `teams`: takım bilgileri (`sport`, `logo_url`)
|
||||
- `players`: oyuncu kayıtları
|
||||
- `matches`: kalıcı maç kaydı (FT/historical dahil)
|
||||
- `live_matches`: canlı/akış bazlı maç kaydı (JSON odds/lineups/sidelined dahil)
|
||||
|
||||
### 4.2 Odds Tabloları
|
||||
|
||||
- `odd_categories`: market başlıkları (MS, OU, BTTS vb.)
|
||||
- `odd_selections`: kategori alt seçimleri ve oran değerleri
|
||||
- `odds_history`: oran değişim geçmişi
|
||||
|
||||
### 4.3 Maç İçi Detay Tabloları
|
||||
|
||||
- `match_team_stats`: takım istatistikleri (futbol+basketbol alanları)
|
||||
- `match_player_participation`: kadro/ilk 11 katılımı
|
||||
- `match_player_events`: gol/kart/değişiklik olayları
|
||||
- `match_player_stats`: oyuncu istatistikleri
|
||||
- `match_officials`: hakem/yardımcı hakem vb.
|
||||
- `official_roles`: hakem rol sözlüğü
|
||||
|
||||
### 4.4 AI Tabloları
|
||||
|
||||
- `match_ai_features`: hesaplanmış feature cache/tabanı
|
||||
- `predictions`: match bazlı cache edilmiş prediction JSON
|
||||
- `ai_predictions_log`: tahmin/sonuç performans logu
|
||||
|
||||
### 4.5 Kullanıcı/Kupon Tabloları
|
||||
|
||||
- `users`
|
||||
- `refresh_tokens`
|
||||
- `usage_limits`
|
||||
- `user_coupons`
|
||||
- `user_coupon_items`
|
||||
- `analyses`
|
||||
|
||||
### 4.6 Sistem Tabloları
|
||||
|
||||
- `app_settings`: state/checkpoint gibi key-value ayarlar
|
||||
- `translations`: runtime çeviri girdileri
|
||||
|
||||
### 4.7 İlişki Mantığı (kısa)
|
||||
|
||||
- `matches` merkezi entity’dir.
|
||||
- Odds: `matches -> odd_categories -> odd_selections -> odds_history`
|
||||
- Kadro/event/stats: `matches` + `teams` + `players`
|
||||
- Kupon item: `user_coupon_items.match_id -> matches.id`
|
||||
|
||||
---
|
||||
|
||||
## 5. API Envanteri (Backend)
|
||||
|
||||
Base prefix: `/api`
|
||||
|
||||
### 5.1 Auth (`/auth`)
|
||||
|
||||
- `POST /register`
|
||||
- `POST /login`
|
||||
- `POST /refresh`
|
||||
- `POST /logout`
|
||||
|
||||
### 5.2 Predictions (`/predictions`)
|
||||
|
||||
- `GET /health`
|
||||
- `GET /upcoming`
|
||||
- `GET /value-bets`
|
||||
- `GET /history`
|
||||
- `GET /:matchId`
|
||||
- `POST /generate`
|
||||
- `POST /smart-coupon`
|
||||
|
||||
Not (çalışma modu):
|
||||
|
||||
- `REDIS_ENABLED=false` iken `QueueModule` ve `PredictionsModule` AppModule importundan çıkarılır; bu modda `/api/predictions/*` route'ları yüklenmez.
|
||||
- `REDIS_ENABLED=true` iken queue + predictions endpointleri aktif olur.
|
||||
|
||||
### 5.3 Coupons (`/coupon`)
|
||||
|
||||
- `POST /analyze-match`
|
||||
- `POST /daily-banko`
|
||||
- `POST /suggest`
|
||||
- `POST /create`
|
||||
- `GET /my-stats`
|
||||
- `GET /history`
|
||||
|
||||
### 5.4 Matches (`/matches`)
|
||||
|
||||
- `POST /query`
|
||||
- `GET /`
|
||||
- `GET /leagues/active`
|
||||
- `GET /:id`
|
||||
|
||||
### 5.5 Leagues (`/leagues`)
|
||||
|
||||
- `GET /countries`
|
||||
- `GET /countries/:id`
|
||||
- `GET /`
|
||||
- `GET /:id`
|
||||
- `GET /teams/search`
|
||||
- `GET /teams/:id`
|
||||
- `GET /teams/:id/matches`
|
||||
- `GET /teams/h2h`
|
||||
|
||||
### 5.6 Health (`/health`)
|
||||
|
||||
- `GET /`
|
||||
- `GET /ready`
|
||||
- `GET /live`
|
||||
|
||||
### 5.7 Analysis (`/analysis`)
|
||||
|
||||
- `POST /analyze-matches`
|
||||
- `GET /history`
|
||||
|
||||
### 5.8 Users (`/users`)
|
||||
|
||||
- `GET /me`
|
||||
|
||||
### 5.9 Admin (`/admin`)
|
||||
|
||||
- `GET /users`
|
||||
- `GET /users/:id`
|
||||
- `DELETE /users/:id`
|
||||
- `GET /settings`
|
||||
- `GET /usage-limits`
|
||||
- `POST /usage-limits/reset-all`
|
||||
- `GET /analytics/overview`
|
||||
|
||||
---
|
||||
|
||||
## 6. AI Engine API Envanteri
|
||||
|
||||
Ana dosya: `/Users/piton/Documents/Suggest-Bet-BE/ai-engine/main.py`
|
||||
|
||||
Ana route’lar:
|
||||
|
||||
- `GET /`
|
||||
- `GET /health`
|
||||
- `POST /v20plus/analyze/{match_id}`
|
||||
- `POST /v20plus/coupon`
|
||||
- `GET /v20plus/daily-banker`
|
||||
|
||||
Geriye uyumluluk alias’ları:
|
||||
|
||||
- `POST /predict/v20/{match_id}`
|
||||
- `POST /v20/analyze/{match_id}`
|
||||
- `POST /smart-coupon`
|
||||
- `POST /v20/coupon`
|
||||
|
||||
Not: Backend uygulaması artık yalnızca `v20plus` route'larını çağırır.
|
||||
|
||||
---
|
||||
|
||||
## 7. V20+ Ana Tahmin Mimarisi (Şu anki temel)
|
||||
|
||||
Ana servis: `ai-engine/services/single_match_orchestrator.py`
|
||||
|
||||
Akış:
|
||||
|
||||
1. Maç verisini getir (`live_matches` öncelik, `matches` fallback)
|
||||
2. Odds çıkar (`live_matches.odds` JSON, yoksa relational odds fallback)
|
||||
3. Lineup çıkar:
|
||||
- `live_matches.lineups` JSON parse (`id` / `playerId` / `personId` destekli)
|
||||
- yoksa `match_player_participation` (aynı match, `is_starting=true`) fallback
|
||||
- yine yoksa tarih bazlı muhtemel XI fallback: ilgili takımın maç tarihinden önceki FT maçlarında en sık başlayan 11 oyuncu (home/away tarafları ayrı hesaplanır, karıştırılmaz)
|
||||
4. V20 ensemble çalıştır (`models/v20_ensemble.py`)
|
||||
5. Tek sözleşmede prediction package döndür
|
||||
|
||||
Package ana alanları:
|
||||
|
||||
- `match_info`
|
||||
- `data_quality`
|
||||
- `risk`
|
||||
- `engine_breakdown`
|
||||
- `main_pick`
|
||||
- `bet_advice`
|
||||
- `bet_summary`
|
||||
- `supporting_picks`
|
||||
- `aggressive_pick`
|
||||
- `scenario_top5`
|
||||
- `score_prediction`
|
||||
- `market_board`
|
||||
- `reasoning_factors`
|
||||
|
||||
Pick karar alanları (özellikle `main_pick` ve `supporting_picks`):
|
||||
|
||||
- `raw_confidence`
|
||||
- `calibrated_confidence`
|
||||
- `min_required_confidence`
|
||||
- `edge`
|
||||
- `play_score`
|
||||
- `playable`
|
||||
- `bet_grade` (`A`/`B`/`C`/`PASS`)
|
||||
- `stake_units`
|
||||
- `decision_reasons`
|
||||
|
||||
Bu sözleşme frontend + kupon + otomasyon için ortak temel kabul edilir.
|
||||
|
||||
---
|
||||
|
||||
## 8. Queue ve Asenkron İşler
|
||||
|
||||
Queue tanımı:
|
||||
|
||||
- Queue adı: `predictions-queue`
|
||||
- Job tipleri:
|
||||
- `predict-match`
|
||||
- `smart-coupon`
|
||||
|
||||
Kod:
|
||||
|
||||
- `src/modules/predictions/queues/predictions.types.ts`
|
||||
- `src/modules/predictions/queues/predictions.queue.ts`
|
||||
- `src/modules/predictions/queues/predictions.processor.ts`
|
||||
- `src/common/queues/queue.module.ts`
|
||||
|
||||
---
|
||||
|
||||
## 9. Cron/Task Envanteri
|
||||
|
||||
Dosyalar:
|
||||
|
||||
- `src/tasks/data-fetcher.task.ts`
|
||||
- `src/tasks/live-updater.task.ts`
|
||||
- `src/tasks/limit-resetter.task.ts`
|
||||
|
||||
Başlıca işler:
|
||||
|
||||
- 15 dk: canlı maç fetch (`fetchLiveMatches`)
|
||||
- 15 dk: live score update (`updateLiveScores`)
|
||||
- 30 dk: finished match finalize (`finalizeFinishedMatches`)
|
||||
- Günlük 03:00: usage limit reset
|
||||
- Günlük 04:00: eski data cleanup
|
||||
- Günlük 00:00: subscription expiry check
|
||||
|
||||
---
|
||||
|
||||
## 10. Çalıştırma Komutları (Repo Gerçeği)
|
||||
|
||||
Kaynak: `package.json`
|
||||
|
||||
- Dev server: `npm run start:dev`
|
||||
- Build: `npm run build`
|
||||
- Test: `npm run test`
|
||||
- E2E: `npm run test:e2e`
|
||||
- Lint: `npm run lint`
|
||||
|
||||
Feeder scriptleri:
|
||||
|
||||
- `npm run feeder:historical`
|
||||
- `npm run feeder:fill-gaps`
|
||||
- `npm run feeder:basketball`
|
||||
- `npm run feeder:live`
|
||||
- `npm run cleanup:live`
|
||||
|
||||
AI/backtest scriptleri (sık kullanılan):
|
||||
|
||||
- `python3 ai-engine/scripts/backtest_v20plus_today.py`
|
||||
- `python3 ai-engine/scripts/backtest_v20plus_today.py --date YYYY-MM-DD`
|
||||
- `python3 ai-engine/scripts/backtest_v20plus_today.py --date YYYY-MM-DD --end-date YYYY-MM-DD`
|
||||
|
||||
---
|
||||
|
||||
## 11. Env Değişkenleri (Zorunlu/Önemli)
|
||||
|
||||
Kaynak: `src/config/env.validation.ts`
|
||||
|
||||
Kritikler:
|
||||
|
||||
- `NODE_ENV`, `PORT`
|
||||
- `DATABASE_URL`
|
||||
- `JWT_SECRET`
|
||||
- `JWT_ACCESS_EXPIRATION`, `JWT_REFRESH_EXPIRATION`
|
||||
- `REDIS_ENABLED`
|
||||
- `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD`
|
||||
- `DEFAULT_LANGUAGE`, `FALLBACK_LANGUAGE`
|
||||
- `THROTTLE_TTL`, `THROTTLE_LIMIT`
|
||||
|
||||
Opsiyoneller:
|
||||
|
||||
- `ENABLE_MAIL`, `ENABLE_S3`, `ENABLE_WEBSOCKET`, `ENABLE_MULTI_TENANCY`
|
||||
- Mail/S3 alanları
|
||||
|
||||
AI endpoint host’u:
|
||||
|
||||
- Backend tarafında `AI_ENGINE_URL` env’i zorunlu olarak set edilmelidir (önerilen: `http://ai-engine:8000`).
|
||||
|
||||
---
|
||||
|
||||
## 12. Model Artefact Durumu (Özet)
|
||||
|
||||
XGBoost artefact klasörü:
|
||||
|
||||
- `/Users/piton/Documents/Suggest-Bet-BE/ai-engine/models/xgboost`
|
||||
|
||||
Aktif yüklenen pkl’ler:
|
||||
|
||||
- `xgb_ms.pkl`
|
||||
- `xgb_ou25.pkl`
|
||||
- `xgb_btts.pkl`
|
||||
- `xgb_ht_ft.pkl`
|
||||
|
||||
Not:
|
||||
|
||||
- Bazı marketlerde `.json` dosyaları bulunabilir; inferans tarafı pkl odaklıdır.
|
||||
|
||||
---
|
||||
|
||||
## 13. Temizlenen/Legacy Kod Notu
|
||||
|
||||
V20+ geçişinde kaldırılan örnek dead code:
|
||||
|
||||
- `ai-engine/services/coupon_builder_v2.py`
|
||||
- `src/modules/predictions/dto/python-prediction.dto.ts`
|
||||
- birkaç eski debug/test Python scripti
|
||||
|
||||
Not:
|
||||
|
||||
- Repo’da kullanıcı kaynaklı başka değişiklikler olabilir; silme/temizlik öncesi `git status` ile doğrulama şart.
|
||||
|
||||
---
|
||||
|
||||
## 14. Bilinen Riskler / Teknik Borç
|
||||
|
||||
1. Repo genelinde `src/scripts/*` altında mevcut TypeScript/lint hataları var (bu dosyalar ana runtime dışında).
|
||||
2. Bazı ortamlarda `dist/` klasörü permission/root ownership problemi build sürecini bozabiliyor.
|
||||
3. Tahmin kalitesi için lineup/odds kapsamı kritik; eksik veri durumunda confidence düşürme stratejisi uygulanmalı.
|
||||
4. Contract testleri ve backtest raporlarının CI içine alınması henüz yeterli değil.
|
||||
5. ~~V20+ bet calibration şu an hafif katsayı tabanlı; pazar bazlı (MS/OU/BTTS) düzenli kalibrasyon pipeline'ı (ör. weekly recalibration) ile desteklenmeli.~~ **ÇÖZÜLDÜ**: Isotonic Regression calibration sistemi eklendi (Şubat 2026).
|
||||
6. `xgb_ou15.pkl` ve `xgb_ou35.pkl` bazı ortamlarda eksik olabilir; bu durumda ilgili marketler fallback mantıkla çalışır, kalite düşebilir.
|
||||
|
||||
---
|
||||
|
||||
## 15. Isotonic Regression Calibration Sistemi (Şubat 2026)
|
||||
|
||||
### 15.1 Genel Bakış
|
||||
|
||||
V20+ tahmin modelinin olasılık çıktılarını kalibre etmek için **Isotonic Regression** tabanlı bir calibration sistemi eklendi.
|
||||
|
||||
**Neden Calibration?**
|
||||
|
||||
- XGBoost modelleri genellikle aşırı güvenli (overconfident) tahminler üretir
|
||||
- Örnek: Model %70 derken gerçek kazanma oranı %60 olabilir
|
||||
- Isotonic Regression, tahmin edilen olasılıkları gerçek sonuç oranlarına map eder
|
||||
|
||||
### 15.2 Dosya Yapısı
|
||||
|
||||
```
|
||||
ai-engine/models/
|
||||
├── calibration.py # Ana calibration modülü
|
||||
└── calibration/ # Eğitilmiş modeller (otomatik oluşturulur)
|
||||
├── ms_home_calibrator.pkl
|
||||
├── ms_home_metrics.json
|
||||
├── ou25_calibrator.pkl
|
||||
├── ou25_metrics.json
|
||||
└── ...
|
||||
```
|
||||
|
||||
### 15.3 Kullanım
|
||||
|
||||
```python
|
||||
from models.calibration import get_calibrator
|
||||
|
||||
calibrator = get_calibrator()
|
||||
|
||||
# Tek bir olasılığı kalibre et
|
||||
raw_prob = 0.75
|
||||
calibrated_prob = calibrator.calibrate("ou25", raw_prob)
|
||||
# Örnek: 0.75 → 0.68 (daha gerçekçi)
|
||||
```
|
||||
|
||||
### 15.4 Eğitim Scriptleri
|
||||
|
||||
```bash
|
||||
# Tüm marketler için calibration eğitimi
|
||||
python3 ai-engine/scripts/train_calibration.py
|
||||
|
||||
# Belirli marketler
|
||||
python3 ai-engine/scripts/train_calibration.py --markets ou25 btts ms_home
|
||||
|
||||
# Tarih aralığı ile
|
||||
python3 ai-engine/scripts/train_calibration.py --start 2026-01-01 --end 2026-02-15
|
||||
|
||||
# Sadece top ligler
|
||||
python3 ai-engine/scripts/train_calibration.py --top-leagues-only
|
||||
```
|
||||
|
||||
### 15.5 Backtest ve Doğrulama
|
||||
|
||||
```bash
|
||||
# Calibration karşılaştırması
|
||||
python3 ai-engine/scripts/backtest_calibration.py --start 2026-01-01 --end 2026-02-15
|
||||
```
|
||||
|
||||
**Çıktı Örneği:**
|
||||
|
||||
```
|
||||
Market N Raw Calibrated Improvement Status
|
||||
ou25 1245 0.2134 0.1987 +0.0147 ✓ Better
|
||||
btts 1189 0.2245 0.2101 +0.0144 ✓ Better
|
||||
ms_home 1230 0.2456 0.2398 +0.0058 ✓ Better
|
||||
```
|
||||
|
||||
### 15.6 Metrikler
|
||||
|
||||
| Metrik | Açıklama | İdeal Değer |
|
||||
| ---------------- | -------------------------- | -------------- |
|
||||
| **Brier Score** | Olasılık tahmin doğruluğu | 0 (mükemmel) |
|
||||
| **ECE** | Expected Calibration Error | 0 (mükemmel) |
|
||||
| **Sample Count** | Eğitim örnek sayısı | >1000 önerilir |
|
||||
|
||||
### 15.7 Desteklenen Marketler
|
||||
|
||||
- `ms_home`, `ms_draw`, `ms_away` - Maç Sonucu
|
||||
- `ou15`, `ou25`, `ou35` - Alt/Üst
|
||||
- `btts` - Karşılıklı Gol
|
||||
- `ht_home`, `ht_draw`, `ht_away` - İlk Yarı Sonucu
|
||||
- `dc` - Çifte Şans
|
||||
- `ht_ft` - İlk Yarı/Maç Sonucu
|
||||
|
||||
### 15.8 Weekly Recalibration Önerisi
|
||||
|
||||
En iyi sonuçlar için haftalık olarak calibration modellerini yeniden eğitin:
|
||||
|
||||
```bash
|
||||
# Cron job (her Pazartesi 05:00)
|
||||
0 5 * * 1 cd /path/to/ai-engine && python3 scripts/train_calibration.py --top-leagues-only
|
||||
```
|
||||
|
||||
### 15.9 Backtest Sonuçları ve Optimizasyonlar (Şubat 2026)
|
||||
|
||||
**V20 Ensemble Backtest Özeti (107 maç, 17-18 Şubat 2026):**
|
||||
|
||||
| Market | Doğruluk | Değerlendirme |
|
||||
| ---------------- | --------- | ------------- |
|
||||
| Alt/Üst 1.5 | **82.2%** | 🔥 En yüksek |
|
||||
| Çifte Şans | **76.6%** | 🔥 Yüksek |
|
||||
| İY Alt/Üst 0.5 | **75.7%** | 🔥 Yüksek |
|
||||
| Alt/Üst 2.5 | **65.4%** | 👍 İyi |
|
||||
| Maç Sonucu (1X2) | 57.0% | 👍 Orta |
|
||||
| Alt/Üst 3.5 | 56.1% | 👍 Orta |
|
||||
| KG Var/Yok | 47.7% | ⚠️ Düşük |
|
||||
| İlk Yarı Sonucu | 41.1% | 💀 Çok düşük |
|
||||
|
||||
**Confidence Bucket Analizi:**
|
||||
|
||||
| Confidence Aralığı | Doğruluk | Öneri |
|
||||
| ------------------ | ---------- | ---------------------- |
|
||||
| 80%+ | **100.0%** | Kesin banko |
|
||||
| 60-80% | 70.0% | Güvenilir |
|
||||
| **40-60%** | **83.3%** | 🔥 **Sürpriz yüksek!** |
|
||||
| 0-40% | 49.4% | Riskli |
|
||||
|
||||
**Önemli Bulgular:**
|
||||
|
||||
- 40-60% confidence aralığı beklenenden çok daha yüksek doğruluk gösteriyor (83.3%)
|
||||
- Bu nedenle MIN_CONFIDENCE threshold 60%'tan **40%'a düşürüldü**
|
||||
- Yüksek doğruluklu marketler (DC, OU15, HT_OU05, OU25) önceliklendirildi
|
||||
|
||||
**Guaranteed Pick Optimizasyonu:**
|
||||
|
||||
```python
|
||||
# Önceki (eski) değerler
|
||||
MIN_CONFIDENCE = 60.0
|
||||
|
||||
# Yeni (optimize edilmiş) değerler
|
||||
MIN_CONFIDENCE = 40.0 # Backtest sonucuna göre
|
||||
HIGH_ACCURACY_MARKETS = {"DC", "OU15", "HT_OU05", "OU25"} # Öncelikli marketler
|
||||
```
|
||||
|
||||
**Market Calibration Değerleri (Backtest'e göre güncellendi):**
|
||||
|
||||
```python
|
||||
market_calibration = {
|
||||
"OU15": 0.82, # 82.2% accuracy - EN YÜKSEK
|
||||
"DC": 0.77, # 76.6% accuracy
|
||||
"HT_OU05": 0.76, # 75.7% accuracy
|
||||
"OU25": 0.65, # 65.4% accuracy
|
||||
"MS": 0.57, # 57.0% accuracy
|
||||
"BTTS": 0.48, # 47.7% accuracy - düşük
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16. İlgili Yeni Dokümanlar
|
||||
|
||||
- API response sözleşmesi: `mds/API_RESPONSE_SCHEMA.md`
|
||||
|
||||
---
|
||||
|
||||
## 15. Karar: Bundan Sonra Tek Referans
|
||||
|
||||
Bu dosya (`mds/OZET.md`) tek ana referanstır.
|
||||
|
||||
Her büyük değişiklikten sonra şu alanlar güncellenecek:
|
||||
|
||||
- 5. API envanteri
|
||||
- 7. V20+ mimari
|
||||
- 9. Task/Cron envanteri
|
||||
- 12. Model artefact durumu
|
||||
- 14. Riskler
|
||||
|
||||
Böylece context reset olsa bile proje devamlılığı bu dosyadan sağlanır.
|
||||
|
||||
---
|
||||
|
||||
## 17. Son Konuşma Güncellemesi (16 Şubat 2026)
|
||||
|
||||
Bu bölüm, son diyalogda netleşen teknik durumları özetler:
|
||||
|
||||
1. HT/FT `.pkl` boyutu neden çok yüksek?
|
||||
|
||||
- `xgb_ht_ft.pkl` yaklaşık `313.55 MB` ölçüldü.
|
||||
- Model tipi `CalibratedClassifierCV (cv=5)` ve her fold içinde `XGBClassifier` var.
|
||||
- HT/FT marketi `9 sınıf` olduğu için ağaç sayısı katlanıyor (`n_estimators=720`, `num_class=9`, `cv=5`).
|
||||
- Sonuç: boyut büyük ama mevcut eğitim konfigürasyonuyla beklenen bir durum; zorunlu değil, yeniden eğitimle küçültülebilir.
|
||||
|
||||
2. Neden farklı `match_id` ile aynı HT/FT sonucu çıktı?
|
||||
|
||||
- DB'siz hızlı testte `match_id` feature olarak kullanılmıyor.
|
||||
- Modele aynı feature vektörü verildiği için farklı ID’lerde aynı olasılık çıktısı üretiyor.
|
||||
- Gerçek maça özel farklı sonuç için feature’ların match bazında DB’den üretilmesi gerekir.
|
||||
|
||||
3. HT/FT testini kolaylaştırmak için yapılan API güncellemesi
|
||||
|
||||
- `ai-engine/main.py` içine yeni endpoint eklendi:
|
||||
- `GET /v20plus/analyze-htft/{match_id}?timeout_sec=30`
|
||||
- Bu endpoint sadece HT/FT odaklı özet döndürür:
|
||||
- `ht_ft_probs`, `surprise_hunter`, `ht_ft_reversal_radar`, `main_pick`, `bet_summary`
|
||||
- Timeout koruması var (uzun süre asılı kalmayı engeller, timeoutta `504` döner).
|
||||
|
||||
4. DB bağlantı davranışı (localhost/127) güncellemesi
|
||||
|
||||
- `ai-engine/data/db.py` içinde host zorlaması kaldırıldı.
|
||||
- Artık `DATABASE_URL` içindeki host ne ise (`localhost`, `postgres`, vb.) aynen kullanılır.
|
||||
- `connect_timeout` ekleme mantığı korundu (`PGCONNECT_TIMEOUT`, default `5`).
|
||||
|
||||
5. Docker içi DB port düzeltmesi
|
||||
|
||||
- `docker-compose.yml` içinde container-to-container DB bağlantılarında yanlış port vardı (`15432`).
|
||||
- Düzeltilenler:
|
||||
- `app` servisi DB URL: `postgres:15432`
|
||||
- `ai-engine` servisi DB URL: `postgres:15432`
|
||||
- Not: Hosttan erişim için `127.0.0.1:15432` map’i ayrı ve doğru.
|
||||
|
||||
6. Deploy ve büyük model artefact notu
|
||||
|
||||
- GitHub dosya limiti nedeniyle büyük `.pkl` dosyaları normal push ile yönetilemeyebilir.
|
||||
- Daha doğru yaklaşım: model artefact’ı harici depodan indirmek (S3/release artifact) ve deploy sırasında bootstrap etmek.
|
||||
|
||||
---
|
||||
|
||||
## 18. Son Çalışma Güncellemesi (17 Şubat 2026) - HT/FT Analiz ve Düzeltmeler
|
||||
|
||||
Bu bölüm, kullanıcı talebiyle yapılan HT/FT odaklı tüm analiz ve kod değişikliklerini toplu özetler.
|
||||
|
||||
### 18.1 Hedef ve Kapsam
|
||||
|
||||
Hedef:
|
||||
|
||||
- `top_leagues.json` içindeki lig ID’lerine göre filtrelenmiş maçlarda HT/FT patternini çıkarmak.
|
||||
- `1/1`, `2/1`, `1/2`, `X/2` gibi sonuçların hangi koşullarda arttığını bulmak.
|
||||
- Sonucu model davranışına (kalibrasyon/öncelik dağılımı) yansıtmak.
|
||||
|
||||
Kapsam:
|
||||
|
||||
- Veri kaynağı: `matches`, `live_matches`, `odd_categories`, `odd_selections`, `leagues`, `teams`.
|
||||
- Lig filtresi: doğrudan `/Users/piton/Documents/Suggest-Bet-BE/top_leagues.json`.
|
||||
|
||||
### 18.2 Top-Leagues HT/FT Bulguları (Özet İstatistik)
|
||||
|
||||
Top leagues football örneklemi:
|
||||
|
||||
- `n = 21,069`
|
||||
|
||||
HT/FT dağılımı:
|
||||
|
||||
- `1/1: 26.43%`
|
||||
- `2/2: 16.94%`
|
||||
- `X/X: 15.85%`
|
||||
- `X/1: 14.92%`
|
||||
- `X/2: 10.57%`
|
||||
- `2/1: 2.73%`
|
||||
- `1/2: 2.30%`
|
||||
|
||||
HT -> FT geçiş:
|
||||
|
||||
- HT `1` ise FT `1`: `78.02%`
|
||||
- HT `2` ise FT `2`: `68.35%`
|
||||
- HT `X` ise FT `X`: `38.35%`, FT `1`: `36.09%`, FT `2`: `25.56%`
|
||||
|
||||
Reversal (1/2 + 2/1) devre farkına göre:
|
||||
|
||||
- Devre farkı `1`: `10.83%`
|
||||
- Devre farkı `2`: `3.18%`
|
||||
- Devre farkı `3`: `0.64%`
|
||||
|
||||
Oran (MS 1X2) ilişkisi:
|
||||
|
||||
- Home fav maçlarda `1/1` belirgin yüksek.
|
||||
- Away fav maçlarda `2/2` belirgin yüksek.
|
||||
- Favori devre geriye düşerse `2/1` veya `1/2` olasılığı belirgin artıyor.
|
||||
|
||||
Sonuç:
|
||||
|
||||
- `1/1` biası tamamen bug kaynaklı değil; veri dağılımı gerçekten `1/1` ağırlıklı.
|
||||
- Ancak odds sinyali doğru parse edilmezse model tarafsız/fallback davranıp `1/1`i gereğinden fazla öne çekebiliyor.
|
||||
|
||||
### 18.3 Kök Nedenler (Bug ve Davranış)
|
||||
|
||||
1. Odds parser market eşleşmesi fazla genişti:
|
||||
|
||||
- `Maç Sonucu` için substring kontrolü, `İlk Yarı/Maç Sonucu` gibi marketlerle çakışıyordu.
|
||||
- `2,5 Alt/Üst` kontrolü, `2,5 Kart Puanı Alt/Üst` ile çakışıyordu.
|
||||
- `Karşılıklı Gol` kontrolü, `1. Yarı Karşılıklı Gol` ile çakışıyordu.
|
||||
- Sonuç: Ana market odds’ları overwrite oluyordu.
|
||||
|
||||
2. Bazı maçlarda odds fallback defaultlarına düşülüyordu:
|
||||
|
||||
- Bu durum favori taraf sinyalini bozuyordu.
|
||||
|
||||
3. `Decimal` tipleri bazı yerlerde float bölme hatası üretiyordu:
|
||||
|
||||
- Prediction akışı kırılıyor veya testler fail oluyordu.
|
||||
|
||||
### 18.4 Yapılan Kod Değişiklikleri
|
||||
|
||||
1. HT/FT prior odds-koşullu hale getirildi (`home_fav/away_fav/balanced`):
|
||||
|
||||
- Dosya: `ai-engine/models/v20_ensemble.py`
|
||||
- Eklenenler:
|
||||
- `FOOTBALL_TOP_PRIOR_HOME_FAV`
|
||||
- `FOOTBALL_TOP_PRIOR_AWAY_FAV`
|
||||
- `FOOTBALL_TOP_PRIOR_BALANCED`
|
||||
- `_favorite_side_from_ms_odds`
|
||||
- `_get_top_odds_conditioned_prior`
|
||||
- prior blending içinde odds-koşullu prior entegrasyonu
|
||||
|
||||
2. Odds defaultları nötrleştirildi (home bias azaltımı):
|
||||
|
||||
- Dosya: `ai-engine/models/v20_ensemble.py`
|
||||
- Dosya: `ai-engine/services/single_match_orchestrator.py`
|
||||
- Dosya: `ai-engine/core/engines/odds_predictor.py`
|
||||
- Yeni default: `ms_h=2.65`, `ms_d=3.20`, `ms_a=2.65`
|
||||
|
||||
3. Odds parser tam eşleşme mantığına geçirildi:
|
||||
|
||||
- Dosya: `ai-engine/services/single_match_orchestrator.py`
|
||||
- Değişiklik:
|
||||
- substring yerine normalize + exact category match
|
||||
- `MS`, `OU15`, `OU25`, `OU35`, `BTTS`, `DC` alanları güvenli eşleşme
|
||||
|
||||
4. Decimal tip güvenliği eklendi:
|
||||
|
||||
- Dosya: `ai-engine/core/engines/odds_predictor.py`
|
||||
- `_odds_to_prob` içinde `float()` cast
|
||||
- Dosya: `ai-engine/features/sidelined_analyzer.py`
|
||||
- DB stats alanlarına (`goals/assists/starts/matches`) güvenli float cast
|
||||
|
||||
5. HT/FT config ayarları eklendi/güncellendi:
|
||||
|
||||
- Dosya: `ai-engine/config/ensemble_config.yaml`
|
||||
- Eklenen kritikler:
|
||||
- `risk.htft_prior_odds_blend_top`
|
||||
- `risk.htft_prior_odds_blend_top_with_league`
|
||||
- `risk.htft_favorite_balance_gap`
|
||||
|
||||
### 18.5 Test Komutları ve Sonuçlar
|
||||
|
||||
Kullanılan script:
|
||||
|
||||
- `python3 ai-engine/scripts/test_ht_ft_match.py --match-id <id>`
|
||||
|
||||
Örnek sonuçlar:
|
||||
|
||||
1. `Coventry vs Middlesbrough` (`8z03io3g443y73gwxbxk66590`)
|
||||
|
||||
- Top1: `1/1` (`21.12%`)
|
||||
|
||||
2. `Girona vs Barcelona` (`2elfffvt87h2apmhh2c0et3pw`)
|
||||
|
||||
- Odds doğru parse sonrası:
|
||||
- `ms_h=6.38`, `ms_d=5.24`, `ms_a=1.19` (away favori)
|
||||
- Top1 HT/FT:
|
||||
- `2/2` (`23.08%`)
|
||||
|
||||
Bu test, parser ve odds-koşullu prior düzeltmesinin çalıştığını doğrular.
|
||||
|
||||
### 18.6 Operasyonel Not
|
||||
|
||||
- HT/FT yüzdeleri `confidence` değil, sınıf olasılığıdır (`probability`).
|
||||
- Tek maçta yüzde düşükken farklı sonuç gerçekleşebilir; kalite ölçümü tek maç değil toplu backtest ile yapılmalıdır.
|
||||
|
||||
---
|
||||
|
||||
## 19. Son Çalışma Güncellemesi (17 Şubat 2026) - Veri Bütünlüğü, Type Uyumu, Uçtan Uca Test
|
||||
|
||||
Bu bölümde, `live_matches` üzerinden gelen verinin eksiksiz parse edilmesi, Python tarafındaki alanların type sözleşmesine uyumu ve tahmin paketine doğru aktarım için yapılan kritik düzeltmeler yer alır.
|
||||
|
||||
### 19.1 Hedef
|
||||
|
||||
- Oran kategori parse hatalarını engellemek.
|
||||
- Eksik takım/lineup verisinde yanlış tahmin üretimini kesmek.
|
||||
- `lineups`, `sidelined`, `referee`, `odds`, takım formu ve lig pozisyonu gibi sinyalleri tek maç analizine güvenli taşımak.
|
||||
- Python tarafındaki sözleşmeyi TypeScript/uygulama beklentisiyle uyumlu hale getirmek.
|
||||
|
||||
### 19.2 Yapılan Kod Düzeltmeleri
|
||||
|
||||
1. Team feature key eşleşmeleri düzeltildi:
|
||||
|
||||
- Dosya: `ai-engine/core/engines/team_predictor.py`
|
||||
- `possession -> avg_possession`, `shots_on_target -> avg_shots_on_target`, `corners -> avg_corners`
|
||||
|
||||
2. Sahte lineup defaultları kaldırıldı:
|
||||
|
||||
- Dosya: `ai-engine/features/squad_analysis_engine.py`
|
||||
- `or 11 / or 18` fallbackleri temizlendi; gerçek sayılar kullanılıyor.
|
||||
|
||||
3. Player predictor lineup gate ve confidence iyileştirildi:
|
||||
|
||||
- Dosya: `ai-engine/core/engines/player_predictor.py`
|
||||
- `lineup_available` artık her iki takımda da en az 11 oyuncu şartına bağlı.
|
||||
- Lineup yokken confidence daha agresif düşürülüyor; alt sınır clamp ile korunuyor.
|
||||
|
||||
4. Referee feature fallback güçlendirildi:
|
||||
|
||||
- Dosya: `ai-engine/core/engines/referee_predictor.py`
|
||||
- `match_id` ile gelen veri zayıfsa ve `referee_name` varsa isim bazlı daha güçlü örneklem seçiliyor.
|
||||
|
||||
5. Tek maç orchestrator veri sözleşmesi genişletildi:
|
||||
|
||||
- Dosya: `ai-engine/services/single_match_orchestrator.py`
|
||||
- `MatchData` eklendi:
|
||||
- `home_goals_avg`, `home_conceded_avg`, `away_goals_avg`, `away_conceded_avg`
|
||||
- `lineup_source`
|
||||
- Zorunlu gate:
|
||||
- `home_team_id` veya `away_team_id` yoksa analiz iptal (`None`).
|
||||
- Yeni yardımcılar:
|
||||
- `_calculate_team_form`
|
||||
- `_estimate_league_position`
|
||||
- `_extract_lineups` artık `(home, away, source)` döner:
|
||||
- `confirmed_live`, `confirmed_participation`, `probable_xi`, `none`
|
||||
- `market` kararlarında:
|
||||
- `probable_xi` lineup-sensitive marketlerde ceza alır.
|
||||
- Zorunlu odds eksikse market `market_odds_missing` ile playable olmaz.
|
||||
- Data quality:
|
||||
- Gerçek odds ile default odds ayrıştırılır.
|
||||
- `lineup_source` kalite ve reasoning alanına taşınır.
|
||||
|
||||
6. Testler yeni sözleşmeye göre güncellendi:
|
||||
|
||||
- Dosya: `ai-engine/tests/test_single_match_orchestrator.py`
|
||||
- Yeni testler:
|
||||
- takım id eksikse match load reject
|
||||
- required odds yoksa market block
|
||||
|
||||
### 19.3 Çalıştırılan Testler
|
||||
|
||||
- Python unit test:
|
||||
- `python3 -m unittest discover -s ai-engine/tests -v`
|
||||
- Sonuç: `19/19 PASS`
|
||||
|
||||
- Jest:
|
||||
- `npx jest --runInBand`
|
||||
- Sonuç: `2 suite / 4 test PASS`
|
||||
|
||||
- DB smoke doğrulama:
|
||||
- Team ID eksik future match artık analiz edilmiyor.
|
||||
- Complete veri içeren match normal analiz üretiyor.
|
||||
|
||||
### 19.4 Veri Kalitesi Bulgusu (Neden Bazı Maçlar Zayıf Kalıyor?)
|
||||
|
||||
- `future30` içinde `live_matches` satırlarında `league_id/home_team_id/away_team_id` çok yüksek oranda boş olabiliyor.
|
||||
- Aynı pencerede `odds/lineups/referee/sidelined` da çoğu zaman boş kalabiliyor.
|
||||
- Sonuç: model kapasitesi yüksek olsa da giriş verisi boşsa “sürpriz yakalama” veya “garanti market” üretimi sınırlanır.
|
||||
|
||||
Bu yüzden yeni yaklaşım:
|
||||
|
||||
- Eksik kritik alan varsa tahmini zorla üretme.
|
||||
- Veri kaynağını `lineup_source` gibi kalite etiketleriyle açıkça işaretle.
|
||||
- Eksik market odds varsa o marketi otomatik ele.
|
||||
|
||||
### 19.5 Basketbol Fazı (Bir Sonraki Adım Planı)
|
||||
|
||||
Futbol için kritik parse/type/quality sorunları stabilize edildi. Sıradaki odak basketbol:
|
||||
|
||||
1. Basketbol market sözlüğü ve parser matrisi:
|
||||
|
||||
- 1X2 yerine basketbola özgü marketleri (`ML`, `spread`, `total`) ayrı haritala.
|
||||
|
||||
2. Basketbol feature contract:
|
||||
|
||||
- `match_team_stats` içindeki basketbol alanlarını (pace, rebound, turnover, 3P vb.) zorunlu/opsiyonel diye netleştir.
|
||||
|
||||
3. Lineup/injury impact modeli (basketbol):
|
||||
|
||||
- İlk 5 ve rotasyon oyuncusu etkisini pozisyon ve usage ile ağırlıkla.
|
||||
|
||||
4. Basketbol için ayrı confidence calibration:
|
||||
|
||||
- Futbol kalibrasyon katsayılarını basketbola taşımadan lig bazlı yeniden ayarla.
|
||||
|
||||
5. Basketbol E2E test paketi:
|
||||
|
||||
- `live_matches -> orchestrator -> package -> market gating` zincirini basketbol maçları için ayrı fixture setiyle doğrula.
|
||||
|
||||
## 20) Swagger Endpoint Envanteri (2026-02-17)
|
||||
|
||||
### 20.1 Yapılanlar
|
||||
|
||||
1. Swagger tag kapsamı genişletildi:
|
||||
|
||||
- Dosya: `src/main.ts`
|
||||
- Eklenen tagler: `Matches`, `Leagues`, `Analysis`, `Coupon`, `Predictions`
|
||||
|
||||
2. `users/me` endpointi Swagger’da eksiksiz tanımlandı:
|
||||
|
||||
- Dosya: `src/modules/users/users.controller.ts`
|
||||
- Eklendi:
|
||||
- `@ApiOperation({ summary: 'Get current authenticated user profile' })`
|
||||
- `@ApiOkResponse({ type: UserResponseDto })`
|
||||
|
||||
3. Tüm backend endpointlerinin otomatik JSON özeti üretildi:
|
||||
|
||||
- Yeni script: `src/scripts/export-swagger-endpoints-summary.ts`
|
||||
- NPM komutu: `npm run swagger:summary`
|
||||
- Üretilen çıktı: `mds/backend_endpoints_swagger_summary.json`
|
||||
|
||||
### 20.2 JSON Özeti İçeriği
|
||||
|
||||
Üretilen JSON dosyasında her endpoint için:
|
||||
|
||||
- HTTP method + path
|
||||
- controller/method kaynak bilgisi
|
||||
- endpoint summary/description
|
||||
- auth gereksinimi (`bearer`, `@Public`)
|
||||
- path/query/header/cookie parametre tipleri
|
||||
- body şeması (Swagger’da varsa) + TypeScript body type hint
|
||||
- response status listesi + şema referansları (Swagger’da varsa) + TypeScript return type
|
||||
- tag bazlı endpoint sayıları
|
||||
|
||||
### 20.3 Not
|
||||
|
||||
- `PredictionsModule`, `AppModule` içinde `REDIS_ENABLED` koşuluna bağlı olduğu için export scripti kapsamlı envanter için `REDIS_ENABLED=true` ile Swagger dokümanı üretir.
|
||||
Reference in New Issue
Block a user