feat: Haben-clone + client portal privacy fix

Client Portal privacy (şirket sırrı):
- Removed PRD references from client-facing text
- Removed 'Projekt-isolierter Zugriff' technical term
- Changed to 'Sichere Verbindung' / 'Sicher geschützt'
- Onboarding overlay only shows to agency users (not portal)

Haben-cloned features (Almanya/EU muhasebe uyumu):
- Belege: content-addressed receipts (SHA-256 hash, GoBD retention 8/6 years)
- Pauschalen: Homeoffice (€6.92/day), Kilometer (€0.30/km), Verpflegung (€14/€24/€28)
  - EStG § 4 Abs. 5, § 9 Abs. 1 compliant rates (2026)
- Anlagen & AfA: Anlagenverzeichnis with linear depreciation
  - GWG (≤€800 Sofortabschreibung, § 6 Abs. 2 EStG)
  - Sammelposten (€251-€1000, § 6 Abs. 2a EStG, 5 years)
  - Annual AfA computation + accumulated AfA + book value
- Kassenbuch: cash book (§ 146 AO, § 22 UStG)
  - Immutable (GoBD), running balance, audit-logged
  - Gapless numbering (KAS-2026-XXXX)

Seed data: 5 Belege, 7 Pauschalen, 5 Anlagen, 5 Kassenbuch entries
TypeScript: 0 errors | ESLint: clean
This commit is contained in:
Z User committed 2026-10-27 17:40:47 +00:00
1 parent 3cb7532417
commit 1573931c0f
13 files changed
+2234 -5

No files matched your search

+5 -5
View File
@@ -131,14 +131,14 @@ function PortalLogin({ onBack, onSelect }: { onBack: () => void; onSelect: (id:
<ArrowLeft className="size-4" />Zur Agentur-Ansicht
</Button>
<div className="ml-auto flex items-center gap-2 text-xs text-muted-foreground">
<ShieldCheck className="size-3.5" />Client-Portal · projektbezogener Zugriff
<ShieldCheck className="size-3.5" />Sichere Verbindung
</div>
</header>
<main className="mx-auto w-full max-w-3xl flex-1 p-4 md:p-8">
<div className="mb-6 space-y-1.5">
<h1 className="text-2xl font-semibold tracking-tight">Client-Portal</h1>
<p className="text-sm text-muted-foreground">
Wähle dein Unternehmen. Du siehst ausschließlich deine eigenen Projekte, Rechnungen, Tickets und Freigaben — projektbezogen isoliert (PRD §5.6).
Wähle dein Unternehmen. Du siehst ausschließlich deine eigenen Projekte, Rechnungen, Tickets und Freigaben.
</p>
</div>
<div className="mb-4">
@@ -222,7 +222,7 @@ function PortalApp({ companyId, tab, setTab, onExit }: {
<div className="ml-auto flex items-center gap-2">
<PortalNotificationsBell companyId={data.company.id} />
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
<ShieldCheck className="size-3.5" />Projekt-isolierter Zugriff
<ShieldCheck className="size-3.5" />Sicher geschützt
</div>
</div>
</header>
@@ -281,7 +281,7 @@ function PortalOverview({ data, setTab }: { data: PortalData; setTab: (t: 'overv
<div className="flex-1">
<h2 className="text-lg font-semibold">Willkommen, {data.company.name}</h2>
<p className="text-xs text-muted-foreground">
Du siehst ausschließlich deine eigenen Daten — projektbezogen isoliert (PRD §5.6).
Du siehst ausschließlich deine eigenen Daten — sicher und geschützt.
{data.kpis.pendingApprovals > 0 && <span className="font-medium text-foreground"> {data.kpis.pendingApprovals} Freigabe(n) warten auf dich.</span>}
</p>
</div>
@@ -421,7 +421,7 @@ function PortalApprovals({ data, refetch }: { data: PortalData; refetch: () => v
<CheckCircle2 className="size-5 text-muted-foreground" />
<div>
<h1 className="text-lg font-semibold">Freigaben</h1>
<p className="text-xs text-muted-foreground">Meilenstein-Freigaben mit Zeitstempel- und IP-Evidenz (PRD §6.3).</p>
<p className="text-xs text-muted-foreground">Meilenstein-Freigaben mit Zeitstempel- und IP-Evidenz.</p>
</div>
</div>