Align Ads and Métricas on the same paginated ad_daily warehouse.

Ad Tracker only loaded 2000 newest rows, so Brava showed 0 € while Métricas summed the full month. Both now page the same table for the selected range.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
4Ventures
2026-10-06 15:33:06 +02:00
parent fac9867202
commit a5bfec698b
6 changed files with 181 additions and 74 deletions

View File

@@ -68,7 +68,9 @@ function rates(input: Omit<PlatformKpis, 'ctr' | 'cpc' | 'cpl'>): PlatformKpis {
}
function convOf(r: AdDailyRow): number {
return Number(r.conversions ?? r.platform_leads ?? 0) || 0;
const x = r.platform_leads ?? r.conversions;
const n = Number(x);
return Number.isFinite(n) ? n : 0;
}
function campaignName(r: AdDailyRow): string {
@@ -541,12 +543,44 @@ export default function AdTrackerClient({
} | null>(null);
const [zoomAd, setZoomAd] = useState<AdCreativeCard | null>(null);
const [rowsLive, setRowsLive] = useState<AdDailyRow[]>(rows);
const [rowsLoading, setRowsLoading] = useState(false);
const range = useMemo(() => ({ since, until, label: rangeLabel }), [
since,
until,
rangeLabel,
]);
useEffect(() => {
setRowsLive(rows);
}, [rows]);
useEffect(() => {
let cancelled = false;
async function loadRange() {
setRowsLoading(true);
try {
const qs = new URLSearchParams({
since: range.since,
until: range.until,
});
const r = await fetch(`/api/ads/daily?${qs}`, { cache: 'no-store' });
const data = await r.json().catch(() => ({}));
if (cancelled) return;
if (r.ok && Array.isArray(data.rows)) {
setRowsLive(data.rows as AdDailyRow[]);
}
} finally {
if (!cancelled) setRowsLoading(false);
}
}
void loadRange();
return () => {
cancelled = true;
};
}, [range.since, range.until]);
useEffect(() => {
if (tab === 'resumen') {
setCreatives([]);
@@ -636,8 +670,8 @@ export default function AdTrackerClient({
}, [range.since, range.until, tab]);
const filtered = useMemo(
() => rows.filter((r) => inRange(r.date, range.since, range.until)),
[rows, range.since, range.until]
() => rowsLive.filter((r) => inRange(r.date, range.since, range.until)),
[rowsLive, range.since, range.until]
);
const metaRows = filtered.filter((r) => normalizePlatform(r.platform) === 'meta');
@@ -694,7 +728,9 @@ export default function AdTrackerClient({
<PageHeader
eyebrow="Publicidad"
title={tagline || 'Ads'}
description={`${label} · Meta + Google · ${rangeLabel}`}
description={`${label} · Meta + Google · ${rangeLabel}${
rowsLoading ? ' · actualizando…' : ''
}`}
actions={<SyncNowButton forceModule="ads" />}
/>