feat(skills): update BPS & static skills, add audience to brief, inline angle/hook editing and montage notes

This commit is contained in:
Marcos Fargas
2026-10-12 20:32:15 +02:00
parent 34ce46774d
commit 317a3aa46d
9 changed files with 277 additions and 55 deletions

View File

@@ -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')

View File

@@ -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(),
};

View File

@@ -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',
},
}
);
}