import { PrismaClient } from '@prisma/client'; import * as dotenv from 'dotenv'; import axios from 'axios'; dotenv.config(); // BigInt serialization fix (BigInt.prototype as any).toJSON = function () { return this.toString(); }; const prisma = new PrismaClient(); // Test with Club Brugge match const matchId = '7cnm7h7qbsq2bbaxngusojh90'; async function verifyDataUsage() { console.log('šŸ” VERIFYING DATA USAGE IN AI ENGINE'); console.log('='.repeat(80)); // 1. Fetch match from database const match = await prisma.liveMatch.findUnique({ where: { id: matchId }, include: { homeTeam: true, awayTeam: true, league: true, }, }); if (!match) { console.log('āŒ Match not found'); return; } console.log(`\nšŸ“Š Match: ${match.homeTeam?.name} vs ${match.awayTeam?.name}`); console.log(`\n1ļøāƒ£ ODDS DATA:`); console.log(` Type: ${typeof match.odds}`); console.log(` Is null: ${match.odds === null}`); if (match.odds) { const oddsStr = typeof match.odds === 'string' ? match.odds : JSON.stringify(match.odds); console.log(` Length: ${oddsStr.length} characters`); // Parse and show summary try { const oddsObj = typeof match.odds === 'string' ? JSON.parse(match.odds) : match.odds; const markets = Object.keys(oddsObj); console.log(` Markets: ${markets.length}`); console.log(` Sample markets: ${markets.slice(0, 5).join(', ')}...`); console.log(` āœ… ODDS DATA: PRESENT`); } catch (e) { console.log(` āŒ ODDS DATA: Invalid JSON`); } } else { console.log(` āŒ ODDS DATA: NULL/MISSING`); } console.log(`\n2ļøāƒ£ SIDELINED DATA:`); console.log(` Type: ${typeof match.sidelined}`); console.log(` Is null: ${match.sidelined === null}`); if (match.sidelined) { const sidelinedStr = typeof match.sidelined === 'string' ? match.sidelined : JSON.stringify(match.sidelined); console.log(` Length: ${sidelinedStr.length} characters`); try { const sidelinedObj = typeof match.sidelined === 'string' ? JSON.parse(match.sidelined) : match.sidelined; const homeTeam = sidelinedObj.homeTeam || sidelinedObj.home; const awayTeam = sidelinedObj.awayTeam || sidelinedObj.away; console.log(` Home team sidelined: ${homeTeam?.totalSidelined || homeTeam?.players?.length || 0}`); console.log(` Away team sidelined: ${awayTeam?.totalSidelined || awayTeam?.players?.length || 0}`); console.log(` āœ… SIDELINED DATA: PRESENT`); } catch (e) { console.log(` āŒ SIDELINED DATA: Invalid JSON`); } } else { console.log(` āŒ SIDELINED DATA: NULL/MISSING`); } console.log(`\n3ļøāƒ£ LINEUP DATA:`); console.log(` Type: ${typeof match.lineups}`); console.log(` Is null: ${match.lineups === null}`); if (match.lineups) { try { const lineupsObj = typeof match.lineups === 'string' ? JSON.parse(match.lineups) : match.lineups; const homeCount = lineupsObj.stats?.home?.length || 0; const awayCount = lineupsObj.stats?.away?.length || 0; console.log(` Home lineup: ${homeCount}`); console.log(` Away lineup: ${awayCount}`); console.log(` āœ… LINEUP DATA: PRESENT`); } catch (e) { console.log(` āŒ LINEUP DATA: Invalid JSON`); } } else { console.log(` āŒ LINEUP DATA: NULL/MISSING`); } // 2. Send prediction request console.log(`\n\nšŸ¤– SENDING TO AI ENGINE...`); const aiEngineUrl = 'http://localhost:8007'; const predictionUrl = `${aiEngineUrl}/v20plus/analyze/${matchId}`; const startTime = Date.now(); const response = await axios.post(predictionUrl, {}, { timeout: 120000, }); const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); console.log(`āœ… Prediction received in ${elapsed}s\n`); const pkg = response.data; // 3. Verify data quality console.log('šŸ“Š AI ENGINE DATA QUALITY:'); const dq = pkg.data_quality; console.log(` Label: ${dq.label}`); console.log(` Score: ${dq.score}`); console.log(` Home lineup count: ${dq.home_lineup_count}`); console.log(` Away lineup count: ${dq.away_lineup_count}`); console.log(` Lineup source: ${dq.lineup_source}`); console.log(` Flags: ${dq.flags.join(', ') || 'None'}`); // 4. Check if odds influenced the prediction console.log('\nšŸ“ˆ ENGINE BREAKDOWN (signal weights):'); const eb = pkg.engine_breakdown; if (eb) { console.log(` Team signal: ${eb.team}%`); console.log(` Player signal: ${eb.player}%`); console.log(` Odds signal: ${eb.odds}%`); console.log(` Referee signal: ${eb.referee}%`); if (eb.odds > 50) { console.log(` āœ… ODDS DATA: USED SIGNIFICANTLY (${eb.odds}%)`); } else if (eb.odds > 0) { console.log(` āš ļø ODDS DATA: USED MINIMALLY (${eb.odds}%)`); } else { console.log(` āŒ ODDS DATA: NOT USED`); } } // 5. Check sidelined impact console.log('\nāš ļø SIDELINED IMPACT:'); const reasoning = pkg.reasoning_factors || []; const hasSidelinedMention = reasoning.some((f: string) => f.toLowerCase().includes('sideline') || f.toLowerCase().includes('injury') || f.toLowerCase().includes('absence') || f.toLowerCase().includes('missing') ); if (hasSidelinedMention) { console.log(` āœ… SIDELINED DATA: MENTIONED IN REASONING`); reasoning.forEach((f: string) => { if (f.toLowerCase().includes('sideline') || f.toLowerCase().includes('injury') || f.toLowerCase().includes('absence') || f.toLowerCase().includes('missing')) { console.log(` - ${f}`); } }); } else { console.log(` āš ļø SIDELINED DATA: No explicit mention (but may still be used internally)`); console.log(` Reasoning factors: ${reasoning.join(', ')}`); } // 6. Main pick summary console.log('\nšŸŽÆ PREDICTION SUMMARY:'); const mp = pkg.main_pick; console.log(` Market: ${mp.market}`); console.log(` Pick: ${mp.pick}`); console.log(` Confidence: ${mp.confidence}%`); console.log(` Odds: ${mp.odds}`); console.log(` Edge: ${(mp.edge * 100).toFixed(2)}%`); console.log(` Grade: ${mp.bet_grade}`); console.log('\n' + '='.repeat(80)); console.log('āœ… VERIFICATION COMPLETE'); console.log('='.repeat(80)); await prisma.$disconnect(); } verifyDataUsage().catch(console.error);