feat: league tier system + retrained V25 models (48 quality leagues)
Deploy Iddaai Backend / build-and-deploy (push) Failing after 3m56s
Deploy Iddaai Backend / build-and-deploy (push) Failing after 3m56s
- Add LeagueTier DB model and Prisma schema - Add league-tiers service (CRUD, sync, retrain trigger) - Add league-tiers controller with admin API endpoints - Add /v1/admin/retrain endpoint in AI engine (extract→train→reload pipeline) - Retrain V25 Pro with 48 quality leagues (MS accuracy: 26.9%→51.4%) - Update qualified_leagues.json (443→48 leagues) - Include V25 model files in repo for Docker deployment Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# Changelog - 2026-05-20
|
||||
|
||||
Bu dokuman, 20 Mayis 2026 tarihinde yapilan **League Tier Sistemi** calismasini ozetler. Amac: model egitiminde kullanilan ligleri kalite bazli filtreleyerek tahmin dogrulugunu artirmak.
|
||||
|
||||
## 1. Problem Analizi
|
||||
|
||||
- Model 443 lig ile egitiliyordu (DB'de toplam 1142 lig).
|
||||
- Dusuk kaliteli ligler (zayif bahis pazari, eksik veri) modelin sinyalini bozuyordu.
|
||||
- Mevcut performans: **MS %26.9** (rastgeleden kotu), **OU2.5 %57.7**, **BTTS %53.8**
|
||||
- Model hic "X" (draw) tahmini yapmiyordu — agir home bias vardi.
|
||||
- 19 gercek bahisten 5 kazanc, 14 kayip = **%26.3 win rate, -9.68 unit**
|
||||
|
||||
## 2. Cozum: League Tier Sistemi
|
||||
|
||||
Bookmaker margin (overround) analizine dayanarak 48 kaliteli lig secildi:
|
||||
|
||||
| Tier | Isim | Lig Sayisi | Kriter |
|
||||
|------|------|-----------|--------|
|
||||
| 1 | Elmas | 10 | En iyi veri kalitesi, en dusuk margin (Premier League, La Liga, Serie A vb.) |
|
||||
| 2 | Altin | 20 | Iyi veri kalitesi (Eredivisie, Ligue 2, Championship vb.) |
|
||||
| 3 | Gumus | 18 | Kabul edilebilir veri (Ekstraklasa, MLS, Liga MX vb.) |
|
||||
|
||||
## 3. Veritabani Degisiklikleri
|
||||
|
||||
### Yeni tablo: `league_tiers`
|
||||
```sql
|
||||
CREATE TABLE league_tiers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
league_id TEXT NOT NULL UNIQUE REFERENCES leagues(id) ON DELETE CASCADE,
|
||||
tier INT NOT NULL DEFAULT 1,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
added_by TEXT,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_league_tiers_tier_active ON league_tiers(tier, is_active);
|
||||
```
|
||||
|
||||
### Prisma schema guncellendi
|
||||
- `LeagueTier` modeli eklendi (`prisma/schema.prisma`)
|
||||
- `League` modeline `leagueTier LeagueTier?` iliskisi eklendi
|
||||
- Not: Migration shadow DB hatasi nedeniyle tablo dogrudan SQL ile olusturuldu
|
||||
|
||||
## 4. Backend Degisiklikleri
|
||||
|
||||
### Yeni dosyalar
|
||||
|
||||
**`src/modules/leagues/league-tiers.service.ts`**
|
||||
- `findAll()` — tum tier'lari listele
|
||||
- `findActive()` — aktif tier'lari listele
|
||||
- `findByTier(tier)` — belirli tier'daki ligler
|
||||
- `addLeague(leagueId, tier, notes, addedBy)` — lig ekle/guncelle (upsert), otomatik JSON sync + retrain tetikle
|
||||
- `removeLeague(leagueId)` — ligi pasif yap (soft delete), JSON sync
|
||||
- `updateTier(leagueId, tier)` — tier seviyesi degistir
|
||||
- `deleteLeague(leagueId)` — kalici sil
|
||||
- `syncQualifiedLeagues()` — DB'den `qualified_leagues.json` dosyasini guncelle
|
||||
- `triggerModelRetrain()` — AI engine'e POST `/v1/admin/retrain`
|
||||
- `getStats()` — tier istatistikleri + toplam qualified match sayisi
|
||||
|
||||
**`src/modules/leagues/league-tiers.controller.ts`**
|
||||
- `GET /admin/league-tiers` — listele (`?active=true` filtreli)
|
||||
- `GET /admin/league-tiers/stats` — istatistikler
|
||||
- `GET /admin/league-tiers/tier/:tier` — tier bazli filtre
|
||||
- `POST /admin/league-tiers` — lig ekle (body: `{ leagueId, tier?, notes?, addedBy? }`)
|
||||
- `PUT /admin/league-tiers/:leagueId/tier` — tier guncelle
|
||||
- `PUT /admin/league-tiers/:leagueId/deactivate` — pasif yap
|
||||
- `DELETE /admin/league-tiers/:leagueId` — kalici sil
|
||||
- `POST /admin/league-tiers/sync` — JSON sync tetikle
|
||||
- `POST /admin/league-tiers/retrain` — model retrain tetikle
|
||||
- Tum endpointler `@Roles("superadmin")` ile korumali
|
||||
|
||||
### Guncellenen dosyalar
|
||||
|
||||
**`src/modules/leagues/leagues.module.ts`**
|
||||
- `HttpModule` import eklendi (retrain HTTP cagirisi icin)
|
||||
- `LeagueTiersController` ve `LeagueTiersService` register edildi
|
||||
|
||||
## 5. qualified_leagues.json Sync
|
||||
|
||||
- Onceki durum: **443 lig**
|
||||
- Yeni durum: **48 lig** (DB'deki aktif tier'lardan)
|
||||
- `data-fetcher.task.ts` zaten bu dosyayi okuyor — yeni mac verisi sadece 48 lig icin cekilecek
|
||||
- `extract_training_data.py` zaten bu dosyayi okuyor — egitim verisi sadece 48 ligden gelecek
|
||||
|
||||
## 6. Mevcut Veri Akisi
|
||||
|
||||
```
|
||||
Admin Panel (lig ekle/cikar)
|
||||
|
|
||||
v
|
||||
LeagueTiersService.addLeague() / removeLeague()
|
||||
|
|
||||
+---> DB guncelle (league_tiers tablosu)
|
||||
+---> syncQualifiedLeagues() ---> qualified_leagues.json guncelle
|
||||
+---> triggerModelRetrain() ---> AI Engine POST /v1/admin/retrain
|
||||
|
||||
Data Fetcher (cron):
|
||||
qualified_leagues.json ---> sadece bu liglerden live_matches cek
|
||||
|
||||
Training Pipeline:
|
||||
qualified_leagues.json ---> sadece bu liglerden training_data extract et
|
||||
```
|
||||
|
||||
## 7. Yapilacaklar
|
||||
|
||||
- [ ] AI engine'de `/v1/admin/retrain` endpoint olustur (Python tarafi)
|
||||
- [ ] Modeli yeni 48 lig dataseti ile yeniden egit
|
||||
- [ ] Admin panel frontend'inde league tier yonetim UI'i
|
||||
- [ ] Draw blindness sorununu arastir (model hic X tahmini yapmiyor)
|
||||
- [ ] Prisma migration gecmisini duzelt (manual SQL → migration align)
|
||||
Reference in New Issue
Block a user