This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# Eksik Marketlerin Doğrulanması — Detaylı Özet
|
||||
|
||||
**Tarih:** 15 Mart 2026
|
||||
**Kapsam:** `ai-engine/services/single_match_orchestrator.py` ve `ai-engine/pyt/services/single_match_orchestrator.py`
|
||||
**Sonuç:** Tüm marketler zaten implement edilmişti — yalnızca 1 test güncellendi
|
||||
|
||||
---
|
||||
|
||||
## 1. Amaç
|
||||
|
||||
AI Engine'in `single_match_orchestrator.py` dosyasında **OE (Tek/Çift)**, **HTFT (İY/MS)**, **HT_OU05**, **corners**, **cards** ve **handicap** gibi marketlerin prediction pipeline'dan API response'a kadar doğru şekilde aktarılıp aktarılmadığını doğrulamak.
|
||||
|
||||
---
|
||||
|
||||
## 2. Yapılan Analiz
|
||||
|
||||
### 2.1. Odds Parsing Pipeline İncelemesi
|
||||
|
||||
Orchestrator'da iki ayrı odds parsing katmanı incelendi:
|
||||
|
||||
#### `_parse_odds_json(odds_json)`
|
||||
- **Kaynak:** Canlı maç JSON verisi (`live_matches.odds` veya `matches.odds`)
|
||||
- **Çalışma mantığı:** Market isimlerini (`"Maç Sonucu"`, `"2,5 Alt/Üst"`, vb.) regex ile eşleştirip, selection key'leri ile (`"1"`, `"X"`, `"Üst"`, `"Alt"`, vb.) değerleri parse eder
|
||||
- **Parse edilen marketler:**
|
||||
- MS (Maç Sonucu) → `ms_h`, `ms_d`, `ms_a`
|
||||
- DC (Çifte Şans) → `dc_1x`, `dc_x2`, `dc_12`
|
||||
- OU15/25/35 (Alt/Üst) → `ou15_o`, `ou15_u`, `ou25_o`, `ou25_u`, `ou35_o`, `ou35_u`
|
||||
- BTTS (Karşılıklı Gol) → `btts_y`, `btts_n`
|
||||
- HT (1. Yarı Sonucu) → `ht_h`, `ht_d`, `ht_a`
|
||||
- HT_OU05 (İY 0,5 Alt/Üst) → `ht_ou05_o`, `ht_ou05_u`
|
||||
- **OE (Tek/Çift)** → `oe_odd`, `oe_even`
|
||||
- **HTFT (İlk Yarı/Maç Sonucu)** → `htft_11`, `htft_1x`, `htft_12`, `htft_x1`, `htft_xx`, `htft_x2`, `htft_21`, `htft_2x`, `htft_22`
|
||||
- Basketbol: ML, Total, Spread, HT Total
|
||||
|
||||
#### `_parse_relational_odds(rows, parsed)`
|
||||
- **Kaynak:** `odd_categories` tablosundan gelen relational veri
|
||||
- **Çalışma mantığı:** `category_name` + `selection_name` eşleştirmesi
|
||||
- **Ek olarak parse edilen marketler:**
|
||||
- **OE** → `"Tek/Çift"` kategorisi, `"tek"/"odd"` → `oe_odd`, `"çift"/"even"` → `oe_even`
|
||||
- **HTFT** → `"İlk Yarı/Maç Sonucu"` kategorisi, `"1/1"`, `"1/X"` vb.
|
||||
|
||||
### 2.2. Market Board ve API Response İncelemesi
|
||||
|
||||
#### `_build_market_rows(data, pred)`
|
||||
- OE market row'u, prediction'da `odd_even_pick` varsa ve `oe_odd`/`oe_even` odds mevcutsa oluşturuluyor
|
||||
- 8 standart market + OE = **9 market row**
|
||||
|
||||
#### `_build_prediction_package(data, pred, ...)`
|
||||
`market_board` sözlüğü şu bölümleri içeriyor:
|
||||
|
||||
| Bölüm | İçerik |
|
||||
|--------|--------|
|
||||
| `MS` | Maç Sonucu olasılıkları |
|
||||
| `DC` | Çifte Şans |
|
||||
| `OU25` | 2.5 Alt/Üst |
|
||||
| `BTTS` | Karşılıklı Gol |
|
||||
| `HT` | İlk Yarı Sonucu |
|
||||
| **`OE`** | Tek/Çift olasılıkları |
|
||||
| **`HT_OU05`** | İY 0.5 Alt/Üst |
|
||||
| **`others`** | Köşe, kart, handicap tahminleri |
|
||||
|
||||
#### `others` Bölümü
|
||||
```python
|
||||
"others": {
|
||||
"corner_pick": pred.corner_pick,
|
||||
"corner_confidence": pred.corner_confidence,
|
||||
"card_pick": pred.card_pick,
|
||||
"card_confidence": pred.card_confidence,
|
||||
"handicap_pick": getattr(pred, "handicap_pick", None),
|
||||
"handicap_confidence": getattr(pred, "handicap_confidence", None),
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Sonuç: Tüm Marketler Zaten Kodlanmıştı
|
||||
|
||||
Implementation plan'daki 6 maddenin tamamı **her iki orchestrator dosyasında da** (`pyt/services/` ve root `services/`) mevcut:
|
||||
|
||||
| # | Özellik | Dosya Konumları | Durum |
|
||||
|---|---------|-----------------|-------|
|
||||
| 1 | OE odds parsing (`_parse_odds_json`) | `pyt`: satır 1305-1307, `root`: satır 1572 | ✅ |
|
||||
| 2 | OE odds parsing (`_parse_relational_odds`) | `pyt`: satır 1403-1407, `root`: satır 1671 | ✅ |
|
||||
| 3 | HTFT odds parsing (her iki parser) | `pyt`: satır 1308-1317 / 1408-1415 | ✅ |
|
||||
| 4 | OE odds wiring (`_build_market_rows`) | `pyt`: satır 2367-2373, `root`: satır 2670 | ✅ |
|
||||
| 5 | OE + HT_OU05 (`market_board`) | `pyt`: satır 1826-1839 | ✅ |
|
||||
| 6 | `others` section (corners/cards/handicap) | `pyt`: satır 1841-1851, `root`: satır 2111 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 4. Yapılan Tek Kod Değişikliği: Test Güncellemesi
|
||||
|
||||
**Dosya:** `ai-engine/tests/test_single_match_orchestrator.py`
|
||||
|
||||
### Sorun
|
||||
`test_parse_odds_json_uses_exact_market_match_and_ignores_collisions` testi, HTFT parsing henüz yokken yazılmıştı. Test şu assertion'ı içeriyordu:
|
||||
|
||||
```python
|
||||
self.assertNotIn("htft_11", parsed) # HTFT parse edilmemeli
|
||||
```
|
||||
|
||||
HTFT parsing artık aktif olduğu için bu assertion başarısız oluyordu.
|
||||
|
||||
### Düzeltme
|
||||
```diff
|
||||
- self.assertNotIn("htft_11", parsed)
|
||||
+ self.assertEqual(parsed["htft_11"], 4.30)
|
||||
```
|
||||
|
||||
Test verisi `"İlk Yarı/Maç Sonucu": {"1/1": "4.30"}` içerdiği için, HTFT parser bu değeri doğru şekilde `htft_11 = 4.30` olarak alıyor.
|
||||
|
||||
---
|
||||
|
||||
## 5. Test Sonuçları
|
||||
|
||||
```
|
||||
17 passed in 1.51s
|
||||
```
|
||||
|
||||
Tüm birim testleri başarılı ✅
|
||||
|
||||
---
|
||||
|
||||
## 6. Önemli Notlar
|
||||
|
||||
### Dosya Senkronizasyonu
|
||||
Projede orchestrator'ın **iki kopyası** bulunuyor:
|
||||
- `ai-engine/pyt/services/single_match_orchestrator.py` — Docker/production kopyası
|
||||
- `ai-engine/services/single_match_orchestrator.py` — Root/development kopyası
|
||||
|
||||
Her iki dosya da aynı implementasyonu içeriyor.
|
||||
|
||||
### Market Akışı (End-to-End)
|
||||
```
|
||||
Mackolik (web scraping)
|
||||
→ live_matches.odds (JSON) / odd_categories (relational)
|
||||
→ _parse_odds_json() / _parse_relational_odds()
|
||||
→ odds_data dict (ms_h, oe_odd, htft_11, ...)
|
||||
→ _build_market_rows() → market bazlı satırlar
|
||||
→ _build_prediction_package() → market_board + others
|
||||
→ NestJS API → Frontend
|
||||
```
|
||||
|
||||
### Parse Edilen Tüm Odds Key'leri
|
||||
|
||||
**Futbol:**
|
||||
| Grup | Key'ler |
|
||||
|------|---------|
|
||||
| MS | `ms_h`, `ms_d`, `ms_a` |
|
||||
| DC | `dc_1x`, `dc_x2`, `dc_12` |
|
||||
| OU | `ou15_o/u`, `ou25_o/u`, `ou35_o/u` |
|
||||
| BTTS | `btts_y`, `btts_n` |
|
||||
| HT | `ht_h`, `ht_d`, `ht_a` |
|
||||
| HT_OU05 | `ht_ou05_o`, `ht_ou05_u` |
|
||||
| OE | `oe_odd`, `oe_even` |
|
||||
| HTFT | `htft_11`, `htft_1x`, `htft_12`, `htft_x1`, `htft_xx`, `htft_x2`, `htft_21`, `htft_2x`, `htft_22` |
|
||||
|
||||
**Basketbol:**
|
||||
| Grup | Key'ler |
|
||||
|------|---------|
|
||||
| ML | `ml_h`, `ml_a` |
|
||||
| Total | `tot_line`, `tot_o`, `tot_u` |
|
||||
| Spread | `spread_home_line`, `spread_h`, `spread_a` |
|
||||
| HT Total | `ht_tot_line`, `ht_tot_o`, `ht_tot_u` |
|
||||
Reference in New Issue
Block a user