import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); async function main() { console.log("Seeding audit data..."); const brands = await prisma.brand.findMany(); if (brands.length === 0) { console.log("No brands. Run main seed first."); return; } for (const brand of brands) { // Clear existing await prisma.technicalIssue.deleteMany({ where: { audit: { brandId: brand.id } } }); await prisma.technicalAudit.deleteMany({ where: { brandId: brand.id } }); await prisma.deadPageSource.deleteMany({ where: { deadPage: { brandId: brand.id } } }); await prisma.deadPage.deleteMany({ where: { brandId: brand.id } }); await prisma.performancePageScore.deleteMany({ where: { audit: { brandId: brand.id } } }); await prisma.performanceAudit.deleteMany({ where: { brandId: brand.id } }); // ── Technical Audit ── await prisma.technicalAudit.create({ data: { brandId: brand.id, crawlHealth: 68, pagesScanned: 1248, duration: 262, errorCount: 17, warningCount: 34, noticeCount: 12, passedCount: 89, issues: { create: [ { category: "metadata", severity: "critical", title: "Missing meta description", detail: "14 pages have no meta description tag", pageUrl: "/features", affected: 14 }, { category: "metadata", severity: "critical", title: "Duplicate title tags", detail: "6 pages share identical title tags", pageUrl: "/products", affected: 6 }, { category: "links", severity: "critical", title: "Broken internal links", detail: "17 links point to pages that return 404", pageUrl: "/blog", affected: 17 }, { category: "headings", severity: "medium", title: "Images missing alt text", detail: "31 images have no alt attribute", pageUrl: "/about", affected: 31 }, { category: "crawl", severity: "medium", title: "Oversized images (>200 KB)", detail: "23 images exceed recommended size", pageUrl: "/products", affected: 23 }, { category: "metadata", severity: "medium", title: "No structured data", detail: "8 pages have no schema markup", pageUrl: "/services", affected: 8 }, { category: "crawl", severity: "medium", title: "HTTP links on HTTPS page", detail: "4 mixed content resources detected", pageUrl: "/about", affected: 4 }, { category: "headings", severity: "low", title: "Missing H1 tag", detail: "3 pages have no H1 element", pageUrl: "/contact", affected: 3 }, { category: "crawl", severity: "low", title: "Slow page load (>3 s)", detail: "9 pages exceed 3 second load time", pageUrl: "/pricing", affected: 9 }, { category: "indexability", severity: "low", title: "Missing canonical tags", detail: "11 pages have no canonical URL", pageUrl: "/blog", affected: 11 }, { category: "redirects", severity: "medium", title: "Redirect chains", detail: "3 URLs have 2+ redirects before final", pageUrl: "/old-pricing", affected: 3 }, { category: "indexability", severity: "medium", title: "Noindex on important pages", detail: "2 service pages accidentally blocked", pageUrl: "/services/seo", affected: 2 }, ], }, }, }); console.log(` Technical audit: 12 issues for ${brand.name}`); // ── Dead 404 Pages ── const deadPages = [ { deadUrl: "/old-pricing", priority: "high", suggestedFix: "Redirect to /pricing", sources: [{ sourceUrl: "/about", anchorText: "our pricing" }, { sourceUrl: "/blog/launch", anchorText: "pricing page" }] }, { deadUrl: "/blog/2022/launch", priority: "medium", suggestedFix: "Redirect to /blog", sources: [{ sourceUrl: "/blog", anchorText: "launch post" }] }, { deadUrl: "/products/legacy", priority: "medium", suggestedFix: "Redirect to /products", sources: [{ sourceUrl: "/features", anchorText: "legacy product" }, { sourceUrl: "/about", anchorText: "our first product" }] }, { deadUrl: "/team/jane-old-bio", priority: "low", suggestedFix: "Redirect to /about#team", sources: [{ sourceUrl: "/blog/team-update", anchorText: "Jane's bio" }] }, { deadUrl: "/downloads/brochure-v1", priority: "low", suggestedFix: "Remove links or upload new version", sources: [{ sourceUrl: "/contact", anchorText: "download brochure" }] }, ]; for (const dp of deadPages) { await prisma.deadPage.create({ data: { brandId: brand.id, deadUrl: dp.deadUrl, priority: dp.priority, suggestedFix: dp.suggestedFix, sources: { create: dp.sources }, }, }); } console.log(` Dead pages: ${deadPages.length} for ${brand.name}`); // ── Performance Audit (mobile) ── const mobilePages = [ { pageUrl: "/", performance: 64, accessibility: 89, bestPractices: 78, seo: 92, lcpMs: 3800, inpMs: 280, clsVal: 0.04, fcpMs: 2100, ttfbMs: 620 }, { pageUrl: "/about", performance: 72, accessibility: 91, bestPractices: 83, seo: 95, lcpMs: 2900, inpMs: 180, clsVal: 0.02, fcpMs: 1800, ttfbMs: 540 }, { pageUrl: "/pricing", performance: 45, accessibility: 78, bestPractices: 72, seo: 88, lcpMs: 5100, inpMs: 420, clsVal: 0.18, fcpMs: 3200, ttfbMs: 890 }, { pageUrl: "/blog", performance: 81, accessibility: 93, bestPractices: 89, seo: 97, lcpMs: 1800, inpMs: 120, clsVal: 0.01, fcpMs: 1100, ttfbMs: 380 }, { pageUrl: "/contact", performance: 91, accessibility: 95, bestPractices: 92, seo: 98, lcpMs: 1100, inpMs: 90, clsVal: 0.00, fcpMs: 800, ttfbMs: 340 }, { pageUrl: "/products", performance: 52, accessibility: 82, bestPractices: 75, seo: 85, lcpMs: 4400, inpMs: 350, clsVal: 0.12, fcpMs: 2800, ttfbMs: 720 }, { pageUrl: "/features", performance: 58, accessibility: 84, bestPractices: 77, seo: 87, lcpMs: 4000, inpMs: 310, clsVal: 0.09, fcpMs: 2500, ttfbMs: 680 }, { pageUrl: "/login", performance: 93, accessibility: 96, bestPractices: 91, seo: 90, lcpMs: 900, inpMs: 70, clsVal: 0.00, fcpMs: 600, ttfbMs: 280 }, ]; await prisma.performanceAudit.create({ data: { brandId: brand.id, device: "mobile", pages: { create: mobilePages.map((p) => ({ ...p, device: "mobile", status: p.performance >= 90 ? "pass" : p.performance >= 50 ? "average" : "fail", })), }, }, }); console.log(` Performance audit: ${mobilePages.length} pages (mobile) for ${brand.name}`); // ── Performance Audit (desktop) ── const desktopPages = mobilePages.map((p) => ({ ...p, performance: Math.min(100, p.performance + 20), lcpMs: Math.round(p.lcpMs * 0.5), inpMs: Math.round(p.inpMs * 0.5), clsVal: Math.round(p.clsVal * 0.5 * 100) / 100, fcpMs: Math.round(p.fcpMs * 0.5), ttfbMs: Math.round(p.ttfbMs * 0.6), })); await prisma.performanceAudit.create({ data: { brandId: brand.id, device: "desktop", pages: { create: desktopPages.map((p) => ({ ...p, device: "desktop", status: p.performance >= 90 ? "pass" : p.performance >= 50 ? "average" : "fail", })), }, }, }); console.log(` Performance audit: ${desktopPages.length} pages (desktop) for ${brand.name}`); } console.log("Audit seeding complete!"); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());