/** * Optional, dev-only SEO sanity check — NOT part of the build or deploy * pipeline, never blocks production. Run manually: * * npm run seo:check * * Only ever warns; exits 0 regardless of findings (a content gap here isn't * a broken deploy). */ import { getPayload } from "payload"; import config from "../payload.config"; let warnings = 0; function warn(message: string) { warnings++; console.warn(` ⚠ ${message}`); } async function checkCollection( payload: Awaited>, collection: "offers" | "events" | "posts", label: string, ) { console.log(`${label}:`); const { docs } = await payload.find({ collection, limit: 500, depth: 0 }); const slugCounts = new Map(); for (const doc of docs as { slug?: string | null; title?: string }[]) { if (doc.slug) slugCounts.set(doc.slug, (slugCounts.get(doc.slug) ?? 0) + 1); } for (const [slug, count] of slugCounts) { if (count > 1) warn(`Slug „${slug}“ kommt ${count}× vor.`); } for (const doc of docs as { slug?: string | null; title?: string; seo?: { description?: string | null } | null }[]) { if (!doc.title?.trim()) warn(`Dokument ohne Titel (slug: ${doc.slug ?? "—"}).`); if (!doc.slug?.trim()) warn(`Dokument ohne Slug: „${doc.title ?? "—"}“.`); } if (docs.length === 0) console.log(" (keine Einträge)"); } async function checkMedia(payload: Awaited>) { console.log("Medien (Alt-Texte):"); const { docs } = await payload.find({ collection: "media", limit: 1000, depth: 0 }); const missingAlt = (docs as { alt?: string; filename?: string }[]).filter((doc) => !doc.alt?.trim()); if (missingAlt.length === 0) { console.log(" Alle Bilder haben einen Alt-Text."); } else { for (const doc of missingAlt) warn(`Bild ohne Alt-Text: ${doc.filename ?? "unbekannt"}`); } } async function run() { const payload = await getPayload({ config }); await checkCollection(payload, "offers", "Angebote"); await checkCollection(payload, "events", "Termine"); await checkCollection(payload, "posts", "Aktuelles"); await checkMedia(payload); console.log(`\n${warnings === 0 ? "Keine Auffälligkeiten gefunden." : `${warnings} Hinweis(e) gefunden — siehe oben.`}`); process.exit(0); } run().catch((err) => { console.error(err); process.exit(0); });