const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); async function analyzeMatch() { const matchId = '2ivwkprq3bnkkp2bfa2cdintg'; console.log('\n'); console.log( '╔══════════════════════════════════════════════════════════════════╗', ); console.log( '║ GLM-5 TAHMİN & SÜRPRİZ ANALİZİ ║', ); console.log( '║ Maç ID: ' + matchId.substring(0, 20) + '... ║', ); console.log( '╚══════════════════════════════════════════════════════════════════╝', ); const match = await prisma.match.findUnique({ where: { id: matchId }, include: { homeTeam: true, awayTeam: true, league: { include: { country: true } }, oddCategories: { include: { selections: true } }, officials: { include: { role: true } }, aiFeatures: true, }, }); if (!match) { console.log('❌ Maç bulunamadı!'); await prisma.$disconnect(); return; } console.log( '\n═══════════════════════════════════════════════════════════════', ); console.log('⚽ MAÇ BİLGİLERİ'); console.log( '═══════════════════════════════════════════════════════════════', ); console.log(`\n🏠 Ev Sahibi: ${match.homeTeam?.name}`); console.log(`✈️ Deplasman: ${match.awayTeam?.name}`); console.log( `🏆 Lig: ${match.league?.name} (${match.league?.country?.name || ''})`, ); console.log( `📅 Tarih: ${new Date(Number(match.mstUtc)).toLocaleString('tr-TR', { timeZone: 'Europe/Istanbul' })}`, ); console.log(`📊 Durum: ${match.state} / ${match.status}`); console.log(`🔢 İddaa Kodu: ${match.iddaaCode || 'Yok'}`); // SKORU GİZLE - Sona saklayacağız // ═════════════════════════════════════════════════════════════════ // 1. ORAN ANALİZİ // ═════════════════════════════════════════════════════════════════ console.log( '\n═══════════════════════════════════════════════════════════════', ); console.log('📊 1. ORAN ANALİZİ'); console.log( '═══════════════════════════════════════════════════════════════', ); const odds = { ms_h: null, ms_d: null, ms_a: null, dc_1x: null, dc_x2: null, dc_12: null, ou25_o: null, ou25_u: null, btts_y: null, btts_n: null, ht_h: null, ht_d: null, ht_a: null, }; console.log('\n📋 Tüm Oran Kategorileri:\n'); for (const cat of match.oddCategories) { const selections = cat.selections .map((s) => `${s.name}: ${s.oddValue}`) .join(' | '); console.log(` ${cat.name}: ${selections}`); if (cat.name?.includes('Maç Sonucu') || cat.name === 'MS') { for (const sel of cat.selections) { if (sel.name === '1') odds.ms_h = parseFloat(sel.oddValue); if (sel.name === 'X') odds.ms_d = parseFloat(sel.oddValue); if (sel.name === '2') odds.ms_a = parseFloat(sel.oddValue); } } if (cat.name?.includes('Çifte Şans')) { for (const sel of cat.selections) { if (sel.name === '1-X') odds.dc_1x = parseFloat(sel.oddValue); if (sel.name === 'X-2') odds.dc_x2 = parseFloat(sel.oddValue); if (sel.name === '1-2') odds.dc_12 = parseFloat(sel.oddValue); } } if (cat.name?.includes('2,5') || cat.name?.includes('2.5')) { for (const sel of cat.selections) { if (sel.name === 'Alt' || sel.name === 'A') odds.ou25_u = parseFloat(sel.oddValue); if (sel.name === 'Üst' || sel.name === 'Ü') odds.ou25_o = parseFloat(sel.oddValue); } } if ( cat.name?.toLowerCase().includes('karşılıklı') || cat.name?.includes('KG') ) { for (const sel of cat.selections) { if (sel.name === 'Var' || sel.name === 'Evet') odds.btts_y = parseFloat(sel.oddValue); if (sel.name === 'Yok' || sel.name === 'Hayır') odds.btts_n = parseFloat(sel.oddValue); } } if (cat.name?.includes('1. Yarı') && cat.name?.includes('Sonuc')) { for (const sel of cat.selections) { if (sel.name === '1') odds.ht_h = parseFloat(sel.oddValue); if (sel.name === 'X') odds.ht_d = parseFloat(sel.oddValue); if (sel.name === '2') odds.ht_a = parseFloat(sel.oddValue); } } } let margin = null; let normHome = 33, normDraw = 33, normAway = 33; let favorite = null, favoriteOdds = null; if (odds.ms_h && odds.ms_d && odds.ms_a) { const rawHome = (1 / odds.ms_h) * 100; const rawDraw = (1 / odds.ms_d) * 100; const rawAway = (1 / odds.ms_a) * 100; const total = rawHome + rawDraw + rawAway; margin = total - 100; normHome = (rawHome / total) * 100; normDraw = (rawDraw / total) * 100; normAway = (rawAway / total) * 100; // Favori kim? if (odds.ms_h < odds.ms_a) { favorite = 'home'; favoriteOdds = odds.ms_h; } else if (odds.ms_a < odds.ms_h) { favorite = 'away'; favoriteOdds = odds.ms_a; } else { favorite = 'draw'; favoriteOdds = odds.ms_d; } console.log( `\n📊 MS Oranları: 1=${odds.ms_h} | X=${odds.ms_d} | 2=${odds.ms_a}`, ); console.log(`📈 Bookmaker Margin: %${margin.toFixed(1)}`); console.log(`🎯 Normalize Olasılık:`); console.log( ` 1 (${match.homeTeam?.name?.substring(0, 15)}): %${normHome.toFixed(1)}`, ); console.log(` X (Beraberlik): %${normDraw.toFixed(1)}`); console.log( ` 2 (${match.awayTeam?.name?.substring(0, 15)}): %${normAway.toFixed(1)}`, ); console.log( `\n🏆 Favori: ${favorite === 'home' ? match.homeTeam?.name + ' (1)' : favorite === 'away' ? match.awayTeam?.name + ' (2)' : 'Beraberlik (X)'} @ ${favoriteOdds}`, ); } // ═════════════════════════════════════════════════════════════════ // 2. TAKIM FORM ANALİZİ // ═════════════════════════════════════════════════════════════════ console.log( '\n═══════════════════════════════════════════════════════════════', ); console.log('📈 2. TAKIM FORM ANALİZİ'); console.log( '═══════════════════════════════════════════════════════════════', ); // Ev sahibi son 10 maç const homeMatches = await prisma.match.findMany({ where: { OR: [{ homeTeamId: match.homeTeamId }, { awayTeamId: match.homeTeamId }], sport: 'football', state: 'postGame', scoreHome: { not: null }, scoreAway: { not: null }, }, orderBy: { mstUtc: 'desc' }, take: 10, }); let homeWins = 0, homeDraws = 0, homeLosses = 0; let homeGoalsFor = 0, homeGoalsAgainst = 0; for (const m of homeMatches) { const isHome = m.homeTeamId === match.homeTeamId; const gf = isHome ? m.scoreHome : m.scoreAway; const ga = isHome ? m.scoreAway : m.scoreHome; homeGoalsFor += gf || 0; homeGoalsAgainst += ga || 0; if (gf > ga) homeWins++; else if (gf < ga) homeLosses++; else homeDraws++; } const homeFormScore = homeMatches.length > 0 ? ((homeWins * 3 + homeDraws) / (homeMatches.length * 3)) * 100 : 50; console.log(`\n🏠 ${match.homeTeam?.name}:`); console.log( ` Son ${homeMatches.length} Maç: ${homeWins}G ${homeDraws}B ${homeLosses}M`, ); console.log(` Gol: ${homeGoalsFor} attı, ${homeGoalsAgainst} yedi`); console.log(` Form Skoru: ${homeFormScore.toFixed(1)}/100`); // Deplasman son 10 maç const awayMatches = await prisma.match.findMany({ where: { OR: [{ homeTeamId: match.awayTeamId }, { awayTeamId: match.awayTeamId }], sport: 'football', state: 'postGame', scoreHome: { not: null }, scoreAway: { not: null }, }, orderBy: { mstUtc: 'desc' }, take: 10, }); let awayWins = 0, awayDraws = 0, awayLosses = 0; let awayGoalsFor = 0, awayGoalsAgainst = 0; for (const m of awayMatches) { const isHome = m.homeTeamId === match.awayTeamId; const gf = isHome ? m.scoreHome : m.scoreAway; const ga = isHome ? m.scoreAway : m.scoreHome; awayGoalsFor += gf || 0; awayGoalsAgainst += ga || 0; if (gf > ga) awayWins++; else if (gf < ga) awayLosses++; else awayDraws++; } const awayFormScore = awayMatches.length > 0 ? ((awayWins * 3 + awayDraws) / (awayMatches.length * 3)) * 100 : 50; console.log(`\n✈️ ${match.awayTeam?.name}:`); console.log( ` Son ${awayMatches.length} Maç: ${awayWins}G ${awayDraws}B ${awayLosses}M`, ); console.log(` Gol: ${awayGoalsFor} attı, ${awayGoalsAgainst} yedi`); console.log(` Form Skoru: ${awayFormScore.toFixed(1)}/100`); const formDiff = homeFormScore - awayFormScore; console.log( `\n📈 Form Farkı: ${formDiff > 0 ? '+' : ''}${formDiff.toFixed(1)}`, ); // ═════════════════════════════════════════════════════════════════ // 3. HEAD-TO-HEAD // ═════════════════════════════════════════════════════════════════ console.log( '\n═══════════════════════════════════════════════════════════════', ); console.log('🔄 3. HEAD-TO-HEAD'); console.log( '═══════════════════════════════════════════════════════════════', ); const h2hMatches = await prisma.match.findMany({ where: { OR: [ { homeTeamId: match.homeTeamId, awayTeamId: match.awayTeamId }, { homeTeamId: match.awayTeamId, awayTeamId: match.homeTeamId }, ], sport: 'football', state: 'postGame', }, orderBy: { mstUtc: 'desc' }, take: 5, }); let h2hHomeWins = 0, h2hAwayWins = 0, h2hDraws = 0; if (h2hMatches.length > 0) { for (const m of h2hMatches) { const homeTeamIsHome = m.homeTeamId === match.homeTeamId; const result = m.scoreHome > m.scoreAway ? homeTeamIsHome ? '1' : '2' : m.scoreHome < m.scoreAway ? homeTeamIsHome ? '2' : '1' : 'X'; if (result === '1') h2hHomeWins++; else if (result === '2') h2hAwayWins++; else h2hDraws++; console.log( ` ${m.homeTeam?.name} ${m.scoreHome}-${m.scoreAway} ${m.awayTeam?.name} [${result}]`, ); } console.log( `\n H2H: ${match.homeTeam?.name} ${h2hHomeWins}G, ${h2hDraws}B, ${match.awayTeam?.name} ${h2hAwayWins}G`, ); } else { console.log(' Karşılıklı maç bulunamadı'); } // ═════════════════════════════════════════════════════════════════ // 4. HAKEM ANALİZİ // ═════════════════════════════════════════════════════════════════ console.log( '\n═══════════════════════════════════════════════════════════════', ); console.log('👨‍⚖️ 4. HAKEM ANALİZİ'); console.log( '═══════════════════════════════════════════════════════════════', ); let refUpsetRate = 0; const mainReferee = match.officials?.find( (o) => o.role?.name === 'Orta Hakem', ); if (mainReferee) { console.log(`\n👤 Hakem: ${mainReferee.name}`); const refereeMatches = await prisma.matchOfficial.findMany({ where: { name: mainReferee.name, roleId: 1 }, include: { match: true }, take: 30, }); let refHomeWins = 0, refDraws = 0, refAwayWins = 0; let refUpsets = 0, refTotal = 0; for (const rm of refereeMatches) { if (rm.match?.scoreHome !== null && rm.match?.scoreAway !== null) { refTotal++; // Bu maç için favori belirle (basit: ev sahibi favori varsay) // Gerçek hayatta oranlar kontrol edilmeli if (rm.match.scoreHome > rm.match.scoreAway) refHomeWins++; else if (rm.match.scoreHome < rm.match.scoreAway) { refAwayWins++; refUpsets++; // Ev sahibi kaybetti = sürpriz (basitleştirilmiş) } else refDraws++; } } if (refTotal > 0) { console.log(` Yönettiği maçlar: ${refTotal}`); console.log( ` Ev kazanma: %${((refHomeWins / refTotal) * 100).toFixed(1)}`, ); console.log( ` Beraberlik: %${((refDraws / refTotal) * 100).toFixed(1)}`, ); console.log( ` Deplasman: %${((refAwayWins / refTotal) * 100).toFixed(1)}`, ); refUpsetRate = (refAwayWins / refTotal) * 100; console.log( ` ⚠️ Sürpriz (ev kaybı) oranı: %${refUpsetRate.toFixed(1)}`, ); } } else { console.log(' Hakem bilgisi yok'); } // ═════════════════════════════════════════════════════════════════ // 5. SÜRPRİZ SKORU HESAPLAMA // ═════════════════════════════════════════════════════════════════ console.log( '\n═══════════════════════════════════════════════════════════════', ); console.log('🎯 5. SÜRPRİZ SKORU HESAPLAMA'); console.log( '═══════════════════════════════════════════════════════════════', ); let upsetScore = 0; const upsetReasons = []; console.log('\n📊 Sürpriz Skoru Hesaplaması:\n'); // 1. Margin if (margin !== null) { if (margin > 20) { upsetScore += 15; upsetReasons.push('Margin yüksek (%20+)'); console.log(` ✓ Margin %${margin.toFixed(1)} > %20 → +15 puan`); } else if (margin > 18) { upsetScore += 10; upsetReasons.push('Margin orta-yüksek'); console.log(` ✓ Margin %${margin.toFixed(1)} > %18 → +10 puan`); } else { console.log(` ✗ Margin %${margin.toFixed(1)} < %18 → +0 puan`); } } // 2. Favori Oran if (favoriteOdds !== null) { if (favoriteOdds >= 1.5 && favoriteOdds < 1.6) { upsetScore += 25; upsetReasons.push('Favori oran 1.50-1.60 arası (riskli)'); console.log(` ✓ Favori oran ${favoriteOdds} (1.50-1.60) → +25 puan`); } else if (favoriteOdds >= 1.4 && favoriteOdds < 1.5) { upsetScore += 20; upsetReasons.push('Favori oran 1.40-1.50 arası'); console.log(` ✓ Favori oran ${favoriteOdds} (1.40-1.50) → +20 puan`); } else if (favoriteOdds >= 1.3 && favoriteOdds < 1.4) { upsetScore += 15; upsetReasons.push('Favori oran 1.30-1.40 arası'); console.log(` ✓ Favori oran ${favoriteOdds} (1.30-1.40) → +15 puan`); } else if (favoriteOdds < 1.2) { upsetScore += 20; upsetReasons.push('Favori oran çok düşük (tuzak şüphesi)'); console.log( ` ✓ Favori oran ${favoriteOdds} (<1.20, tuzak?) → +20 puan`, ); } else { console.log( ` ✗ Favori oran ${favoriteOdds} (güvenli aralık) → +0 puan`, ); } } // 3. Hakem if (refUpsetRate > 30) { upsetScore += 20; upsetReasons.push( `Hakem sürpriz oranı yüksek (%${refUpsetRate.toFixed(0)})`, ); console.log( ` ✓ Hakem sürpriz oranı %${refUpsetRate.toFixed(0)} > %30 → +20 puan`, ); } else if (refUpsetRate > 20) { upsetScore += 10; upsetReasons.push('Hakem sürpriz oranı orta'); console.log( ` ✓ Hakem sürpriz oranı %${refUpsetRate.toFixed(0)} > %20 → +10 puan`, ); } else { console.log( ` ✗ Hakem sürpriz oranı %${refUpsetRate.toFixed(0)} < %20 → +0 puan`, ); } // 4. Form Farkı if (Math.abs(formDiff) > 40) { upsetScore += 15; upsetReasons.push( `Form farkı çok büyük (${formDiff > 0 ? '+' : ''}${formDiff.toFixed(0)})`, ); console.log( ` ✓ Form farkı ${formDiff.toFixed(0)} > 40 (tuzak?) → +15 puan`, ); } else { console.log(` ✗ Form farkı ${formDiff.toFixed(0)} < 40 → +0 puan`); } // 5. H2H Sürpriz if (h2hAwayWins > 0 && favorite === 'home') { upsetScore += 10; upsetReasons.push('H2H geçmişinde deplasman galibiyeti var'); console.log(` ✓ H2H'de deplasman ${h2hAwayWins} galibiyet → +10 puan`); } else if (h2hHomeWins > 0 && favorite === 'away') { upsetScore += 10; upsetReasons.push('H2H geçmişinde ev sahibi galibiyeti var'); console.log(` ✓ H2H'de ev sahibi ${h2hHomeWins} galibiyet → +10 puan`); } else { console.log(` ✗ H2H'de sürpriz yok → +0 puan`); } console.log(`\n ─────────────────────────────`); console.log(` 📊 SÜRPRİZ SKORU: ${upsetScore}/100`); // ═════════════════════════════════════════════════════════════════ // 6. FİNAL TAHMİN // ═════════════════════════════════════════════════════════════════ console.log('\n'); console.log( '╔══════════════════════════════════════════════════════════════════╗', ); console.log( '║ 🎯 FİNAL TAHMİN ║', ); console.log( '╚══════════════════════════════════════════════════════════════════╝', ); // Normal tahmin const w = { odds: 0.4, form: 0.3, home: 0.15, league: 0.15 }; const homeScore = normHome * w.odds + homeFormScore * w.form + 8 * w.home; const awayScore = normAway * w.odds + awayFormScore * w.form + 0 * w.home; const drawScore = normDraw * w.odds + (100 - Math.abs(formDiff)) * 0.1 * w.form; const total = homeScore + drawScore + awayScore; const finalHome = (homeScore / total) * 100; const finalDraw = (drawScore / total) * 100; const finalAway = (awayScore / total) * 100; let prediction, confidence; if (finalHome > finalDraw && finalHome > finalAway) { prediction = '1'; confidence = finalHome; } else if (finalAway > finalDraw) { prediction = '2'; confidence = finalAway; } else { prediction = 'X'; confidence = finalDraw; } // Alt/Üst const avgGoals = (homeGoalsFor + homeGoalsAgainst + awayGoalsFor + awayGoalsAgainst) / (homeMatches.length + awayMatches.length) || 2.5; const ou25 = avgGoals > 2.5 ? 'ÜST' : 'ALT'; console.log(`\n📊 NORMAL TAHMİN (Oran + Form):`); console.log(` 1: %${finalHome.toFixed(1)}`); console.log(` X: %${finalDraw.toFixed(1)}`); console.log(` 2: %${finalAway.toFixed(1)}`); console.log(`\n 🏆 TAHMİN: ${prediction}`); console.log(` 📊 Güven: %${confidence.toFixed(1)}`); console.log(` ⚽ 2.5 ${ou25}`); // Sürpriz tahmini console.log(`\n⚠️ SÜRPRİZ ANALİZİ:`); console.log(` Sürpriz Skoru: ${upsetScore}/100`); if (upsetScore >= 50) { console.log(`\n 🔴 YÜKSEK SÜRPRİZ RİSKİ!`); console.log(` Sürpriz işaretleri:`); for (const reason of upsetReasons) { console.log(` • ${reason}`); } // Value bet önerisi const upsetPrediction = prediction === '1' ? '2' : prediction === '2' ? '1' : 'X'; const upsetOdds = prediction === '1' ? odds.ms_a : prediction === '2' ? odds.ms_h : odds.ms_d; console.log(`\n 💰 VALUE BET ÖNERİSİ:`); console.log( ` Normal tahmin: ${prediction} @ ${prediction === '1' ? odds.ms_h : prediction === '2' ? odds.ms_a : odds.ms_d}`, ); console.log( ` Sürpriz tahmin: ${upsetPrediction} @ ${upsetOdds} ← VALUE BET!`, ); } else if (upsetScore >= 30) { console.log(`\n 🟡 ORTA SÜRPRİZ RİSKİ`); console.log(` Dikkatli olun, çifte şans düşünülebilir`); } else { console.log(`\n 🟢 DÜŞÜK SÜRPRİZ RİSKİ`); console.log(` Normal tahmin güvenle oynanabilir`); } // ═════════════════════════════════════════════════════════════════ // GERÇEK SONUÇ (SON) // ═════════════════════════════════════════════════════════════════ console.log('\n'); console.log( '╔══════════════════════════════════════════════════════════════════╗', ); console.log( '║ 📊 GERÇEK SONUÇ ║', ); console.log( '╚══════════════════════════════════════════════════════════════════╝', ); if (match.scoreHome !== null && match.scoreAway !== null) { const actual = match.scoreHome > match.scoreAway ? '1' : match.scoreHome < match.scoreAway ? '2' : 'X'; const actualGoals = match.scoreHome + match.scoreAway; const actualOU = actualGoals > 2.5 ? 'ÜST' : 'ALT'; console.log( `\n Skor: ${match.homeTeam?.name} ${match.scoreHome} - ${match.scoreAway} ${match.awayTeam?.name}`, ); console.log(` Sonuç: ${actual}`); console.log(` Alt/Üst: ${actualOU} (${actualGoals} gol)`); console.log(`\n ─────────────────────────────`); console.log( ` 🎯 Normal Tahmin (${prediction}): ${prediction === actual ? '✅ DOĞRU' : '❌ YANLIŞ'}`, ); console.log( ` 🎯 2.5 ${ou25}: ${ou25 === actualOU ? '✅ DOĞRU' : '❌ YANLIŞ'}`, ); if (upsetScore >= 50) { const upsetPrediction = prediction === '1' ? '2' : prediction === '2' ? '1' : 'X'; console.log( ` 🎯 Sürpriz Tahmin (${upsetPrediction}): ${upsetPrediction === actual ? '✅ DOĞRU' : '❌ YANLIŞ'}`, ); } } else { console.log(`\n Maç henüz oynanmamış veya skor yok`); } console.log('\n'); await prisma.$disconnect(); } analyzeMatch().catch(console.error);