Files
iddaai-be/mds/archive/02_deep_fixes_log.md
T
fahricansecer 2f0b85a0c7
Deploy Iddaai Backend / build-and-deploy (push) Failing after 18s
first (part 2: other directories)
2026-04-16 15:11:25 +03:00

4.3 KiB
Executable File
Raw Blame History

Derin Teknik Düzeltmeler ve Analiz Günlüğü

Dosya: 02_deep_fixes_log.md Amaç: Son geliştirme döngüsünde çözülen karmaşık sorunların teknik detaylarını belgelemek.


1. Live Match Synchronization & DB Safety

Sorun Tanımı

Canlı maçlar (Live Matches), ana matches tablosuna henüz işlenmemiş olabiliyor. Ancak sistem bunları analiz etmeye çalıştığında:

  1. match_player_participation tablosuna oyuncu eklemeye çalışıyor -> matches tablosunda ID olmadığı için Foreign Key Constraint Error alıyordu.
  2. Veri tabana yazılamadığı için Python scripti "Lineup not found" hatasıyla patlıyordu.

Uygulanan Çözüm

Dual-Persistence Strategy (Çift Yazma Stratejisi):

  • Logic: FeederPersistenceService.saveLineups ve saveOdds metodları artık önce matches tablosunda matchId var mı diye kontrol ediyor.
  • Varsa: Hem ilişkisel tablolara (match_player_participation) hem de live_matches JSON kolonuna yazıyor.
  • Yoksa (Sadece Canlı): İlişkisel tabloları tamamen pas geçiyor (SKIP), veriyi sadece live_matches.lineups ve live_matches.odds JSON kolonlarına strüktüre edilmiş olarak yazıyor.

Fallback Mechanism (Python & NestJS):

  • NestJS: getPlayerCount metodu önce ilişkisel tabloyu sayıyor. Sayı 0 ise live_matches JSON'ını parse edip oradaki oyuncu sayısını dönüyor.
  • Python: _run_model içinde önce SQL sorgusu ile kadro çekmeye çalışıyor. Liste boşsa, live_matches tablosundaki JSON kolonunu çekip manuel parse ediyor.

2. Model Score & Context Mapping (Kritik)

Sorun Tanımı

Kullanıcı, modelin skor tahminlerinin ve maç sonucu (1/X/2) tercihlerinin tutarsız olduğundan şikayetçiydi ("Home win diyor ama skor 0-1" gibi).

Tespit Edilen Kök Nedenler

  1. HT/FT Sıralaması: Model eğitimi ht*3 + ft (0=X, 1=1, 2=2) mantığıyla yapılmıştı. Ancak tahmin scripti etiketleri 1/1, 1/X... gibi rastgele bir sırayla diziyordu. Bu yüzden 1/1 tahmini X/X gibi görünüyordu.
  2. Beraberlik (Draw) Körlüğü: Data Feeder, beraberlik oranını X etiketiyle kaydediyordu (Mackolik verisi). Python scripti ise sadece 0 etiketini "Beraberlik" olarak kabul ediyordu. Sonuç olarak model "Beraberlik Oranı: 0.0" görüyordu (yani oran yok). Bu, modelin maçın dengesini yanlış anlamasına neden oluyordu.
  3. Away Bias (Deplasman Yanlılığı): Backtest verileri, modelin sistematik olarak deplasman takımına fazla gol yazdığını (%15-20 fazla) gösterdi.

Uygulanan Çözüm

  1. Etiket Düzeltmesi: htft_labels listesi [X/X, X/1, X/2, 1/X, 1/1, 1/2, 2/X, 2/1, 2/2] olarak, eğitim verisiyle %100 uyumlu hale getirildi.
  2. Oran Normalizasyonu: Python scripti artık hem 0 hem X etiketlerini beraberlik oranı olarak kabul ediyor.
  3. Skor Kalibrasyonu: Backtest sonrası optimizasyon katsayıları eklendi.
    • HOME_GOAL_SCALE = 1.00
    • AWAY_GOAL_SCALE = 0.85

3. Akıllı Kupon Servisi (Smart Coupon)

Yapı

NestJS tarafında SmartCouponService ve Python tarafında smart_coupon_service.py (CLI) işbirliği ile çalışır.

Akış

  1. Request: POST /api/coupon/analyze-match { matchId }
  2. Pre-Check 1 (Kadro): DB'de kadro var mı?
    • Yoksa -> FeederService.refreshMatch(lineups) -> Tekrar kontrol -> Hâlâ yoksa Hata Fırlat ("Yetersiz Veri").
  3. Pre-Check 2 (Oran): DB'de oran var mı?
    • Yoksa -> FeederService.refreshMatch(odds) -> Log bas (Engelleyici değil).
  4. Prediction: Python scripti çalıştırılır (--analyze --json).
    • Script: DB veya JSON Fallback'ten veriyi okur.
    • Script: Modeli çalıştırır, kalibrasyon katsayılarını uygular.
    • Script: JSON döner.
  5. Response: NestJS JSON'ı parse edip kullanıcıya döner.

Gelecek İçin Notlar

  • Database: live_matches tablosundaki JSON kolonları artık kritik öneme sahip. Bunların şeması Prisma tarafında Json olarak tanımlı ama iç yapısı kod içinde (FeederPersistence) belirleniyor. Yapıyı değiştirirken dikkatli olunmalı.
  • Model: V17 modeli şu an stabil. V18'e geçilirse player_model_v17.py değiştirilmeli ve smart_coupon_service.py içindeki scale faktörleri sıfırlanıp tekrar backtest yapılmalı.