feat(creatives): task 5 - approval actions, outgoing webhooks with HMAC, and publish patch
This commit is contained in:
82
src/app/api/integrations/creatives/[id]/route.ts
Normal file
82
src/app/api/integrations/creatives/[id]/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { authenticateIntegrationRequest } from '@/lib/integrations-auth';
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
|
||||
export async function PATCH(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
let body: any;
|
||||
try {
|
||||
body = await req.json();
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
|
||||
}
|
||||
|
||||
const { id } = await params;
|
||||
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);
|
||||
|
||||
// Obtener creatividad previa
|
||||
const { data: creative, error: getErr } = await adminClient
|
||||
.from('creatives')
|
||||
.select('*')
|
||||
.eq('id', id)
|
||||
.eq('tenant_id', tenantId)
|
||||
.maybeSingle();
|
||||
|
||||
if (getErr || !creative) {
|
||||
return NextResponse.json({ error: 'Creatividad no encontrada' }, { status: 404 });
|
||||
}
|
||||
|
||||
const prevStatus = creative.status;
|
||||
|
||||
const updates: Record<string, any> = {
|
||||
updated_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
if (body.meta_ad_id !== undefined) updates.meta_ad_id = body.meta_ad_id;
|
||||
if (body.status !== undefined) updates.status = body.status;
|
||||
if (body.adset_id !== undefined) updates.adset_id = body.adset_id;
|
||||
if (body.campaign_name !== undefined) updates.campaign_name = body.campaign_name;
|
||||
if (body.asset_url !== undefined) updates.asset_url = body.asset_url;
|
||||
if (body.thumbnail_url !== undefined) updates.thumbnail_url = body.thumbnail_url;
|
||||
|
||||
const { data: updated, error: updateErr } = await adminClient
|
||||
.from('creatives')
|
||||
.update(updates)
|
||||
.eq('id', id)
|
||||
.eq('tenant_id', tenantId)
|
||||
.select('*')
|
||||
.single();
|
||||
|
||||
if (updateErr) {
|
||||
return NextResponse.json({ error: updateErr.message }, { status: 500 });
|
||||
}
|
||||
|
||||
// Si pasa a publicada o cambia meta_ad_id, registrar en creative_events
|
||||
if (updates.status === 'publicada' || updates.meta_ad_id) {
|
||||
await adminClient.from('creative_events').insert({
|
||||
tenant_id: tenantId,
|
||||
creative_id: id,
|
||||
event_type: updates.status === 'publicada' ? 'published' : 'creative_updated',
|
||||
actor: auth.caller || 'n8n',
|
||||
from_status: prevStatus,
|
||||
to_status: updates.status || prevStatus,
|
||||
payload: {
|
||||
meta_ad_id: updates.meta_ad_id || creative.meta_ad_id,
|
||||
adset_id: updates.adset_id,
|
||||
},
|
||||
visibility: 'client',
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json(updated);
|
||||
}
|
||||
Reference in New Issue
Block a user