# 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` |