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

156 lines
7.6 KiB
TypeScript

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<string, string> = {};
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());