import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); /** * Seeds tasks and page launches for each brand. * Run: npx tsx prisma/seed-tasks.ts */ async function main() { console.log("Seeding tasks and page launches..."); const brands = await prisma.brand.findMany(); if (brands.length === 0) { console.log("No brands found. Run the main seed first."); return; } for (const brand of brands) { // Clear existing await prisma.pageLaunchSnapshot.deleteMany({ where: { pageLaunch: { brandId: brand.id } }, }); await prisma.pageLaunch.deleteMany({ where: { brandId: brand.id } }); await prisma.task.deleteMany({ where: { brandId: brand.id } }); // ── Tasks ── const tasks = [ { title: "Add meta descriptions to 14 pages", category: "seo", priority: "high", effort: "low", status: "completed", pageUrl: "/features", recommendation: "Missing meta descriptions reduce CTR by ~15%", daysAgo: 21 }, { title: "Fix 17 broken internal links", category: "technical", priority: "high", effort: "medium", status: "completed", pageUrl: "/blog", recommendation: "Broken links waste crawl budget and link equity", daysAgo: 18 }, { title: "Optimize hero images for Core Web Vitals", category: "technical", priority: "high", effort: "low", status: "completed", pageUrl: "/pricing", recommendation: "LCP is 3.8s — compress images to get under 2.5s", daysAgo: 14 }, { title: "Publish SEO pillar page: AI Tools Guide", category: "content", priority: "high", effort: "high", status: "completed", pageUrl: "/blog/ai-tools", recommendation: "Target 'AI SEO tools' — 6.8K monthly searches, low competition", daysAgo: 10 }, { title: "Add FAQ schema to top 5 guides", category: "seo", priority: "medium", effort: "low", status: "in_progress", pageUrl: "/blog/seo-guide", recommendation: "FAQ schema increases AI citation probability by ~40%", daysAgo: 7 }, { title: "Improve mobile speed on /products", category: "technical", priority: "high", effort: "medium", status: "in_progress", pageUrl: "/products", recommendation: "Mobile score 52/100 — defer JS and lazy-load images", daysAgo: 5 }, { title: "Update GBP listing with new services", category: "gbp", priority: "medium", effort: "low", status: "todo", pageUrl: null, recommendation: "GBP listings with complete info get 7x more clicks", daysAgo: 3 }, { title: "Create comparison page: meSEO vs RankBoost", category: "content", priority: "medium", effort: "high", status: "todo", pageUrl: "/vs-rankboost", recommendation: "Comparison pages capture 800-2000 visits/mo in your category", daysAgo: 2 }, { title: "Optimize AI visibility for Perplexity", category: "llmo", priority: "high", effort: "medium", status: "todo", pageUrl: "/features", recommendation: "Competitor displaced you — publish competing technical guide", daysAgo: 1 }, { title: "Fix HTTP mixed content on 4 pages", category: "technical", priority: "low", effort: "low", status: "todo", pageUrl: "/about", recommendation: "HTTPS pages with HTTP resources trigger security warnings", daysAgo: 0 }, ]; const createdTasks: Record = {}; for (const t of tasks) { const createdAt = new Date(); createdAt.setDate(createdAt.getDate() - t.daysAgo); const task = await prisma.task.create({ data: { brandId: brand.id, title: t.title, category: t.category, priority: t.priority, effort: t.effort, status: t.status, pageUrl: t.pageUrl, recommendation: t.recommendation, completedAt: t.status === "completed" ? new Date(createdAt.getTime() + 3 * 86400000) : null, dueDate: new Date(Date.now() + (t.status === "todo" ? 7 : 14) * 86400000), createdAt, }, }); createdTasks[t.title] = task.id; } console.log(` Created ${tasks.length} tasks for ${brand.name}`); // ── Page Launches (from completed tasks) ── const launches = [ { taskTitle: "Add meta descriptions to 14 pages", pageUrl: "/features", pageType: "landing", daysAgo: 18, baseline: { sessions: 120, clicks: 80, impressions: 2400, position: 14.2, conversions: 3, revenue: 240 }, snapshots: [ { daysAgo: 14, sessions: 135, clicks: 95, impressions: 2800, position: 12.8, conversions: 4, revenue: 320 }, { daysAgo: 7, sessions: 158, clicks: 118, impressions: 3200, position: 10.5, conversions: 6, revenue: 480 }, { daysAgo: 0, sessions: 172, clicks: 132, impressions: 3600, position: 9.1, conversions: 7, revenue: 560 }, ], }, { taskTitle: "Fix 17 broken internal links", pageUrl: "/blog", pageType: "blog", daysAgo: 15, baseline: { sessions: 280, clicks: 160, impressions: 5200, position: 11.4, conversions: 5, revenue: 0 }, snapshots: [ { daysAgo: 10, sessions: 310, clicks: 185, impressions: 5800, position: 10.2, conversions: 6, revenue: 0 }, { daysAgo: 3, sessions: 340, clicks: 210, impressions: 6400, position: 9.5, conversions: 8, revenue: 0 }, { daysAgo: 0, sessions: 355, clicks: 225, impressions: 6800, position: 8.8, conversions: 9, revenue: 0 }, ], }, { taskTitle: "Publish SEO pillar page: AI Tools Guide", pageUrl: "/blog/ai-tools", pageType: "blog", daysAgo: 7, baseline: { sessions: 0, clicks: 0, impressions: 0, position: 0, conversions: 0, revenue: 0 }, snapshots: [ { daysAgo: 4, sessions: 45, clicks: 28, impressions: 820, position: 18.4, conversions: 1, revenue: 0 }, { daysAgo: 0, sessions: 120, clicks: 78, impressions: 2200, position: 11.2, conversions: 3, revenue: 0 }, ], }, ]; for (const l of launches) { const taskId = createdTasks[l.taskTitle]; const launchDate = new Date(); launchDate.setDate(launchDate.getDate() - l.daysAgo); const launch = await prisma.pageLaunch.create({ data: { brandId: brand.id, taskId, pageUrl: l.pageUrl, pageType: l.pageType, launchDate, notes: `Launched after completing: ${l.taskTitle}`, baselineSessions: l.baseline.sessions, baselineClicks: l.baseline.clicks, baselineImpressions: l.baseline.impressions, baselinePosition: l.baseline.position, baselineConversions: l.baseline.conversions, baselineRevenue: l.baseline.revenue, }, }); // Add snapshots for (const s of l.snapshots) { const snapshotDate = new Date(); snapshotDate.setDate(snapshotDate.getDate() - s.daysAgo); await prisma.pageLaunchSnapshot.create({ data: { pageLaunchId: launch.id, date: snapshotDate, sessions: s.sessions, clicks: s.clicks, impressions: s.impressions, position: s.position, conversions: s.conversions, revenue: s.revenue, }, }); } } console.log(` Created ${launches.length} page launches with snapshots for ${brand.name}`); } console.log("Tasks and page launches seeding complete!"); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());