/** * GET — resolve LinkedIn strategy URL + summary for active tenant * (brandbook URL, known slug map, optional ?url= override). * Used by CalendarCreator / zoom to show associated strategy content. */ import { NextRequest, NextResponse } from 'next/server'; import { createClient } from '@/lib/supabase/server'; import { resolveActiveTenant, restGet } from '@/lib/tenant-context'; import { isAgencyRole, userRole } from '@/lib/agency'; import { BRANDBOOK_DOC_TYPE, parseBrandbook, } from '@/lib/brandbook'; import { loadLinkedInStrategyContext, resolveLinkedInStrategyUrl, } from '@/lib/linkedin-strategy'; export const dynamic = 'force-dynamic'; export const maxDuration = 45; export async function GET(req: NextRequest) { const supabase = await createClient(); const { data: { user }, } = await supabase.auth.getUser(); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } if (!isAgencyRole(userRole(user))) { return NextResponse.json({ error: 'Solo agencia' }, { status: 403 }); } const ctx = await resolveActiveTenant(user); if (!ctx.tenantId || ctx.portfolioWide) { return NextResponse.json( { error: 'Selecciona un cliente en Contexto.' }, { status: 400 } ); } const override = req.nextUrl.searchParams.get('url') || ''; const postId = req.nextUrl.searchParams.get('post_id') || ''; let slug = 'cliente'; const t = await restGet<{ slug?: string }[]>( `/rest/v1/tenants?id=eq.${encodeURIComponent(ctx.tenantId)}&select=slug` ); slug = t.data?.[0]?.slug || ctx.label.toLowerCase().replace(/\s+/g, '-'); const bb = await restGet<{ content?: unknown }[]>( `/rest/v1/documents?tenant_id=eq.${encodeURIComponent( ctx.tenantId )}&type=eq.${BRANDBOOK_DOC_TYPE}&select=content&order=updated_at.desc&limit=1` ); const brandbook = parseBrandbook(bb.data?.[0]?.content); const url = resolveLinkedInStrategyUrl({ brandbook, slug, overrideUrl: override, }); if (!url) { return NextResponse.json({ ok: true, url: null, brandbook_url: brandbook?.linkedin_strategy_url || null, posts: [], themes: brandbook?.linkedin_themes || [], formats: brandbook?.linkedin_formats || [], ctas: brandbook?.linkedin_cta || [], message: 'Sin URL de estrategia LinkedIn en brandbook ni mapa conocido.', }); } const ctxLi = await loadLinkedInStrategyContext({ url, brandbook, mode: 'from_strategy', }); const posts = (ctxLi?.posts || []).map((p) => ({ id: p.id, n: p.n, title: p.title, meta: p.meta, angle: p.angle, body_preview: (p.body || '').slice(0, 500), body: postId && p.id === postId ? p.body : undefined, })); let selected = postId ? ctxLi?.posts.find((p) => p.id === postId) || null : null; return NextResponse.json({ ok: true, url, brandbook_url: brandbook?.linkedin_strategy_url || null, posts_count: ctxLi?.posts.length || 0, posts: posts.slice(0, 80), selected: selected ? { id: selected.id, title: selected.title, meta: selected.meta, angle: selected.angle, body: selected.body, } : null, themes: brandbook?.linkedin_themes || [], formats: brandbook?.linkedin_formats || [], ctas: brandbook?.linkedin_cta || [], thought_leadership: brandbook?.thought_leadership || [], }); }