/** * Zentrale Definition aller Berechtigungen. * * Aus plan.md Abschnitt 20: Eine zentrale Berechtigungsschicht, damit * Berechtigungslogik nicht ueber den ganzen Code verteilt wird. * Alle API-Routen und Server-Komponenten MUSSSEN diese Funktionen * verwenden statt eigene Ad-hoc-Pruefungen zu schreiben. */ import type { Role } from '@prisma/client'; /** Minimal notwendige Informationen ueber den angemeldeten Benutzer. */ export interface AuthenticatedUser { id: string; email: string; /** Frei waehlbarer Anzeigename; null, wenn nicht gesetzt. */ username: string | null; role: Role; } /** Minimal notwendige Informationen ueber einen Kalender. */ export interface CalendarRef { id: string; ownerId: string; isActive: boolean; } /** Minimal notwendige Informationen ueber eine Reservierung. */ export interface ReservationRef { id: string; calendarId: string; userId: string; } /** Minimal notwendige Informationen ueber eine Mitgliedschaft. */ export interface MembershipRef { calendarId: string; userId: string; } /** * Darf der User den Kalender sehen? * Admin: alle Kalender (Verwaltungsrolle). User: nur Kalender, in * denen er Mitglied ist. Deaktivierte Kalender bleiben fuer Member * sichtbar (mit Hinweis), damit sie ihre Reservierungen noch einsehen * koennen. */ export function canViewCalendar( user: AuthenticatedUser, calendar: CalendarRef, isMember: boolean, ): boolean { if (user.role === 'ADMIN') { return true; } return isMember; } /** * Darf der User den Kalender verwalten (bearbeiten, Invites erstellen, * loeschen)? Admins duerfen alle Kalender verwalten (auch die anderer * Benutzer), normale User keinen. */ export function canManageCalendar( user: AuthenticatedUser, calendar: CalendarRef, ): boolean { return user.role === 'ADMIN'; } /** * Darf der User eine Reservierung in diesem Kalender erstellen? * Admins in allen aktiven Kalendern, User nur in ihrem einen Kalender * (Mitgliedschaft). Deaktivierte Kalender erlauben keine neuen * Reservierungen. */ export function canCreateReservation( user: AuthenticatedUser, calendar: CalendarRef, isMember: boolean, ): boolean { if (!calendar.isActive) { return false; } if (user.role === 'ADMIN') { return true; } return isMember; } /** * Darf der User eine Reservierung LOESCHEN? * Ausschliesslich Admins (in allen Kalendern). Normale User koennen * Reservierungen nur anlegen und sehen - nicht loeschen. */ export function canDeleteReservation( user: AuthenticatedUser, _reservation: ReservationRef, calendar: CalendarRef, ): boolean { return user.role === 'ADMIN' && canViewCalendar(user, calendar, false); } /** * Darf der User die Reservierung sehen? * Admin: in allen Kalendern alle. User: nur eigene Reservierungen * im eigenen Kalender. */ export function canViewReservation( user: AuthenticatedUser, reservation: ReservationRef, calendar: CalendarRef, isMember: boolean, ): boolean { if (!canViewCalendar(user, calendar, isMember)) { return false; } if (user.role === 'ADMIN') { return true; } return reservation.userId === user.id; } /** * Darf der User die Reservierung aendern oder loeschen? * Admin: alle Reservierungen in allen Kalendern. * User: ausschliesslich eigene Reservierungen. */ export function canModifyReservation( user: AuthenticatedUser, reservation: ReservationRef, calendar: CalendarRef, isMember: boolean, ): boolean { if (!canViewCalendar(user, calendar, isMember)) { return false; } if (user.role === 'ADMIN') { return true; } return reservation.userId === user.id; }