feat(integrations): support history_days in fatigue candidates and ensure data envelope for WF2
This commit is contained in:
@@ -24,11 +24,20 @@ export async function GET(req: NextRequest) {
|
|||||||
return NextResponse.json({ error: rulesErr.message }, { status: 500 });
|
return NextResponse.json({ error: rulesErr.message }, { status: 500 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const lookbackDays = rules?.lookback_days || 7;
|
const lookbackDays = Number(rules?.lookback_days || 7);
|
||||||
|
const minHistory = lookbackDays * 2;
|
||||||
|
|
||||||
// 2. Calcular fecha de inicio según lookback_days
|
// Query param history_days (por defecto 28, mínimo lookback_days * 2)
|
||||||
|
const url = new URL(req.url);
|
||||||
|
const rawHistory = url.searchParams.get('history_days');
|
||||||
|
let historyDays = rawHistory ? parseInt(rawHistory, 10) : 28;
|
||||||
|
if (isNaN(historyDays) || historyDays < minHistory) {
|
||||||
|
historyDays = Math.max(28, minHistory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Calcular fecha de inicio según history_days
|
||||||
const sinceDate = new Date();
|
const sinceDate = new Date();
|
||||||
sinceDate.setDate(sinceDate.getDate() - lookbackDays);
|
sinceDate.setDate(sinceDate.getDate() - historyDays);
|
||||||
const sinceStr = sinceDate.toISOString().split('T')[0];
|
const sinceStr = sinceDate.toISOString().split('T')[0];
|
||||||
|
|
||||||
// 3. Buscar creatividades actualmente publicadas para este cliente
|
// 3. Buscar creatividades actualmente publicadas para este cliente
|
||||||
@@ -51,7 +60,7 @@ export async function GET(req: NextRequest) {
|
|||||||
if (metaIds.length > 0) {
|
if (metaIds.length > 0) {
|
||||||
const { data: metrics, error: metricsErr } = await adminClient
|
const { data: metrics, error: metricsErr } = await adminClient
|
||||||
.from('creative_metrics_daily')
|
.from('creative_metrics_daily')
|
||||||
.select('*')
|
.select('date, impressions, reach, clicks, ctr, frequency, spend, results, cpa, meta_ad_id')
|
||||||
.eq('tenant_id', tenantId)
|
.eq('tenant_id', tenantId)
|
||||||
.in('meta_ad_id', metaIds)
|
.in('meta_ad_id', metaIds)
|
||||||
.gte('date', sinceStr)
|
.gte('date', sinceStr)
|
||||||
@@ -63,22 +72,43 @@ export async function GET(req: NextRequest) {
|
|||||||
|
|
||||||
(metrics || []).forEach((m: any) => {
|
(metrics || []).forEach((m: any) => {
|
||||||
const list = metricsMap.get(m.meta_ad_id) || [];
|
const list = metricsMap.get(m.meta_ad_id) || [];
|
||||||
list.push(m);
|
list.push({
|
||||||
|
date: m.date,
|
||||||
|
impressions: Number(m.impressions || 0),
|
||||||
|
reach: Number(m.reach || 0),
|
||||||
|
clicks: Number(m.clicks || 0),
|
||||||
|
ctr: Number(m.ctr || 0),
|
||||||
|
frequency: Number(m.frequency || 0),
|
||||||
|
spend: Number(m.spend || 0),
|
||||||
|
results: Number(m.results || 0),
|
||||||
|
cpa: m.cpa !== null && m.cpa !== undefined ? Number(m.cpa) : null,
|
||||||
|
});
|
||||||
metricsMap.set(m.meta_ad_id, list);
|
metricsMap.set(m.meta_ad_id, list);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const candidates = (publishedCreatives || []).map((c: any) => ({
|
const creatives = (publishedCreatives || []).map((c: any) => ({
|
||||||
...c,
|
id: c.id,
|
||||||
client_id: c.tenant_id,
|
meta_ad_id: c.meta_ad_id,
|
||||||
|
hook: c.hook,
|
||||||
|
angle: c.angle,
|
||||||
|
campaign_name: c.campaign_name,
|
||||||
metrics: metricsMap.get(c.meta_ad_id) || [],
|
metrics: metricsMap.get(c.meta_ad_id) || [],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const dataPayload = {
|
||||||
|
rules: rules || null,
|
||||||
|
creatives,
|
||||||
|
};
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
|
data: dataPayload,
|
||||||
client_id: tenantId,
|
client_id: tenantId,
|
||||||
tenant_id: tenantId,
|
tenant_id: tenantId,
|
||||||
lookback_days: lookbackDays,
|
lookback_days: lookbackDays,
|
||||||
|
history_days: historyDays,
|
||||||
rules: rules || null,
|
rules: rules || null,
|
||||||
candidates,
|
creatives,
|
||||||
|
candidates: creatives,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,5 +131,11 @@ export async function POST(req: NextRequest) {
|
|||||||
status: 'fatigada',
|
status: 'fatigada',
|
||||||
signals,
|
signals,
|
||||||
generation_request: generationRequest,
|
generation_request: generationRequest,
|
||||||
|
data: {
|
||||||
|
creative_id: creativeId,
|
||||||
|
status: 'fatigada',
|
||||||
|
signals,
|
||||||
|
generation_request: generationRequest,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user