mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:45:23 +02:00
244 lines
8.9 KiB
TypeScript
244 lines
8.9 KiB
TypeScript
import { createClient } from '@supabase/supabase-js';
|
|||
|
|
|
||
|
|
interface Experiment {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
start_date: string;
|
||
|
|
end_date?: string;
|
||
|
|
marketplace: string;
|
||
|
|
asins: string[];
|
||
|
|
baseline_start_date?: string;
|
||
|
|
baseline_end_date?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Configura Supabase con credenciales hardcodeadas para debug
|
||
|
|
const supabase = createClient(
|
||
|
|
'https://qjioywarwdbxmdihyrti.supabase.co',
|
||
|
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFqaW95d2Fyd2RieG1kaWh5cnRpIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc3MTUxMDU0NCwiZXhwIjoyMDg3MDg2NTQ0fQ.oXxdNBDvMSyfMRaf57oCb8cUS2Bqm73CeyM19v3GJPI'
|
||
|
|
);
|
||
|
|
|
||
|
|
async function debugBodynessExperiment() {
|
||
|
|
console.log('=== DEBUG BODYNESS ES EXPERIMENT ===\n');
|
||
|
|
|
||
|
|
// 1. Obtener el experimento
|
||
|
|
const { data: expData, error: expError } = await supabase
|
||
|
|
.from('experiments')
|
||
|
|
.select('*')
|
||
|
|
.ilike('name', '%bodyness%')
|
||
|
|
.single();
|
||
|
|
|
||
|
|
if (expError || !expData) {
|
||
|
|
console.log('❌ No se encontró el experimento');
|
||
|
|
console.log('Error:', expError);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const experiment: Experiment = expData;
|
||
|
|
console.log('📋 Experimento:', experiment.name);
|
||
|
|
console.log('📅 Start:', experiment.start_date);
|
||
|
|
console.log('📅 End:', experiment.end_date);
|
||
|
|
console.log('🌍 Marketplace:', experiment.marketplace);
|
||
|
|
console.log('📦 ASINs:', experiment.asins);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 2. Obtener datos de ventas (sin filtro de año primero) - verificar total
|
||
|
|
const { count, error: countError } = await supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('*', { count: 'exact', head: true });
|
||
|
|
|
||
|
|
console.log(`📊 Total registros en vendor_daily_data: ${count || 'unknown'}`);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// Buscar específicamente los ASINs del experimento
|
||
|
|
console.log('🔍 Buscando ASINs del experimento en la DB...');
|
||
|
|
const { data: asinData, error: asinError } = await supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('*')
|
||
|
|
.in('asin', experiment.asins);
|
||
|
|
|
||
|
|
if (asinError) {
|
||
|
|
console.log('Error buscando ASINs:', asinError.message);
|
||
|
|
} else {
|
||
|
|
console.log(`✅ Registros encontrados para los ASINs del experimento: ${asinData?.length || 0}`);
|
||
|
|
if (asinData && asinData.length > 0) {
|
||
|
|
const asinsEncontrados = [...new Set(asinData.map(r => r.asin))];
|
||
|
|
console.log('ASINs encontrados:', asinsEncontrados);
|
||
|
|
const marketsEncontrados = [...new Set(asinData.map(r => r.market))];
|
||
|
|
console.log('Markets encontrados:', marketsEncontrados);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// Obtener datos filtrados por los ASINs del experimento (usamos asinData que ya tiene los datos)
|
||
|
|
const salesData = asinData || [];
|
||
|
|
console.log(`📊 Total registros para ASINs del experimento: ${salesData.length}`);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// Ver muestra de datos
|
||
|
|
console.log('📋 Muestra de datos (primeros 3 registros - todos los campos):');
|
||
|
|
salesData.slice(0, 3).forEach((r: any, i) => {
|
||
|
|
console.log(` ${i+1}.`, JSON.stringify(r, null, 2));
|
||
|
|
});
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// Ver rango de fechas
|
||
|
|
const dates = salesData.map(r => r.date).filter(Boolean).sort();
|
||
|
|
if (dates.length > 0) {
|
||
|
|
console.log(`📅 Rango de fechas: ${dates[0]} → ${dates[dates.length - 1]}`);
|
||
|
|
}
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 4. Ver marketplace en los datos
|
||
|
|
const marketplaces = [...new Set(salesData.map(r => r.market || 'N/A'))];
|
||
|
|
console.log('🌍 Marketplaces en los datos:', marketplaces);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 5. Filtrar por marketplace del experimento (ES)
|
||
|
|
const mktFilter = (experiment.marketplace || '').toLowerCase();
|
||
|
|
console.log(`Filtrando por marketplace: "${experiment.marketplace}"`);
|
||
|
|
|
||
|
|
const filteredByMkt = salesData.filter(r => {
|
||
|
|
const mkt = (r.market || '').toLowerCase();
|
||
|
|
return !mktFilter || mktFilter === 'all' || mkt.includes(mktFilter) || mktFilter.includes(mkt);
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log(`✅ Registros después de filtrar por marketplace: ${filteredByMkt.length}`);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 6. Agrupar por semana ISO (usando el campo date)
|
||
|
|
const weeksMap = new Map<string, { units: number; records: number; dates: string[] }>();
|
||
|
|
filteredByMkt.forEach((r: any) => {
|
||
|
|
const dateStr = r.date;
|
||
|
|
if (!dateStr) return;
|
||
|
|
const date = new Date(dateStr);
|
||
|
|
const iso = getISOWeek(date);
|
||
|
|
const key = `${iso.year}-W${String(iso.week).padStart(2, '0')}`;
|
||
|
|
const existing = weeksMap.get(key) || { units: 0, records: 0, dates: [] as string[] };
|
||
|
|
existing.units += (r.units || r.unitsTotal || 0);
|
||
|
|
existing.records++;
|
||
|
|
if (!existing.dates.includes(dateStr)) existing.dates.push(dateStr);
|
||
|
|
weeksMap.set(key, existing);
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log('📅 Unidades por semana (TODOS los datos):');
|
||
|
|
const sortedWeeks = Array.from(weeksMap.entries()).sort();
|
||
|
|
sortedWeeks.forEach(([week, data]) => {
|
||
|
|
console.log(` ${week}: ${data.units} unidades (${data.records} registros) - fechas: ${data.dates.sort().join(', ')}`);
|
||
|
|
});
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 7. Ver semanas dentro del período del experimento (Jan 22 - Feb 4, 2026)
|
||
|
|
const startDate = new Date(experiment.start_date!);
|
||
|
|
const endDate = new Date(experiment.end_date!);
|
||
|
|
|
||
|
|
console.log('📅 Período del experimento:', startDate.toISOString().split('T')[0], '→', endDate.toISOString().split('T')[0]);
|
||
|
|
|
||
|
|
// Calcular semanas ISO que toca el experimento
|
||
|
|
const startISO = getISOWeek(startDate);
|
||
|
|
const endISO = getISOWeek(endDate);
|
||
|
|
console.log(`📅 Semanas ISO: ${startISO.year}-W${startISO.week} → ${endISO.year}-W${endISO.week}`);
|
||
|
|
|
||
|
|
const afterWeeks: string[] = [];
|
||
|
|
let currentYear = startISO.year;
|
||
|
|
let currentWeek = startISO.week;
|
||
|
|
|
||
|
|
while (true) {
|
||
|
|
const weekKey = `${currentYear}-W${String(currentWeek).padStart(2, '0')}`;
|
||
|
|
afterWeeks.push(weekKey);
|
||
|
|
|
||
|
|
if (currentYear === endISO.year && currentWeek === endISO.week) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
currentWeek++;
|
||
|
|
const weeksInYear = getWeeksInYear(currentYear);
|
||
|
|
if (currentWeek > weeksInYear) {
|
||
|
|
currentWeek = 1;
|
||
|
|
currentYear++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(`📅 Semanas incluidas en AFTER: ${afterWeeks.join(', ')}`);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 8. Calcular unidades en esas semanas
|
||
|
|
let afterUnits = 0;
|
||
|
|
let afterWeekCount = 0;
|
||
|
|
|
||
|
|
console.log('📊 Unidades en semanas AFTER:');
|
||
|
|
sortedWeeks.forEach(([week, data]) => {
|
||
|
|
if (afterWeeks.includes(week)) {
|
||
|
|
afterUnits += data.units;
|
||
|
|
afterWeekCount++;
|
||
|
|
console.log(` ✅ ${week}: ${data.units} unidades`);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log('');
|
||
|
|
console.log(`📊 Total unidades en AFTER: ${afterUnits}`);
|
||
|
|
console.log(`📊 Número de semanas con datos: ${afterWeekCount}`);
|
||
|
|
console.log(`📊 Media calculada: ${afterUnits} / ${afterWeekCount} = ${(afterUnits / afterWeekCount).toFixed(2)}`);
|
||
|
|
console.log('');
|
||
|
|
|
||
|
|
// 9. Ver baseline (3 semanas antes)
|
||
|
|
const baselineEndTs = getISOWeekMonday(startISO.year, startISO.week);
|
||
|
|
const baselineStartTs = baselineEndTs - (afterWeeks.length * 7 * 86400000);
|
||
|
|
|
||
|
|
console.log('📅 Baseline período:', new Date(baselineStartTs).toISOString().split('T')[0], '→', new Date(baselineEndTs).toISOString().split('T')[0]);
|
||
|
|
|
||
|
|
// Calcular semanas del baseline
|
||
|
|
const baselineWeeks: string[] = [];
|
||
|
|
let baselineDate = new Date(baselineStartTs);
|
||
|
|
while (baselineDate.getTime() < baselineEndTs) {
|
||
|
|
const iso = getISOWeek(baselineDate);
|
||
|
|
const weekKey = `${iso.year}-W${String(iso.week).padStart(2, '0')}`;
|
||
|
|
if (!baselineWeeks.includes(weekKey)) {
|
||
|
|
baselineWeeks.push(weekKey);
|
||
|
|
}
|
||
|
|
baselineDate.setDate(baselineDate.getDate() + 7);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(`📅 Semanas del BASELINE: ${baselineWeeks.join(', ')}`);
|
||
|
|
|
||
|
|
let beforeUnits = 0;
|
||
|
|
let beforeWeekCount = 0;
|
||
|
|
console.log('📊 Unidades en semanas BASELINE:');
|
||
|
|
sortedWeeks.forEach(([week, data]) => {
|
||
|
|
if (baselineWeeks.includes(week)) {
|
||
|
|
beforeUnits += data.units;
|
||
|
|
beforeWeekCount++;
|
||
|
|
console.log(` ✅ ${week}: ${data.units} unidades`);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log('');
|
||
|
|
console.log(`📊 Total unidades en BASELINE: ${beforeUnits}`);
|
||
|
|
console.log(`📊 Número de semanas con datos: ${beforeWeekCount}`);
|
||
|
|
console.log(`📊 Media calculada: ${beforeUnits} / ${beforeWeekCount} = ${(beforeUnits / beforeWeekCount).toFixed(2)}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Funciones helper ISO week
|
||
|
|
function getISOWeek(date: Date): { year: number; week: number } {
|
||
|
|
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||
|
|
const dayNum = d.getUTCDay() || 7;
|
||
|
|
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
|
||
|
|
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
||
|
|
const weekNum = Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
|
||
|
|
return { year: d.getUTCFullYear(), week: weekNum };
|
||
|
|
}
|
||
|
|
|
||
|
|
function getWeeksInYear(year: number): number {
|
||
|
|
const dec28 = new Date(Date.UTC(year, 11, 28));
|
||
|
|
const iso = getISOWeek(dec28);
|
||
|
|
return iso.week;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getISOWeekMonday(year: number, week: number): number {
|
||
|
|
const jan4 = new Date(Date.UTC(year, 0, 4));
|
||
|
|
const dayOfWeek = jan4.getUTCDay() || 7;
|
||
|
|
const week1Monday = new Date(Date.UTC(year, 0, 4 - (dayOfWeek - 1)));
|
||
|
|
return week1Monday.getTime() + (week - 1) * 7 * 86400000;
|
||
|
|
}
|
||
|
|
|
||
|
|
debugBodynessExperiment().catch(console.error);
|