# 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()` — 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 (findAll, findOne, create, update, delete) | | `base/base.controller.ts` | Generic BaseController (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`, `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ş)