fix(experiments): prevent NaN propagation and ACOS zero-value bug in experiment analysis

- Change ?? to || for salesAds/units/revenue in weekly aggregation to guard against NaN
- Add || 0 fallback to ads-only records in mergeSalesAndAdsData
- Fix parseCurrency to check isNaN on all EU-format return paths
- Handle ACOS edge case: cost > 0 with adRevenue = 0 now returns 100% instead of 0%
- Add diagnostic console logging to computeDiD for data flow tracing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Vidal Wolf
2026-02-25 16:34:55 +01:00
co-authored by Claude Opus 4.6
parent de1af7e0db
commit 8b774ae7ba
3 changed files with 36 additions and 15 deletions
+10 -8
View File
@@ -69,7 +69,8 @@ const parseCurrency = (value: string): number => {
// Likely EU decimal without thousands or with thousands implicitly handled
// e.g. "263,83" -> "263.83"
clean = clean.replace(',', '.');
return parseFloat(clean);
const num = parseFloat(clean);
return isNaN(num) ? 0 : num;
}
else if (clean.includes(',') && clean.includes('.')) {
// Mixed: 1.234,56 -> EU
@@ -79,7 +80,8 @@ const parseCurrency = (value: string): number => {
// 1,234.56 -> US
clean = clean.replace(/,/g, '');
}
return parseFloat(clean);
const num = parseFloat(clean);
return isNaN(num) ? 0 : num;
}
// Case B: Standard/US Format or Clean Number (e.g. "277179.09" or "1000")
@@ -832,12 +834,12 @@ export const mergeSalesAndAdsData = (
sku: meta?.sku || '',
salesTotal: 0,
unitsTotal: 0,
salesAds: ad.attributedSales30d,
unitsAds: ad.attributedUnits30d,
cost: ad.cost,
clicks: ad.clicks,
impressions: ad.impressions,
conversions: ad.conversions,
salesAds: ad.attributedSales30d || 0,
unitsAds: ad.attributedUnits30d || 0,
cost: ad.cost || 0,
clicks: ad.clicks || 0,
impressions: ad.impressions || 0,
conversions: ad.conversions || 0,
salesOrganic: 0,
unitsOrganic: 0,
paidSalesShare: 0,