feat(skills): update BPS & static skills, add audience to brief, inline angle/hook editing and montage notes
This commit is contained in:
@@ -48,26 +48,32 @@ export async function POST(req: NextRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
const toInsert = items.map((c: any) => ({
|
||||
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: c.meta || {},
|
||||
}));
|
||||
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')
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function POST(req: NextRequest) {
|
||||
// 1. Obtener la creatividad a marcar
|
||||
const { data: creative, error: getErr } = await adminClient
|
||||
.from('creatives')
|
||||
.select('*, tenant:tenants(slug, name)')
|
||||
.select('*, tenant:tenants(slug, name, campaign_audience)')
|
||||
.eq('id', creativeId)
|
||||
.eq('tenant_id', tenantId)
|
||||
.maybeSingle();
|
||||
@@ -77,7 +77,17 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
if (rules?.auto_request_relief) {
|
||||
const avoidAngles = creative.angle ? [creative.angle] : [];
|
||||
const clientSlug = creative.tenant?.slug || 'bps';
|
||||
const clientSlug = (creative.tenant as any)?.slug || 'bps';
|
||||
const campaignAudienceMap = (creative.tenant as any)?.campaign_audience || {};
|
||||
const campaignName = creative.campaign_name || '';
|
||||
|
||||
let audience: 'b2b' | 'b2c' | null = null;
|
||||
if (campaignName && campaignAudienceMap && typeof campaignAudienceMap === 'object' && campaignAudienceMap[campaignName]) {
|
||||
const val = String(campaignAudienceMap[campaignName]).toLowerCase().trim();
|
||||
if (val === 'b2b' || val === 'b2c') {
|
||||
audience = val;
|
||||
}
|
||||
}
|
||||
|
||||
const deadline = new Date();
|
||||
deadline.setDate(deadline.getDate() + 1); // 24 horas después
|
||||
@@ -94,6 +104,7 @@ export async function POST(req: NextRequest) {
|
||||
avoid_angles: avoidAngles,
|
||||
campaign_name: creative.campaign_name || 'General',
|
||||
adset_id: creative.adset_id || null,
|
||||
audience,
|
||||
language: 'es',
|
||||
deadline: deadline.toISOString(),
|
||||
};
|
||||
|
||||
@@ -4,6 +4,8 @@ import { createClient } from '@supabase/supabase-js';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const auth = await authenticateIntegrationRequest(req, { requireTenant: true });
|
||||
if (!auth.ok) {
|
||||
@@ -61,13 +63,20 @@ export async function GET(req: NextRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
data: {
|
||||
return NextResponse.json(
|
||||
{
|
||||
data: {
|
||||
client_skill: clientSkill,
|
||||
format_skill: formatSkill,
|
||||
},
|
||||
// Compatibilidad en primer nivel
|
||||
client_skill: clientSkill,
|
||||
format_skill: formatSkill,
|
||||
},
|
||||
// Compatibilidad en primer nivel
|
||||
client_skill: clientSkill,
|
||||
format_skill: formatSkill,
|
||||
});
|
||||
{
|
||||
headers: {
|
||||
'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user