Files
iddaai-be/verify-data-usage.ts
T
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

187 lines
6.3 KiB
TypeScript

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);