feat: LinkedIn editorial, accesos agencia estables y deshacer en historial
Integra estrategias LinkedIn en calendarios (backlog publicado vs pendiente), unifica roles/cookies de vista agencia y permite deshacer cambios de brandbook dejando constancia en el historial. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
82
scripts/audit_four_brands.ts
Normal file
82
scripts/audit_four_brands.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Re-enrich TYD/TSP/ECP/DTATF + dump Drive folder scores.
|
||||
* npx tsx scripts/audit_four_brands.ts
|
||||
*/
|
||||
import { config } from 'dotenv';
|
||||
import { resolve } from 'path';
|
||||
config({ path: resolve(process.cwd(), '.env.local') });
|
||||
|
||||
import { enrichTenantBrandbook } from '../src/lib/brandbook-enrich';
|
||||
import { ensureCreativesDriveFolders } from '../src/lib/creatives-drive';
|
||||
import { listClientFoldersUnderClientes } from '../src/lib/google-drive';
|
||||
import { scoreNameToTenant } from '../src/lib/match';
|
||||
|
||||
const FOCUS = ['tyd', 'tsp', 'ecp', 'dtatf'] as const;
|
||||
|
||||
async function main() {
|
||||
const url = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
||||
const key = process.env.SUPABASE_SERVICE_ROLE_KEY!;
|
||||
const h = { apikey: key, Authorization: `Bearer ${key}` };
|
||||
|
||||
const { folders, clientesRoot } = await listClientFoldersUnderClientes();
|
||||
console.log(
|
||||
'Drive root',
|
||||
clientesRoot?.name || '(none)',
|
||||
'folders',
|
||||
folders.length
|
||||
);
|
||||
for (const f of [...folders].sort((a, b) => a.name.localeCompare(b.name))) {
|
||||
console.log(' ', f.name);
|
||||
}
|
||||
|
||||
for (const slug of FOCUS) {
|
||||
const tr = await fetch(
|
||||
`${url}/rest/v1/tenants?slug=eq.${slug}&select=id,name,slug,drive_folder_id`,
|
||||
{ headers: h }
|
||||
);
|
||||
const t = (await tr.json())[0] as
|
||||
| { id: string; name: string; slug: string; drive_folder_id?: string }
|
||||
| undefined;
|
||||
if (!t) {
|
||||
console.log(`[missing] ${slug}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const scored = folders
|
||||
.map((f) => ({
|
||||
name: f.name,
|
||||
id: f.id,
|
||||
score: scoreNameToTenant(f.name, t.name, t.slug),
|
||||
}))
|
||||
.filter((x) => x.score > 0)
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, 8);
|
||||
console.log(`\n[${slug}] folder scores`, scored);
|
||||
|
||||
const r = await enrichTenantBrandbook({
|
||||
tenantId: t.id,
|
||||
forceSeed: true,
|
||||
});
|
||||
console.log(
|
||||
`[enrich] ${slug} ok=${r.ok} created=${r.created} score=${r.completenessAfter} warn=${r.warning || '-'} sources=${r.sources.join('+')}`
|
||||
);
|
||||
|
||||
const drive = await ensureCreativesDriveFolders(t.id, slug);
|
||||
console.log(
|
||||
`[creatives-folders] ${slug}`,
|
||||
drive.ok ? 'ok' : drive.warning
|
||||
);
|
||||
|
||||
const bb = await fetch(
|
||||
`${url}/rest/v1/documents?tenant_id=eq.${t.id}&type=eq.brandbook&select=id&limit=1`,
|
||||
{ headers: h }
|
||||
);
|
||||
const rows = (await bb.json()) as { id: string }[];
|
||||
console.log(`[bb] ${slug}`, rows[0]?.id || 'MISSING');
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user