import { redirect } from "next/navigation"; import type { ReactNode } from "react"; import { HireWizardProvider } from "@/components/hire/HireWizardContext"; import { AppShell } from "@/components/shell/AppShell"; import { currentUserId } from "@/lib/auth/session"; import { withUser } from "@/lib/db"; import { loadShellData } from "@/lib/shell-data"; export default async function AppLayout({ children }: { children: ReactNode }) { const userId = await currentUserId(); if (!userId) redirect("/login"); // Alles in *einer* Transaktion, weil nur dort der Sitzungskontext gilt — // und damit nebenbei auf einem einheitlichen Lesestand. Was dabei in wie // vielen Rundreisen gelesen wird, steht in lib/shell-data.ts. const ergebnis = await withUser(userId, (tx) => loadShellData(tx, userId)); // Hier — und nicht im Proxy — fällt diese Entscheidung: der Proxy hat keine // Datenbankverbindung. Sie wird bei jedem Aufbau frisch gestellt, eine // entzogene Freischaltung wirkt also sofort statt erst mit dem nächsten // Sitzungstoken. // // Beide Umleitungen sind Bedienkomfort, keine Absicherung: wer sie umgeht, // bekommt trotzdem keine Zeile, weil die RLS-Policies dieselbe Frage stellen // (is_hr_user()). Ohne sie stünde die Person nur vor einer leeren Anwendung // und wüsste nicht, warum. if (ergebnis.status === "passwort_wechseln") redirect("/passwort-aendern"); // Ohne den Grund in der Adresse stünde die Person vor einer wortlosen // Anmeldeseite und versuchte es endlos erneut. if (ergebnis.status === "kein_zugang") redirect("/login?error=no_hr_access"); const data = ergebnis.daten; const userLabel = data.profile.full_name || data.profile.email || ""; return ( {children} ); }