import Link from "next/link"; import { requireSession } from "@/server/auth"; import { dbForTenant } from "@/server/db"; import { requirePermission } from "@/server/rbac"; import { PageHead, Pill } from "@/components/mockup-ui"; import { Button } from "@/components/ui/button"; import { buildExportRows } from "@/server/export-context"; import { buildGapItems } from "@/server/gap-context"; import { kennzahlen, PRUEFZIEL_LABEL } from "@/lib/export/vda-isa"; import { interpretationBand, buildNextSteps } from "@/lib/readiness"; import { PRIORITY_LABEL, PRIORITY_TONE } from "@/lib/gap-consolidation"; /** * Management-Zusammenfassung (Story B7-2, C9 §4): Reifegrad-Überblick, Stärken, * Hoch-Punkte, empfohlene Schritte und priorisierter Maßnahmenplan (Quick-Wins * hervorgehoben). Druckbar (Browser → „Als PDF speichern"). Datenquellen: A7/A8. */ export default async function ManagementSummaryPage() { const session = await requireSession(); requirePermission(session, "onboarding:use"); const db = dbForTenant(session.user.tenantId); const [rows, gap] = await Promise.all([ buildExportRows(db, session.user.tenantId), buildGapItems(db, session.user.tenantId), ]); const k = kennzahlen(rows); const band = k.gesamtAvg === null ? null : interpretationBand(k.gesamtAvg); const staerken = rows.filter((r) => r.bestaetigt && (r.reifegrad ?? 0) >= 2).length; const quickWins = gap.items.filter((g) => g.quickWin); const nextSteps = buildNextSteps({ openHighCount: gap.summary.hoch, unvalidatedCount: rows.filter((r) => !r.bestaetigt).length, prototypeGap: rows.some((r) => r.pruefziel === "prototypenschutz"), evidenceUploadPending: gap.summary.withoutTask > 0, }); return (
{/* eslint-disable-next-line @next/next/no-html-link-for-pages -- CSV-Download-Route-Handler, kein Client-Navigations-Ziel */} } />
{/* Reifegrad-Überblick */}

Reifegrad-Überblick

{band ? {band.band} · Ø {k.gesamtAvg!.toFixed(1)} / Ziel 3 : Reifegrad ausstehend}
{band &&

{band.text}

}
Bestätigte Controls: {k.bestaetigt}/{k.total} ({Math.round(k.bestaetigtAnteil * 100)} %)
Stärken (Ø ≥ 2, bestätigt): {staerken}
Offene Punkte: {gap.summary.total} ({gap.summary.hoch} hoch)
{k.jePruefziel.map((p) => ( {PRUEFZIEL_LABEL[p.pruefziel]}: Ø {p.avg?.toFixed(1) ?? "—"} ({p.bestaetigt}/{p.controls}) ))}
{/* Empfohlene nächste Schritte */}

Empfohlene Schritte vor dem Assessment

{nextSteps.length === 0 ? (

Keine offenen Punkte — bereit für die Stichprobenvalidierung.

) : (
    {nextSteps.map((s, i) =>
  • {s}
  • )}
)}
{/* Maßnahmenplan (C9 §4) */}

Maßnahmenplan {quickWins.length > 0 && · {quickWins.length} Quick-Wins}

{gap.items.length === 0 ? (

Keine offenen Maßnahmen.

) : (
    {gap.items.slice(0, 30).map((g) => (
  • {PRIORITY_LABEL[g.priority]} {g.quickWin && Quick-Win} {g.title} → {g.action}{g.controls.length ? ` (${g.controls.join(", ")})` : ""} {g.taskId && · Aufgabe vorhanden}
  • ))}
)} {gap.items.length > 30 &&

… und {gap.items.length - 30} weitere. Vollständig im Gap-Schritt (8) und im CSV-Export.

}

Nachweisregister und vollständige Katalogsicht siehe VDA-ISA-Katalog-Export (CSV). Zum PDF: über den Browser drucken und als PDF speichern.

); }