This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user