import { NextRequest, NextResponse } from 'next/server'; import { authenticateIntegrationRequest } from '@/lib/integrations-auth'; import { createClient } from '@supabase/supabase-js'; export async function POST(req: NextRequest) { let body: any; try { body = await req.json(); } catch { return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 }); } const auth = await authenticateIntegrationRequest(req, { requireTenant: true, parsedBody: body }); if (!auth.ok) { return auth.errorResponse!; } const tenantId = auth.tenantId!; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; const adminClient = createClient(supabaseUrl, serviceRoleKey); // Acepta array o un único objeto const items = Array.isArray(body) ? body : Array.isArray(body.creatives) ? body.creatives : [body]; if (!items.length) { return NextResponse.json({ error: 'No creatives provided' }, { status: 400 }); } // Si viene generation_request_id, averiguar parent_id (source_creative_id del request) let defaultParentId: string | null = null; const genRequestId = body.generation_request_id || items[0]?.generation_request_id; if (genRequestId) { const { data: genReq } = await adminClient .from('generation_requests') .select('source_creative_id') .eq('id', genRequestId) .eq('tenant_id', tenantId) .maybeSingle(); if (genReq) { defaultParentId = genReq.source_creative_id; } } const toInsert = items.map((c: any) => { const meta = { ...(c.meta || {}) }; if (c.composition_notes) { meta.composition_notes = c.composition_notes; } return { tenant_id: tenantId, campaign_name: c.campaign_name || null, adset_id: c.adset_id || null, meta_ad_id: c.meta_ad_id || null, format: c.format || 'estatico', angle: c.angle || null, hook: c.hook || null, primary_text: c.primary_text || null, headline: c.headline || null, cta: c.cta || null, asset_url: c.asset_url || null, thumbnail_url: c.thumbnail_url || null, status: 'borrador', // nacen siempre en borrador visibility: 'agency', // nacen siempre en agency created_by: 'claude', // creadas por Claude parent_id: c.parent_id || defaultParentId, generation_request_id: c.generation_request_id || genRequestId || null, meta, }; }); const { data: inserted, error } = await adminClient .from('creatives') .insert(toInsert) .select('*'); if (error) { return NextResponse.json({ error: error.message }, { status: 500 }); } // Registrar cada creación en creative_events con actor 'claude' for (const c of inserted || []) { await adminClient.from('creative_events').insert({ tenant_id: tenantId, creative_id: c.id, event_type: 'creative_generated', actor: 'claude', to_status: 'borrador', payload: { angle: c.angle, format: c.format, generation_request_id: c.generation_request_id, parent_id: c.parent_id, }, visibility: 'agency', }); } return NextResponse.json({ ok: true, count: inserted?.length || 0, creatives: inserted, }); } export async function GET(req: NextRequest) { const auth = await authenticateIntegrationRequest(req, { requireTenant: true }); if (!auth.ok) { return auth.errorResponse!; } const tenantId = auth.tenantId!; const status = req.nextUrl.searchParams.get('status'); const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; const adminClient = createClient(supabaseUrl, serviceRoleKey); let query = adminClient .from('creatives') .select('*') .eq('tenant_id', tenantId); if (status) { query = query.eq('status', status); } const { data: creatives, error } = await query; if (error) { return NextResponse.json({ error: error.message }, { status: 500 }); } return NextResponse.json(creatives || []); }