diff --git a/backend/src/controllers/booking.controller.ts b/backend/src/controllers/booking.controller.ts index d77ddf5..3591316 100644 --- a/backend/src/controllers/booking.controller.ts +++ b/backend/src/controllers/booking.controller.ts @@ -226,8 +226,8 @@ class BookingController { const isOwner = booking.gebucht_von === req.user!.id; const groups: string[] = req.user?.groups ?? []; const isAdmin = groups.includes('dashboard_admin'); - const canCancelOwn = isAdmin || permissionService.hasPermission(groups, 'kalender:manage_bookings'); - const canCancelAny = isAdmin || permissionService.hasPermission(groups, 'kalender:manage_bookings'); + const canCancelOwn = isAdmin || permissionService.hasPermission(groups, 'fahrzeugbuchungen:manage'); + const canCancelAny = isAdmin || permissionService.hasPermission(groups, 'fahrzeugbuchungen:manage'); if (!(isOwner && canCancelOwn) && !canCancelAny) { res.status(403).json({ success: false, message: 'Keine Berechtigung' }); diff --git a/backend/src/routes/booking.routes.ts b/backend/src/routes/booking.routes.ts index 1cd7d97..fd0b5c7 100644 --- a/backend/src/routes/booking.routes.ts +++ b/backend/src/routes/booking.routes.ts @@ -18,15 +18,15 @@ router.get('/calendar-token', authenticate, bookingController.getCalendarToken.b // ── Write operations ────────────────────────────────────────────────────────── -router.post('/', authenticate, requirePermission('kalender:manage_bookings'), bookingController.create.bind(bookingController)); -router.patch('/:id', authenticate, requirePermission('kalender:manage_bookings'), bookingController.update.bind(bookingController)); +router.post('/', authenticate, requirePermission('fahrzeugbuchungen:create'), bookingController.create.bind(bookingController)); +router.patch('/:id', authenticate, requirePermission('fahrzeugbuchungen:manage'), bookingController.update.bind(bookingController)); // Soft-cancel (sets abgesagt=TRUE) — creator or bookings:write router.delete('/:id', authenticate, bookingController.cancel.bind(bookingController)); router.patch('/:id/cancel', authenticate, bookingController.cancel.bind(bookingController)); // Hard-delete (admin only) -router.delete('/:id/force', authenticate, requirePermission('kalender:manage_bookings'), bookingController.hardDelete.bind(bookingController)); +router.delete('/:id/force', authenticate, requirePermission('fahrzeugbuchungen:manage'), bookingController.hardDelete.bind(bookingController)); // ── Single booking read — after specific routes to avoid path conflicts ─────── diff --git a/backend/src/routes/buchungskategorie.routes.ts b/backend/src/routes/buchungskategorie.routes.ts index c917a72..7da2ee3 100644 --- a/backend/src/routes/buchungskategorie.routes.ts +++ b/backend/src/routes/buchungskategorie.routes.ts @@ -9,7 +9,7 @@ const router = Router(); router.get( '/', authenticate, - requirePermission('kalender:view_bookings'), + requirePermission('fahrzeugbuchungen:view'), buchungskategorieController.list.bind(buchungskategorieController) ); @@ -17,7 +17,7 @@ router.get( router.get( '/active', authenticate, - requirePermission('kalender:view_bookings'), + requirePermission('fahrzeugbuchungen:view'), buchungskategorieController.listActive.bind(buchungskategorieController) ); @@ -25,7 +25,7 @@ router.get( router.post( '/', authenticate, - requirePermission('kalender:manage_bookings'), + requirePermission('fahrzeugbuchungen:manage'), buchungskategorieController.create.bind(buchungskategorieController) ); @@ -33,7 +33,7 @@ router.post( router.patch( '/:id', authenticate, - requirePermission('kalender:manage_bookings'), + requirePermission('fahrzeugbuchungen:manage'), buchungskategorieController.update.bind(buchungskategorieController) ); @@ -41,7 +41,7 @@ router.patch( router.delete( '/:id', authenticate, - requirePermission('kalender:manage_bookings'), + requirePermission('fahrzeugbuchungen:manage'), buchungskategorieController.deactivate.bind(buchungskategorieController) ); @@ -49,7 +49,7 @@ router.delete( router.delete( '/:id/permanent', authenticate, - requirePermission('kalender:manage_bookings'), + requirePermission('fahrzeugbuchungen:manage'), buchungskategorieController.remove.bind(buchungskategorieController) ); diff --git a/backend/src/services/permission.service.ts b/backend/src/services/permission.service.ts index 0e87f59..fe810fc 100644 --- a/backend/src/services/permission.service.ts +++ b/backend/src/services/permission.service.ts @@ -14,11 +14,11 @@ const DEFAULT_GROUP_HIERARCHY: Record = { const DEFAULT_PERMISSION_DEPS: Record = { 'kalender:create': ['kalender:view'], - 'kalender:view_bookings': ['kalender:view'], - 'kalender:manage_bookings': ['kalender:view', 'kalender:view_bookings'], 'kalender:widget_events': ['kalender:view'], - 'kalender:widget_bookings': ['kalender:view'], 'kalender:widget_quick_add': ['kalender:view', 'kalender:create'], + 'fahrzeugbuchungen:create': ['fahrzeugbuchungen:view'], + 'fahrzeugbuchungen:manage': ['fahrzeugbuchungen:view', 'fahrzeugbuchungen:create'], + 'fahrzeugbuchungen:widget': ['fahrzeugbuchungen:view'], 'fahrzeuge:create': ['fahrzeuge:view'], 'fahrzeuge:change_status': ['fahrzeuge:view'], 'fahrzeuge:manage_maintenance': ['fahrzeuge:view'], diff --git a/frontend/src/components/shared/Sidebar.tsx b/frontend/src/components/shared/Sidebar.tsx index cdac9b6..be7f516 100644 --- a/frontend/src/components/shared/Sidebar.tsx +++ b/frontend/src/components/shared/Sidebar.tsx @@ -27,6 +27,7 @@ import { ExpandLess, LocalShipping, BugReport, + BookOnline, } from '@mui/icons-material'; import { useNavigate, useLocation } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; @@ -49,11 +50,6 @@ interface NavigationItem { permission?: string; } -const kalenderSubItems: SubItem[] = [ - { text: 'Veranstaltungen', path: '/kalender' }, - { text: 'Fahrzeugbuchungen', path: '/fahrzeugbuchungen' }, -]; - const adminSubItems: SubItem[] = [ { text: 'Services', path: '/admin?tab=0' }, { text: 'System', path: '/admin?tab=1' }, @@ -77,9 +73,14 @@ const baseNavigationItems: NavigationItem[] = [ text: 'Kalender', icon: , path: '/kalender', - subItems: kalenderSubItems, permission: 'kalender:view', }, + { + text: 'Fahrzeugbuchungen', + icon: , + path: '/fahrzeugbuchungen', + permission: 'fahrzeugbuchungen:view', + }, { text: 'Fahrzeuge', icon: , diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index c56bb2a..57a70ab 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -170,7 +170,7 @@ function Dashboard() { )} - {hasPermission('kalender:view_bookings') && widgetVisible('vehicleBookingList') && ( + {hasPermission('fahrzeugbuchungen:view') && widgetVisible('vehicleBookingList') && ( @@ -178,7 +178,7 @@ function Dashboard() { )} - {hasPermission('kalender:manage_bookings') && widgetVisible('vehicleBooking') && ( + {hasPermission('fahrzeugbuchungen:manage') && widgetVisible('vehicleBooking') && ( diff --git a/frontend/src/pages/FahrzeugBuchungen.tsx b/frontend/src/pages/FahrzeugBuchungen.tsx index 6274271..a45c491 100644 --- a/frontend/src/pages/FahrzeugBuchungen.tsx +++ b/frontend/src/pages/FahrzeugBuchungen.tsx @@ -98,8 +98,8 @@ function FahrzeugBuchungen() { const navigate = useNavigate(); const queryClient = useQueryClient(); - const canCreate = hasPermission('kalender:create'); - const canManage = hasPermission('kalender:manage_bookings'); + const canCreate = hasPermission('fahrzeugbuchungen:create'); + const canManage = hasPermission('fahrzeugbuchungen:manage'); const [tabIndex, setTabIndex] = useState(0);