/** * Backfill pipeline covers/slides → client Drive folder tree. * npx tsx scripts/backfill_pipeline_drive.ts [tenantSlug] */ import { config } from 'dotenv'; import { resolve } from 'path'; config({ path: resolve(process.cwd(), '.env.local') }); import { serviceHeaders, supabaseUrl } from '../src/lib/agency'; import { backfillPipelineItemToDrive } from '../src/lib/pipeline-drive'; async function main() { const slugFilter = process.argv[2]?.trim(); const headers = serviceHeaders(); const base = supabaseUrl(); if (!headers || !base) throw new Error('service role missing'); const tRes = await fetch(`${base}/rest/v1/tenants?select=id,name,slug`, { headers, cache: 'no-store', }); let tenants = (await tRes.json()) as { id: string; name: string; slug: string; }[]; if (slugFilter) { tenants = tenants.filter( (t) => t.slug === slugFilter || t.name.toLowerCase().includes(slugFilter.toLowerCase()) ); } if (!tenants.length) throw new Error('no tenants'); for (const t of tenants) { const pRes = await fetch( `${base}/rest/v1/creative_pipeline?tenant_id=eq.${encodeURIComponent( t.id )}&cover_path=not.is.null&select=id,title,format,caption,notes,scheduled_at,created_at,cover_path,slide_paths&order=created_at.desc&limit=50`, { headers, cache: 'no-store' } ); const pieces = pRes.ok ? await pRes.json() : []; console.log(`\n=== ${t.name} (${pieces.length} con portada) ===`); for (const item of pieces) { const r = await backfillPipelineItemToDrive({ tenantId: t.id, clientLabel: t.slug || t.name, item, }); console.log( item.title, r.ok ? 'OK' : 'PARTIAL', r.results.map((x) => `${x.slot}:${x.detail}`).join(' | ') ); } } } main().catch((e) => { console.error(e); process.exit(1); });