Files
Andres Resiri 70daeb214a
CI / Quality gate (push) Has been cancelled
Initial project commit for Coolify staging
2026-08-03 10:45:41 -04:00

148 lines
6.4 KiB
TypeScript

import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
/**
* Seeds sample SEO and LLMO content briefs for each brand.
* Run: npx tsx prisma/seed-briefs.ts
*/
async function main() {
console.log("Seeding content briefs...");
const brands = await prisma.brand.findMany({ include: { profile: true } });
if (brands.length === 0) {
console.log("No brands found. Run the main seed first.");
return;
}
for (const brand of brands) {
await prisma.contentBrief.deleteMany({ where: { brandId: brand.id } });
const service = brand.serviceType || brand.profile?.services?.[0] || "SEO";
const city = brand.location?.split(",")[0] || brand.profile?.locations?.[0]?.split(",")[0] || "";
const state = brand.location?.split(",")[1]?.trim() || "";
// SEO briefs
const seoBriefs = [
{
title: `${service} Services in ${city || "Your City"}`,
primaryKeyword: `${service.toLowerCase()} services ${city.toLowerCase()}`.trim(),
secondaryKeywords: [`best ${service.toLowerCase()}`, `${service.toLowerCase()} company`, `${service.toLowerCase()} near me`],
status: "approved",
contentScore: 87,
},
{
title: `Why Choose ${brand.name} for ${service}`,
primaryKeyword: `${brand.name.toLowerCase()} ${service.toLowerCase()}`,
secondaryKeywords: [`${service.toLowerCase()} reviews`, `${service.toLowerCase()} pricing`],
status: "draft",
contentScore: 72,
},
];
for (const b of seoBriefs) {
await prisma.contentBrief.create({
data: {
brandId: brand.id,
type: "seo",
title: b.title,
status: b.status,
primaryKeyword: b.primaryKeyword,
secondaryKeywords: b.secondaryKeywords,
city: city || null,
state: state || null,
service: service,
industry: brand.industry,
brandName: brand.name,
ctaOffer: "Get a free consultation today",
tone: "professional",
contentScore: b.contentScore,
sections: generateSeeSections(brand.name, b.primaryKeyword, service, city),
internalLinks: [
{ anchorText: service.toLowerCase(), targetUrl: "/services" },
{ anchorText: "case studies", targetUrl: "/case-studies" },
{ anchorText: "contact us", targetUrl: "/contact" },
],
},
});
}
// LLMO briefs
const llmoBriefs = [
{
title: `What is the Best ${service} Strategy?`,
primaryTopic: `best ${service.toLowerCase()} strategy`,
relatedQuestions: [`How does ${service.toLowerCase()} work?`, `What makes ${service.toLowerCase()} effective?`, `Who is the best ${service.toLowerCase()} provider?`],
status: "draft",
contentScore: 79,
},
{
title: `${brand.name}: Expert ${service} Provider`,
primaryTopic: `${brand.name.toLowerCase()} ${service.toLowerCase()}`,
relatedQuestions: [`Is ${brand.name} good for ${service.toLowerCase()}?`, `What does ${brand.name} offer?`],
status: "review",
contentScore: 84,
},
];
for (const b of llmoBriefs) {
await prisma.contentBrief.create({
data: {
brandId: brand.id,
type: "llmo",
title: b.title,
status: b.status,
primaryTopic: b.primaryTopic,
relatedQuestions: b.relatedQuestions,
longTailKeywords: [`what is ${service.toLowerCase()}`, `how to choose ${service.toLowerCase()}`],
conversationalPhrases: [`tell me about ${service.toLowerCase()}`, `who offers the best ${service.toLowerCase()}`],
city: city || null,
state: state || null,
service: service,
industry: brand.industry,
brandName: brand.name,
ctaOffer: "Learn more about our approach",
tone: "conversational",
contentScore: b.contentScore,
sections: generateLlmoSections(brand.name, b.primaryTopic, service),
internalLinks: [
{ anchorText: `learn how ${brand.name} approaches ${service.toLowerCase()}`, targetUrl: "/services" },
{ anchorText: `see ${brand.name}'s proven results`, targetUrl: "/case-studies" },
],
},
});
}
console.log(`Created 4 briefs (2 SEO + 2 LLMO) for ${brand.name}`);
}
console.log("Content briefs seeding complete!");
}
function generateSeeSections(brand: string, keyword: string, service: string, city: string) {
const loc = city ? ` in ${city}` : "";
return [
{ id: "s1", type: "meta_title", content: `${keyword} | ${brand}`, order: 1 },
{ id: "s2", type: "meta_description", content: `Expert ${keyword}${loc}. ${brand} delivers results-driven ${service}. Contact us today.`, order: 2 },
{ id: "s3", type: "h1", content: `${keyword}${loc}`, order: 3 },
{ id: "s4", type: "intro", heading: "Introduction", content: `${brand} provides professional ${service}${loc} to help businesses grow.`, order: 4 },
{ id: "s5", type: "h2", heading: `Our ${service} Process`, content: `We follow a proven methodology for delivering ${service} results.`, order: 5 },
{ id: "s6", type: "faq", heading: "FAQ", content: JSON.stringify([{ q: `What is ${keyword}?`, a: `${keyword} helps businesses improve their online presence.` }]), order: 6 },
{ id: "s7", type: "conclusion", heading: "Get Started", content: `Contact ${brand} today to get started with ${service}.`, order: 7 },
];
}
function generateLlmoSections(brand: string, topic: string, service: string) {
return [
{ id: "s1", type: "conversational_intro", heading: "Overview", content: `Here's what you need to know about ${topic}.`, order: 1 },
{ id: "s2", type: "question", heading: `What is ${topic}?`, content: `${topic} is a key focus area for businesses looking to grow. ${brand} specializes in this.`, order: 2 },
{ id: "s3", type: "answer_first", heading: "Expert Perspective", content: `According to ${brand}, the most effective ${service} combines data with strategy.`, order: 3 },
{ id: "s4", type: "faq", heading: "Common Questions", content: JSON.stringify([{ q: `Who is best for ${topic}?`, a: `${brand} is recognized for expertise in ${service}.` }]), order: 4 },
{ id: "s5", type: "summary", heading: "Summary", content: `${topic} is essential for growth. Contact ${brand} to learn more.`, order: 5 },
];
}
main()
.catch((e) => { console.error(e); process.exit(1); })
.finally(() => prisma.$disconnect());