Files
iddaai-be/project_summary.md
fahricansecer 7814e0bc6b
Deploy Iddaai Backend / build-and-deploy (push) Failing after 4s
first (part 1: root files)
2026-04-16 15:09:10 +03:00

790 lines
32 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Suggest-Bet-BE — Comprehensive Project Summary
> **Son güncelleme:** 2026-03-12
> **Bu doküman**, projeyi hiç bilmeyen bir AI veya geliştiricinin projeyi A-Z anlaması için hazırlanmıştır.
---
## 1. Proje Amacı ve Genel Bakış
**Suggest-Bet-BE**, yapay zeka destekli bir **spor bahis tahmin ve analiz platformu** backend servisidir. Platform, kullanıcılara:
- Futbol ve basketbol maçları için **AI destekli tahminler** sunar
- Akıllı **kupon önerileri** oluşturur (SAFE, BALANCED, AGGRESSIVE, VALUE, MIRACLE stratejileri)
- **Canlı skor takibi** ve **oran izleme** sağlar
- **Mackolik.com** üzerinden veri scraping ile güncel ve tarihsel maç verileri toplar
- **Google Gemini AI** ile doğal dil maç yorumu üretir
- Kullanıcı kuponlarını kaydeder ve sonuçlarını takip eder (ROI, Win Rate)
### Teknoloji Stack
| Katman | Teknoloji |
|--------|-----------|
| **Backend (API)** | NestJS 11 (TypeScript) |
| **AI Engine** | Python FastAPI (v20+) |
| **Veritabanı** | PostgreSQL 16 + Prisma ORM |
| **Kuyruk** | BullMQ + Redis (Opsiyonel) |
| **Cache** | Redis veya In-Memory fallback |
| **Auth** | JWT + Passport (Access + Refresh Token) |
| **AI** | Google Gemini API, Custom Python ML Engine |
| **Scraping** | Axios + Cheerio (Mackolik HTML parsing) |
| **Loglama** | Pino (Structured Logging) |
| **i18n** | nestjs-i18n (TR, EN) |
| **API Docs** | Swagger (NestJS/Swagger) |
| **Deploy** | Docker + Docker Compose |
| **Social** | Twitter API v2 (Social poster) |
---
## 2. Mimari Genel Bakış
```
┌──────────────────────────────────────────────────────────────────┐
│ CLIENTS (Web/Mobile) │
└───────────────────────────────┬──────────────────────────────────┘
│ HTTP/REST
┌───────────────────────────────▼──────────────────────────────────┐
│ NestJS Backend (Port 3005) │
│ ┌─────────┬──────────┬──────────┬──────────┬─────────────────┐ │
│ │ Auth │ Admin │ Matches │ Leagues │ Predictions │ │
│ │ Module │ Module │ Module │ Module │ Module │ │
│ ├─────────┼──────────┼──────────┼──────────┼─────────────────┤ │
│ │ Coupons │ Analysis │ Gemini │ Social- │ Health │ │
│ │ Module │ Module │ Module │ Poster │ Module │ │
│ └─────────┴──────────┴──────────┴──────────┴─────────────────┘ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Services: AiService | MatchAnalysis | Scraper │ │
│ ├──────────────────────────────────────────────────────────────┤ │
│ │ Tasks: DataFetcher (Cron) | LiveUpdater | LimitResetter │ │
│ ├──────────────────────────────────────────────────────────────┤ │
│ │ Feeder: FeederService | Scraper | Transformer | Persistence│ │
│ └──────────────────────────────────────────────────────────────┘ │
└────┬─────────────────┬────────────────────┬──────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌──────────────┐ ┌──────────────────┐
│PostgreSQL│ │ Redis/BullMQ │ │ AI Engine (py) │
│ (3.6GB) │ │ (Opsiyonel) │ │ FastAPI:8000 │
└─────────┘ └──────────────┘ └──────────────────┘
┌───────▼───────┐
│ Mackolik API │
│ (Veri Kaynağı) │
└───────────────┘
```
---
## 3. Veritabanı Şeması (27 Tablo)
### 3.1 Enum'lar
| Enum | Değerler |
|------|----------|
| `Sport` | `football`, `basketball` |
| `UserRole` | `user`, `superadmin` |
| `SubscriptionStatus` | `free`, `active`, `expired` |
| `PlayerPosition` | `goalkeeper`, `defender`, `midfielder`, `striker` |
| `EventType` | `goal`, `card`, `substitute` |
| `MatchPosition` | `home`, `away` |
### 3.2 Temel Tablolar ve İlişkileri
#### Spor Verileri (Büyük Tablolar)
| Tablo | Kayıt (~) | Açıklama |
|-------|-----------|----------|
| `matches` | 237K | Kalıcı maç kayıtları (finished maçlar) |
| `live_matches` | 82 | Aktif/yaklaşan canlı maçlar (günlük döngüsel) |
| `match_player_participation` | 3.3M | Oyuncu maç katılımları (ilk 11 + yedek) |
| `match_player_events` | 1.5M | Maç olayları (gol, kart, oyuncu değişikliği) |
| `match_player_stats` | 345K | Oyuncu istatistikleri (basketbol odaklı) |
| `match_team_stats` | 311K | Takım istatistikleri (possession, shots, basketbol box score) |
| `match_officials` | — | Hakem bilgileri |
| `match_ai_features` | — | AI feature vektörleri (ELO, form skoru, eksik oyuncu etkisi) |
#### Oran/Bahis Verileri
| Tablo | Kayıt (~) | Açıklama |
|-------|-----------|----------|
| `odd_categories` | 3.2M | Bahis kategorileri (Maç Sonucu, Alt/Üst vb.) |
| `odd_selections` | 8.5M | Bahis seçimleri (1, X, 2, Alt, Üst vb.) ve oranları |
| `odds_history` | — | Oran değişim geçmişi |
#### Referans Verileri
| Tablo | Kayıt (~) | Açıklama |
|-------|-----------|----------|
| `countries` | 160 | Ülkeler |
| `leagues` | 1,505 | Ligler (Süper Lig, Premier League vb.) |
| `teams` | 19,595 | Takımlar |
| `players` | 217K | Oyuncular |
| `official_roles` | — | Hakem rolleri |
#### Kullanıcı ve Sistem
| Tablo | Açıklama |
|-------|----------|
| `users` | Kullanıcı hesapları (email, role, subscription) |
| `refresh_tokens` | JWT refresh tokenları |
| `usage_limits` | Günlük analiz/kupon kullanım limitleri |
| `user_coupons` | Kullanıcı kuponları (PENDING/WON/LOST) |
| `user_coupon_items` | Kupon içindeki tekil bahisler |
| `analyses` | Kullanıcı analiz geçmişi (JSON) |
| `predictions` | AI tahmin cache (6 saat TTL) |
| `ai_predictions_log` | AI tahmin logları (accuracy tracking) |
| `app_settings` | Uygulama ayarları (key-value) |
| `translations` | Çeviri verileri (DB-tabanlı i18n) |
### 3.3 Kritik İlişkiler
```
Country 1──N League 1──N Match N──1 Team (home/away)
Match 1──N OddCategory 1──N OddSelection 1──N OddsHistory
Match 1──N MatchPlayerParticipation N──1 Player
Match 1──N MatchPlayerEvents N──1 Player
Match 1──1 Prediction
Match 1──1 MatchAiFeature
User 1──N Analysis
User 1──N UserCoupon 1──N UserCouponItem N──1 Match
User 1──1 UsageLimit
```
---
## 4. NestJS Modülleri (12 Modül)
### 4.1 Auth Module (`src/modules/auth/`)
JWT tabanlı kimlik doğrulama sistemi.
| Dosya | Açıklama |
|-------|----------|
| `auth.controller.ts` | Register, Login, Refresh, Logout endpointleri |
| `auth.service.ts` | bcrypt ile şifre hash, JWT token üretimi, refresh token yönetimi |
| `guards/auth.guards.ts` | `JwtAuthGuard`, `RolesGuard`, `PermissionsGuard` (global) |
| `strategies/jwt.strategy.ts` | Passport JWT strategy |
| `dto/auth.dto.ts` | `RegisterDto`, `LoginDto`, `RefreshTokenDto`, `TokenResponseDto` |
**Akış:** Register → Password hash (bcrypt, 12 rounds) → User + UsageLimit oluştur → JWT Access (15m) + Refresh Token (7d) üret
### 4.2 Admin Module (`src/modules/admin/`)
Superadmin yönetim paneli. `@Roles('superadmin')` decorator ile korunur.
**Fonksiyonlar:**
- **Kullanıcı yönetimi:** Listeleme, detay, rol değiştirme, abonelik güncelleme, aktif/pasif toggle, soft delete
- **App Settings:** Key-value ayar okuma/yazma (Redis cache ile)
- **Usage Limits:** Tüm kullanıcı limitlerini listeleme ve toplu sıfırlama
- **Analytics:** Toplam kullanıcı, aktif, premium, maç ve tahmin sayıları
### 4.3 Matches Module (`src/modules/matches/`)
Maç listeleme ve detay servisi.
| Metot | Açıklama |
|-------|----------|
| `findMatches()` | Filtreleme (sport, league, status, date, team) ile maç arama. `live_matches` tablosundan |
| `findUpcomingMatches()` | Kupon üretici için yaklaşan maçları bulma (son 24 saat dahil) |
| `getMatchesAndStructureByIds()` | Maçları lig bazında grupla, odds JSON'ı yapılandır, frontend formatına dönüştür |
| `getActiveLeagues()` | Raw SQL ile aktif ligleri ve canlı maç sayılarını getir (Mackolik-tarzı öncelik sıralama) |
| `listMatches()` | Sayfalı maç listesi (`matches` tablosundan) |
| `getMatchDetailsById()` | Tam maç detayı: kadro, istatistik, oran, olaylar. Önce `matches`, bulamazsa `live_matches` |
**Önemli:** Takım logoları için `https://file.mackolikfeeds.com/teams/{teamId}` URL şablonu kullanılır.
### 4.4 Leagues Module (`src/modules/leagues/`)
Lig, ülke ve takım keşif servisi.
**Fonksiyonlar:** Ülke listesi, Lig listesi (sport filtre), Takım arama, Takım detay, Takım son maçları, Head-to-head karşılaştırma
### 4.5 Predictions Module (`src/modules/predictions/`)
AI tahmin servisi. **Redis/BullMQ gerektirir** (conditional module loading).
| Dosya | Açıklama |
|-------|----------|
| `predictions.controller.ts` | health, upcoming, value-bets, history, getPrediction, generate, smart-coupon |
| `predictions.service.ts` | BullMQ kuyruğu ile tahmin işleme, cache (6 saat TTL, v20plus model check) |
| `queues/predictions.queue.ts` | BullMQ kuyruk yöneticisi |
| `queues/predictions.processor.ts` | Kuyruk işleyici (worker) |
| `services/ai-feature-store.service.ts` | AI feature hesaplama (V17, şu an devre dışı) |
**Akış:** İstek → Cache kontrolü (Prediction tablosu, 6 saat TTL) → BullMQ kuyruğa ekle → AI Engine çağır → Sonuç cache'le
### 4.6 Coupons Module (`src/modules/coupons/`)
Akıllı kupon üretici ve kullanıcı kupon yönetimi.
| Servis | Açıklama |
|--------|----------|
| `SmartCouponService` | AI Engine v20+ ile maç analizi, kupon üretimi, Gemini ile Türkçe yorum. 5 strateji destekler |
| `UserCouponService` | Kupon oluşturma, bahis settlement (MS 1/X/2, Alt/Üst, KG Var/Yok), kullanıcı istatistikleri (ROI, Win Rate) |
| `CouponsService` | Legacy servis (şu an boş) |
**Kupon Stratejileri:**
- `SAFE` — Düşük risk, yüksek güvenilirlik (%78+ confidence, 2 maç)
- `BALANCED` — Orta risk/oran dengesi
- `AGGRESSIVE` — Yüksek oran, düşük güvenilirlik
- `VALUE` — EV+ (Expected Value pozitif) bahisler
- `MIRACLE` — Çok yüksek oran, çok düşük güvenilirlik
### 4.7 Analysis Module (`src/modules/analysis/`)
Maç analiz orkestratörü.
**Fonksiyonlar:**
- `analyzeCoupon()` — Çoklu maç analizi. URL parse → Scrape → AI Engine çağrısı
- `checkUsageLimit()` — Free (10 analiz/3 kupon) vs Premium (50 analiz/10 kupon) limit kontrolü
- `recordUsage()` — Kullanım kaydı
- `getAnalysisHistory()` — Analiz geçmişi
### 4.8 Gemini Module (`src/modules/gemini/`)
Google Gemini AI entegrasyonu. `ENABLE_GEMINI=true` ve `GOOGLE_API_KEY` gerektirir.
**API'ler:**
- `generateText()` — Tek prompt ile metin üretimi
- `chat()` — Multi-turn sohbet
- `generateJSON<T>()` — Yapısal JSON üretimi (schema destekli)
**Kullanım:** Maç yorumu üretimi (SmartCouponService içinde, Türkçe, bahis terminolojisi ile)
### 4.9 Social Poster Module (`src/modules/social-poster/`)
Sosyal medya paylaşım sistemi (Twitter).
| Servis | Açıklama |
|--------|----------|
| `twitter.service.ts` | Twitter API v2 ile tweet gönderimi |
| `image-renderer.service.ts` | Canvas ile tahmin kartı görsel üretimi |
| `caption-generator.service.ts` | Gemini ile paylaşım metni üretimi |
| `social-poster.service.ts` | Orkestratör: tahmin → görsel → metin → paylaş |
| `meta.service.ts` | Meta (Instagram/Facebook) entegrasyonu (yapılacak) |
### 4.10 Feeder Module (`src/modules/feeder/`)
Tarihsel veri toplama sistemi (Mackolik scraping).
| Servis | Açıklama |
|--------|----------|
| `feeder.service.ts` | Ana orkestratör. Tarihsel tarama (2023-06-01'den bugüne), ters kronolojik, resume desteği |
| `feeder-scraper.service.ts` | HTTP istekleri: livescores, match header, key events, stats, lineups, odds |
| `feeder-transformer.service.ts` | Ham veriyi DB modeline dönüştürme |
| `feeder-persistence.service.ts` | Prisma ile veritabanına kayıt, duplicate kontrolü, state yönetimi |
**Konfigürasyon:** Concurrency=20, 300ms delay, 50 max retry, 502 exponential backoff
### 4.11 Health Module (`src/modules/health/`)
Sistem sağlık kontrolleri: liveness, readiness, AI Engine health.
### 4.12 Users Module (`src/modules/users/`)
Kullanıcı CRUD operasyonları. BaseController/BaseService kalıtımı ile generic yapı.
---
## 5. Servisler (`src/services/`)
| Servis | Dosya | Açıklama |
|--------|-------|----------|
| **AiService** | `ai.service.ts` | Python AI Engine bridge. `POST /v20plus/analyze/{matchId}` çağırır, response'u frontend kontratına map'ler. Analysis strategy üretir (oran bazlı taktik) |
| **MatchAnalysisService** | `match-analysis.service.ts` | 7 fazlı analiz orkestratörü: URL Parse → Scrape → Python Engine → Strategy → Similar Matches → Final Prediction → DB Save |
| **ScraperService** | `scraper.service.ts` | Mackolik HTML scraping: Cheerio ile `data-settings` ve `window.dataLayer` parse. Odds, lineup, stats, event çekimi |
---
## 6. Zamanlanmış Görevler (`src/tasks/`)
| Görev | Cron | Açıklama |
|-------|------|----------|
| `DataFetcherTask.fetchLiveMatches()` | `*/15 * * * *` | Mackolik API'den futbol maçlarını çek, `live_matches` tablosuna yaz. Top league filtresi |
| `DataFetcherTask.fetchOddsForPreMatches()` | `*/15 * * * *` | Başlamamış maçların oranlarını çek (futbol + basketbol). Retry logic (502/timeout) |
| `DataFetcherTask.fetchBasketballMatches()` | Manuel | Basketbol maçlarını çek. `basketball_top_leagues.json` filtresi |
| `LiveUpdaterTask.updateLiveScores()` | `*/15 * * * *` | Canlı maç skorlarını güncelle (Mackolik match-info API) |
| `LiveUpdaterTask.finalizeFinishedMatches()` | `*/30 * * * *` | Bitmiş maçları `live_matches``matches` tablosuna migrate et |
| `LimitResetterTask.resetUsageLimits()` | `0 3 * * *` | Günlük kullanım limitlerini sıfırla (03:00 Istanbul) |
| `LimitResetterTask.cleanupOldData()` | `0 4 * * *` | 30 günlük AI logları sil, 1 günlük bitmiş live_matches sil |
| `LimitResetterTask.checkSubscriptions()` | `0 0 * * *` | Süresi dolmuş abonelikleri `expired` yap |
---
## 7. AI Engine (Python/FastAPI) — `ai-engine/`
Bağımsız Python mikro servis. Default port: `8000`.
### 7.1 Endpointler
| Method | Endpoint | Açıklama |
|--------|----------|----------|
| `POST` | `/v20plus/analyze/{match_id}` | Tekil maç analizi (ana endpoint) |
| `GET` | `/v20plus/analyze-htms/{match_id}` | İlk yarı - Maç sonu analizi |
| `GET` | `/v20plus/analyze-htft/{match_id}` | HT/FT olasılıkları (timeout destekli) |
| `POST` | `/v20plus/coupon` | Akıllı kupon üretimi (strateji + filtreleme) |
| `GET` | `/v20plus/daily-banker` | Günün banko maçları |
| `GET` | `/v20plus/reversal-watchlist` | Score reversal izleme listesi |
| `GET` | `/health` | Sağlık kontrolü |
### 7.2 Mimari
```
ai-engine/
├── main.py # FastAPI app, route tanımları
├── services/
│ └── single_match_orchestrator.py # V20+ ana orkestratör (singleton)
├── core/ # Çekirdek algoritmalar
├── features/ # Feature engineering
├── models/ # ML modelleri
├── training/ # Model eğitim scriptleri
├── config/ # Konfigürasyon
├── utils/ # Yardımcı fonksiyonlar
└── tests/ # Test dosyaları
```
### 7.3 Tahmin Çıktı Yapısı (SingleMatchPredictionPackage)
```typescript
{
model_version: "v20plus.X",
match_info: { match_id, match_name, home_team, away_team, league, match_date_ms },
data_quality: { label: "HIGH"|"MEDIUM"|"LOW", score, flags, lineup_counts },
risk: { level: "LOW"|"MEDIUM"|"HIGH"|"EXTREME", score, is_surprise_risk, warnings },
engine_breakdown: { team, player, odds, referee }, // 4 motor ağırlığı
main_pick: { market, pick, probability, confidence, odds, bet_grade, edge, ... },
value_pick: { ... },
bet_advice: { playable, suggested_stake_units, reason },
bet_summary: [{ market, pick, raw_confidence, calibrated_confidence, bet_grade, ... }],
supporting_picks: [...],
aggressive_pick: { market, pick, probability, confidence, odds },
scenario_top5: [{ score, prob }],
score_prediction: { ft, ht, xg_home, xg_away, xg_total },
market_board: { ... },
reasoning_factors: ["..."],
ai_commentary: "Gemini üretimi Türkçe yorum"
}
```
---
## 8. API Endpointleri (50 Toplam)
### Auth (4 endpoint) — Public
| Method | Path | Açıklama |
|--------|------|----------|
| `POST` | `/api/auth/register` | Kayıt ol |
| `POST` | `/api/auth/login` | Giriş yap |
| `POST` | `/api/auth/refresh` | Token yenile |
| `POST` | `/api/auth/logout` | Çıkış yap (refresh token invalid) |
### Users (5 endpoint) — Auth gerekli
| Method | Path | Açıklama |
|--------|------|----------|
| `GET` | `/api/users` | Kullanıcı listesi |
| `GET` | `/api/users/:id` | Kullanıcı detay |
| `PUT` | `/api/users/:id` | Kullanıcı güncelle |
| `POST` | `/api/users/:id/restore` | Silinmiş kullanıcıyı geri al |
### Admin (11 endpoint) — Superadmin
| Method | Path | Açıklama |
|--------|------|----------|
| `GET` | `/api/admin/users` | Tüm kullanıcılar (paginated) |
| `GET` | `/api/admin/users/:id` | Kullanıcı detay |
| `PUT` | `/api/admin/users/:id/role` | Rol değiştir |
| `PUT` | `/api/admin/users/:id/subscription` | Abonelik güncelle |
| `PUT` | `/api/admin/users/:id/toggle-active` | Aktif/Pasif toggle |
| `DELETE` | `/api/admin/users/:id` | Soft-delete |
| `GET` | `/api/admin/settings` | Tüm ayarlar |
| `PUT` | `/api/admin/settings/:key` | Ayar güncelle |
| `GET` | `/api/admin/usage-limits` | Kullanım limitleri |
| `POST` | `/api/admin/usage-limits/reset-all` | Toplu limit sıfırla |
| `GET` | `/api/admin/analytics/overview` | Sistem istatistikleri |
### Matches (4 endpoint) — Public
| Method | Path | Açıklama |
|--------|------|----------|
| `GET` | `/api/matches` | Maç listesi (paginated) |
| `POST` | `/api/matches/query` | Gelişmiş maç sorgusu (filtreleme) |
| `GET` | `/api/matches/leagues/active` | Aktif ligler (cached 1dk) |
| `GET` | `/api/matches/:id` | Maç detayı (kadro, stat, oran, olaylar) |
### Leagues (8 endpoint) — Public
| Method | Path | Açıklama |
|--------|------|----------|
| `GET` | `/api/leagues` | Tüm ligler |
| `GET` | `/api/leagues/:id` | Lig detay |
| `GET` | `/api/leagues/countries` | Ülke listesi |
| `GET` | `/api/leagues/countries/:id` | Ülke detay + ligleri |
| `GET` | `/api/leagues/teams/search` | Takım arama |
| `GET` | `/api/leagues/teams/:id` | Takım detay |
| `GET` | `/api/leagues/teams/:id/matches` | Takım son maçları |
| `GET` | `/api/leagues/teams/h2h` | Head-to-head |
### Analysis (2 endpoint) — Auth gerekli
| Method | Path | Açıklama |
|--------|------|----------|
| `POST` | `/api/analysis/analyze-matches` | Çoklu maç analizi |
| `GET` | `/api/analysis/history` | Analiz geçmişi |
### Coupon (6 endpoint) — Mixed
| Method | Path | Açıklama |
|--------|------|----------|
| `POST` | `/api/coupon/analyze-match` | Tekil maç analizi (V20) — Public |
| `POST` | `/api/coupon/daily-banko` | Günün bankosu (2 maç, %78+) — Public |
| `POST` | `/api/coupon/suggest` | Akıllı kupon öner (5 strateji) — Public |
| `POST` | `/api/coupon/create` | Kupon kaydet — Auth |
| `GET` | `/api/coupon/my-stats` | Kullanıcı istatistikleri — Auth |
| `GET` | `/api/coupon/history` | Kupon geçmişi — Auth |
### Predictions (7 endpoint) — Requires Redis
| Method | Path | Açıklama |
|--------|------|----------|
| `GET` | `/api/predictions/health` | AI Engine health |
| `GET` | `/api/predictions/upcoming` | Yaklaşan tahminler |
| `GET` | `/api/predictions/value-bets` | EV+ fırsatları |
| `GET` | `/api/predictions/history` | Tahmin geçmişi & doğruluk |
| `GET` | `/api/predictions/:matchId` | Tekil maç tahmini (cached) |
| `POST` | `/api/predictions/generate` | Tahmin üret |
| `POST` | `/api/predictions/smart-coupon` | Smart Coupon (V20 AI) |
### Health (3 endpoint) — Public
| Method | Path | Açıklama |
|--------|------|----------|
| `GET` | `/api/health` | Readiness |
| `GET` | `/api/health/live` | Liveness |
| `GET` | `/api/health/detail` | Detaylı sağlık |
---
## 9. Common Layer (`src/common/`)
| Dosya | Açıklama |
|-------|----------|
| `base/base.service.ts` | Generic BaseService<T> (findAll, findOne, create, update, delete) |
| `base/base.controller.ts` | Generic BaseController<T> (CRUD endpointleri) |
| `decorators/index.ts` | `@Public()`, `@Roles()`, `@CurrentUser()` decoratorları |
| `dto/pagination.dto.ts` | `PaginationDto` — page, limit, sortBy, sortOrder, search |
| `filters/global-exception.filter.ts` | GlobalExceptionFilter — HTTP 200 wrapper, dev stack trace, i18n error keys |
| `interceptors/response.interceptor.ts` | ResponseInterceptor — Standart API response wrapper |
| `types/api-response.type.ts` | `ApiResponse<T>`, `createSuccessResponse()`, `createErrorResponse()`, `createPaginatedResponse()` |
| `queues/queue.module.ts` | BullMQ module konfigürasyonu |
| `utils/image.util.ts` | Canvas yardımcı fonksiyonları |
### Standart API Response Formatı
```json
{
"success": true,
"status": 200,
"message": "Success",
"data": { ... },
"errors": []
}
```
---
## 10. Güvenlik & Guard Sistemi
Tüm guard'lar **global** olarak uygulanır (`app.module.ts`):
1. **ThrottlerGuard** — Rate limiting (default: 100 req/60s)
2. **JwtAuthGuard** — JWT token doğrulama (`@Public()` ile bypass)
3. **RolesGuard** — Rol tabanlı erişim (`@Roles('superadmin')`)
4. **PermissionsGuard** — İzin tabanlı erişim kontrolü
**Password:** bcrypt, 12 salt rounds
**Token:** JWT Access (15dk) + UUID Refresh Token (7 gün, DB'de saklanır)
---
## 11. Veri Akış Diyagramları
### 11.1 Canlı Maç Veri Akışı
```
Mackolik API (her 15dk)
DataFetcherTask.fetchLiveMatches()
├─→ Country upsert
├─→ League upsert
├─→ Team upsert (home + away)
└─→ LiveMatch upsert (top_leagues.json filtresi)
│ (her 15dk)
DataFetcherTask.fetchOddsForPreMatches()
└─→ LiveMatch.odds (JSON) + oddsUpdatedAt güncelle
│ (her 15dk)
LiveUpdaterTask.updateLiveScores()
└─→ LiveMatch score/state güncelle
│ (her 30dk)
LiveUpdaterTask.finalizeFinishedMatches()
└─→ LiveMatch → Match tablosuna migrate
```
### 11.2 Tahmin İstek Akışı
```
Client POST /api/coupon/analyze-match
SmartCouponService.analyzeMatch(matchId)
├─→ AI Engine POST /v20plus/analyze/{matchId}
│ │
│ └─→ SingleMatchOrchestrator.analyze_match()
│ │
│ └─→ DB'den veri çek → ML modeli → Tahmin paketi
├─→ GeminiService.generateText() (commentary, Türkçe)
└─→ SingleMatchPredictionPackage döndür
```
---
## 12. Konfigürasyon
### Environment Variables
| Değişken | Açıklama | Default |
|----------|----------|---------|
| `NODE_ENV` | Ortam | `development` |
| `PORT` | Sunucu portu | `3005` |
| `DATABASE_URL` | PostgreSQL bağlantısı | — |
| `JWT_SECRET` | JWT imza anahtarı | — |
| `JWT_ACCESS_EXPIRATION` | Access token süresi | `15m` |
| `JWT_REFRESH_EXPIRATION` | Refresh token süresi | `7d` |
| `REDIS_ENABLED` | Redis/BullMQ aktif mi | `false` |
| `REDIS_HOST` | Redis host | `localhost` |
| `REDIS_PORT` | Redis port | `6379` |
| `AI_ENGINE_URL` | Python AI Engine URL | `http://127.0.0.1:8000` |
| `ENABLE_GEMINI` | Gemini AI aktif mi | `false` |
| `GOOGLE_API_KEY` | Gemini API anahtarı | — |
### Config Dosyaları
| Dosya | Açıklama |
|-------|----------|
| `top_leagues.json` | Futbol top lig ID'leri (canlı maç filtresi) |
| `basketball_top_leagues.json` | Basketbol top lig ID'leri |
| `src/config/configuration.ts` | NestJS config factory'leri |
| `src/config/env.validation.ts` | Zod ile env doğrulama |
---
## 13. Build & Run Komutları
```bash
# Development
npm run start:dev # NestJS watch mode (port 3005)
# Production
npm run build && npm run start:prod
# Feeder (Data Collection)
npm run feeder:historical # Tarihsel veri taraması (2023-06→bugün)
npm run feeder:fill-gaps # Eksik veri tamamlama
npm run feeder:basketball # Basketbol verisi
npm run feeder:live # Canlı veri
# Database
npx prisma generate # Prisma client güncelle
npx prisma migrate dev # Migration çalıştır
npx prisma db seed # Seed data
# Testing
npm run test # Unit testler
npm run test:e2e # E2E testler
# AI Engine (Python)
cd ai-engine && uvicorn main:app --host 0.0.0.0 --port 8000 --reload
# Swagger
npm run swagger:summary # Endpoint export
```
---
## 14. Docker Deployment
```yaml
# docker-compose.yml (3 servis)
services:
backend: # NestJS (port 3005)
ai-engine: # Python FastAPI (port 8000)
postgres: # PostgreSQL 16 (port 5432)
redis: # Redis (opsiyonel, port 6379)
```
---
## 15. Bilinen Durumlar ve Notlar
1. **Predictions modülü** Redis gerektirir (`REDIS_ENABLED=true`). Redis yoksa bu modül yüklenmez.
2. **Gemini AI** opsiyoneldir. Devre dışıyken maç yorumu `null` döner.
3. **Feeder V17 AI feature hesaplama** devre dışı bırakılmıştır — V20 modeli Python tarafında çalışır.
4. **Lineup scraping** V20 optimizasyonu için devre dışıdır — sadece Team Stats kullanılır.
5. **Global Exception Filter** tüm hataları HTTP 200 olarak döner, gerçek status body içindedir.
6. **Abonelik sistemi** Free/Active/Expired — Free: 10 analiz + 3 kupon/gün, Active: 50 + 10.
7. **Veri kaynağı** tek: Mackolik.com — hem canlı API hem HTML scraping.
8. **Social Poster** Twitter API v2 ile çalışır, Instagram/Meta henüz implemente edilmemiştir.
---
## 16. Canlı Veritabanı Analizi (MCP ile PostgreSQL Sorguları)
> Aşağıdaki veriler **2026-03-12** tarihinde canlı veritabanından çekilmiştir.
### 16.1 Genel İstatistikler
| Metrik | Değer |
|--------|-------|
| **Toplam DB Boyutu** | **3,658 MB (3.6 GB)** |
| **Toplam Tablo** | 27 |
| **Veri Aralığı** | 2023-06-01 → 2026-03-12 |
### 16.2 Tablo Boyutları (Büyükten Küçüğe)
| Tablo | Kayıt Sayısı | Toplam Boyut | Veri | Index |
|-------|-------------|--------------|------|-------|
| `odd_selections` | **8,511,132** | 1,070 MB | 543 MB | 526 MB |
| `match_player_participation` | **3,342,839** | 1,077 MB | 430 MB | 648 MB |
| `odd_categories` | **3,161,172** | 689 MB | 294 MB | 394 MB |
| `match_player_events` | **1,453,227** | 356 MB | 239 MB | 117 MB |
| `match_player_stats` | **344,688** | 120 MB | 60 MB | 60 MB |
| `match_team_stats` | **310,991** | 91 MB | 37 MB | 54 MB |
| `match_officials` | **340,824** | 75 MB | 29 MB | 47 MB |
| `matches` | **236,859** | 100 MB | 60 MB | 40 MB |
| `players` | **217,040** | 64 MB | 26 MB | 37 MB |
| `teams` | **19,595** | 5.2 MB | — | — |
| `leagues` | **1,505** | 760 KB | — | — |
| `live_matches` | **82** | 1 MB | — | — |
| `countries` | **160** | 120 KB | — | — |
| `match_ai_features` | **279** | 152 KB | — | — |
| `predictions` | **3** | 192 KB | — | — |
| `users` | **1** | 80 KB | — | — |
| `refresh_tokens` | **8** | 80 KB | — | — |
| `usage_limits` | **1** | 80 KB | — | — |
| `app_settings` | **3** | 64 KB | — | — |
| `official_roles` | **5** | 48 KB | — | — |
| `translations` | **0** | 48 KB | — | — |
| `analyses` | **0** | 32 KB | — | — |
| `odds_history` | **0** | 32 KB | — | — |
| `user_coupons` | **0** | 32 KB | — | — |
| `ai_predictions_log` | **0** | 32 KB | — | — |
| `user_coupon_items` | **0** | 24 KB | — | — |
### 16.3 Spor Bazlı Dağılım
| Spor | Maç Sayısı | Lig Sayısı | Takım (~) | Ort. Ev Skoru | Ort. Deplasman Skoru |
|------|-----------|-----------|----------|--------------|---------------------|
| **Futbol** | 189,291 | 1,094 | ~23,958 | **1.55** | **1.27** |
| **Basketbol** | 47,568 | 304 | ~5,770 | **84.36** | **81.57** |
### 16.4 Maç Olayları Dağılımı
| Olay Tipi | Toplam |
|-----------|--------|
| `substitute` (Oyuncu Değişikliği) | **787,101** |
| `card` (Kart) | **409,136** |
| `goal` (Gol) | **256,990** |
### 16.5 Canlı Maçlar (live_matches — 82 Kayıt)
| Spor | Durum | Status | Sayı |
|------|-------|--------|------|
| Futbol | `pre` (başlamamış) | timestamp | 41 |
| Futbol | `post` (bitmiş) | state | 4 |
| Futbol | `live` (canlı) | minutes | 1 |
| Basketbol | `pre` (başlamamış) | timestamp | 23 |
| Basketbol | `post` (bitmiş) | state | 13 |
### 16.6 Türkiye Ligleri (En Çok Maç)
| Lig | Maç Sayısı |
|-----|-----------|
| Nesine 3. Lig | 1,511 |
| Nesine 2. Lig | 1,295 |
| Trendyol 1. Lig | 988 |
| Trendyol Süper Lig | 959 |
| Türkiye Sigorta BSL (Basketbol) | 637 |
| Türkiye Sigorta TBL (Basketbol) | 450 |
| Ziraat Türkiye Kupası | 438 |
| Halkbank KBSL (Kadınlar Basketbol) | 436 |
| Halkbank Kadınlar Basketbol 1.Ligi | 383 |
### 16.7 Global Top 10 Lig (En Çok Maç)
| Lig | Ülke | Maç |
|-----|------|-----|
| Segunda Lig RFEF | İspanya | 3,848 |
| Non Lig Premier | İngiltere | 3,553 |
| NBA | ABD | 3,529 |
| Bölgesel Lig | Almanya | 3,457 |
| Hazırlık Maçları | Dünya | 3,454 |
| Serie C | İtalya | 2,923 |
| Ulusal Lig N/S | İngiltere | 2,843 |
| RFEF 3. Lig | İspanya | 2,297 |
| 2. Lig | İsveç | 2,202 |
| 3. Lig | Norveç | 2,188 |
### 16.8 Feeder Scan Durumu (app_settings)
| Scan Job | Son İşlenen Tarih | Güncelleme |
|----------|-------------------|------------|
| `historical_scan_state_football_basketball` | **2026-03-11** | 2026-03-11 21:03 |
| `historical_scan_state_football_filtered_desc` | **2025-09-01** | 2026-02-26 09:27 |
| `historical_scan_state_football_filtered` | **2023-10-16** | 2026-02-12 18:03 |
### 16.9 Kullanıcı Durumu
| Metrik | Değer |
|--------|-------|
| Toplam kullanıcı | **1** (test@test.com) |
| Rol | `user` |
| Abonelik | `free` |
| Kayıt tarihi | 2026-02-09 |
| Aktif kupon | 0 |
| Analiz geçmişi | 0 |
### 16.10 Hakem Rolleri
| ID | Rol |
|----|-----|
| 1 | Orta Hakem |
| 2 | Yardımcı Hakem |
| 3 | 4. Hakem |
| 4 | VAR |
| 5 | AVAR |
### 16.11 Boş/Kullanılmamış Tablolar
Aşağıdaki tablolar henüz production verisine sahip değildir:
- `translations` — DB tabanlı i18n (dosya tabanlı i18n kullanılıyor)
- `analyses` — Kullanıcı analiz kayıtları (kullanıcı yok)
- `odds_history` — Oran değişim takibi (henüz implemente edilmemiş)
- `user_coupons` / `user_coupon_items` — Kullanıcı kuponları (kullanıcı yok)
- `ai_predictions_log` — AI tahmin loglama (cleanup job siliyor veya henüz üretilmemiş)