Hauptmenue: Gutschriften/Lieferscheine-Gesamtuebersicht (portal-scoped)

Neuer Menuepunkt 'Gutschriften' -> Seite /credit-notes mit Tabelle
aller Belege (Beleg-Nr, Art, Kunde, Vertrag, Betrag, Datum, PDF),
Suche + Pagination.

Neuer Endpoint GET /credit-notes (NICHT staff-only wie die uebrigen
Credit-Note-Endpoints): Staff sieht alle Belege aller Kunden, Portal-
Kunden nur eigene + vertretene (Vollmacht via hasAuthorization).
customerIds kommt aus dem JWT, nicht aus Query/Body -> nicht
manipulierbar. Fuer Portal wird receiptPath aus der Response entfernt
(Belege bleiben staff-only). Route requirePermission contracts:read.

Verifiziert: Staff -> alle Belege; Portal-scoped -> nur eigene, korrekt
zugeordnet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 10:23:53 +02:00
co-authored by Claude Opus 4.8
parent bbe1aed230
commit 48e65be91c
9 changed files with 281 additions and 2 deletions
@@ -16,6 +16,7 @@ import {
Shield,
FileCheck,
UserCircle,
Receipt,
Gauge,
} from 'lucide-react';
@@ -39,6 +40,7 @@ export default function Sidebar() {
{ to: '/contracts', icon: FileText, label: 'Verträge', show: hasPermission('contracts:read'), end: true },
{ to: '/contracts/cockpit', icon: AlertCircle, label: 'Vertrags-Cockpit', show: hasPermission('contracts:read') && !isCustomer },
{ to: '/tasks', icon: isCustomer ? MessageSquare : ClipboardList, label: isCustomer ? 'Support-Anfragen' : 'Aufgaben', show: hasPermission('contracts:read') },
{ to: '/credit-notes', icon: Receipt, label: 'Gutschriften', show: hasPermission('contracts:read'), end: true },
{ to: '/my-meters', icon: Gauge, label: 'Zählerstände', show: isCustomerPortal },
{ to: '/privacy', icon: Shield, label: 'Datenschutz', show: isCustomerPortal },
{ to: '/authorizations', icon: FileCheck, label: 'Vollmachten', show: isCustomerPortal && hasAuthorizations },