fix(publish): no saltar piezas programadas en revisión

El cron también publica revision_agencia/programada con horario vencido; mover en calendario deja la pieza en cola.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
4Ventures
2026-10-16 15:55:12 +02:00
parent 4c91c4b1f4
commit 812052b7eb
2 changed files with 20 additions and 5 deletions

View File

@@ -105,6 +105,10 @@ async function syncPipelineSchedule(
},
body: JSON.stringify({
scheduled_at: scheduledAt,
// Mover en calendario = reprogramar: el cron debe poder publicarla
status: 'aprobada',
publish_status: 'queued',
publish_error: null,
updated_at: new Date().toISOString(),
}),
}

View File

@@ -94,10 +94,13 @@ export async function processDuePipelinePublishes(opts?: {
const now = new Date().toISOString();
const limit = Math.min(50, Math.max(1, opts?.limit || 10));
// Two complementary queries (PostgREST OR with nested AND is fragile).
// Complementary queries (PostgREST OR with nested AND is fragile).
// Incluye revision_agencia/programada en idle: a veces se programa
// desde calendario sin pasar por el flujo que pone publish_status=queued.
const common =
`scheduled_at=lte.${encodeURIComponent(now)}` +
`&cover_path=not.is.null` +
`&published_at=is.null` +
`&select=${SELECT}&order=scheduled_at.asc&limit=${limit}` +
(opts?.tenantId
? `&tenant_id=eq.${encodeURIComponent(opts.tenantId)}`
@@ -108,13 +111,20 @@ export async function processDuePipelinePublishes(opts?: {
`${base}/rest/v1/creative_pipeline?publish_status=in.(queued,failed)&${common}`;
const q2 =
`${base}/rest/v1/creative_pipeline?publish_status=eq.idle&status=eq.aprobada&${common}`;
const q3 =
`${base}/rest/v1/creative_pipeline?publish_status=eq.idle&status=in.(revision_agencia,programada)&${common}`;
const [r1, r2] = await Promise.all([
const [r1, r2, r3] = await Promise.all([
fetch(q1, { headers, cache: 'no-store' }),
fetch(q2, { headers, cache: 'no-store' }),
fetch(q3, { headers, cache: 'no-store' }),
]);
if (!r1.ok || !r2.ok) {
const err = !r1.ok ? await r1.text() : await r2.text();
if (!r1.ok || !r2.ok || !r3.ok) {
const err = !r1.ok
? await r1.text()
: !r2.ok
? await r2.text()
: await r3.text();
return { ok: false, due: 0, results: [], error: err.slice(0, 400) };
}
@@ -124,9 +134,10 @@ export async function processDuePipelinePublishes(opts?: {
updated_at?: string;
})[];
const b = (await r2.json()) as typeof a;
const c = (await r3.json()) as typeof a;
const seen = new Set<string>();
const due: typeof a = [];
for (const row of [...a, ...b]) {
for (const row of [...a, ...b, ...c]) {
if (seen.has(row.id)) continue;
seen.add(row.id);
due.push(row);