From 225456ec14ae0931ecf119b95e4d6bf479921245 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Mon, 4 May 2026 11:36:20 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20Source=20Policy=20=E2=80=94=20strip?= =?UTF-8?q?=20PII/Audit/Blocked,=20move=20to=20Zusatzmodule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed: PII-Regeln tab (→ Core Service, other repo) - Removed: Audit tab (→ redundant with Document Workflow + RBAC) - Removed: Blockierte Inhalte tab (→ belongs to PII) - Kept: Quellen-Whitelist + Berechtigungen (Operations Matrix) - Renamed: "Source Policy" → "Quellen-Verwaltung" - Moved: From Paket 1 (Pflicht) to Zusatzmodule (optional) - sdk-steps.ts: isOptional=true, requirements no longer depends on it - Sidebar: Added under Zusatzmodule section - Page reduced from 365 → 130 lines Co-Authored-By: Claude Opus 4.6 (1M context) --- .../app/sdk/source-policy/page.tsx | 394 ++++-------------- .../sdk/Sidebar/SidebarModuleList.tsx | 1 + admin-compliance/lib/sdk/types/sdk-steps.ts | 8 +- 3 files changed, 85 insertions(+), 318 deletions(-) diff --git a/admin-compliance/app/sdk/source-policy/page.tsx b/admin-compliance/app/sdk/source-policy/page.tsx index ab9e5dc..d2f14c3 100644 --- a/admin-compliance/app/sdk/source-policy/page.tsx +++ b/admin-compliance/app/sdk/source-policy/page.tsx @@ -1,364 +1,130 @@ 'use client' /** - * Source Policy Management Page (SDK Version) + * Source Policy — Quellen-Whitelist fuer RAG Pipeline * - * Whitelist-based data source management for compliance RAG corpus. - * Controls which legal sources may be used, PII rules, and audit trail. + * Kontrolliert welche externen Quellen (Rechtstexte, Standards, Leitfaeden) + * in die lokale Knowledge Base ingested werden duerfen. + * Enterprise-Feature fuer Kanzleien/Unternehmen mit eigenem RAG-System. */ import { useState, useEffect } from 'react' -import { useSDK } from '@/lib/sdk' -import StepHeader from '@/components/sdk/StepHeader/StepHeader' import { SourcesTab } from '@/components/sdk/source-policy/SourcesTab' import { OperationsMatrixTab } from '@/components/sdk/source-policy/OperationsMatrixTab' -import { PIIRulesTab } from '@/components/sdk/source-policy/PIIRulesTab' -import { AuditTab } from '@/components/sdk/source-policy/AuditTab' -// API base URL — now uses Next.js proxy routes const API_BASE = '/api/sdk/v1/source-policy' interface PolicyStats { active_policies: number allowed_sources: number - pii_rules: number - blocked_today: number - blocked_total: number } -type TabId = 'dashboard' | 'sources' | 'operations' | 'pii' | 'audit' | 'blocked' - -interface BlockedContent { - id: string - content_type: string - pattern: string - reason: string - blocked_at: string - source?: string -} +type TabId = 'overview' | 'sources' | 'operations' export default function SourcePolicyPage() { - const { state } = useSDK() - const [activeTab, setActiveTab] = useState('dashboard') + const [activeTab, setActiveTab] = useState('overview') const [stats, setStats] = useState(null) const [loading, setLoading] = useState(true) - const [error, setError] = useState(null) - const [blockedContent, setBlockedContent] = useState([]) - const [blockedLoading, setBlockedLoading] = useState(false) useEffect(() => { - fetchStats() + fetch(`${API_BASE}/policy-stats`) + .then(r => r.ok ? r.json() : null) + .then(data => setStats(data)) + .catch(() => {}) + .finally(() => setLoading(false)) }, []) - useEffect(() => { - if (activeTab === 'blocked') { - fetchBlockedContent() - } - }, [activeTab]) - - const fetchBlockedContent = async () => { - setBlockedLoading(true) - try { - const res = await fetch(`${API_BASE}/blocked-content`) - if (res.ok) { - const data = await res.json() - setBlockedContent(Array.isArray(data) ? data : (data.items || [])) - } - } catch { - // silently ignore — empty state shown - } finally { - setBlockedLoading(false) - } - } - - const handleRemoveBlocked = async (id: string) => { - try { - await fetch(`${API_BASE}/blocked-content/${id}`, { method: 'DELETE' }) - setBlockedContent(prev => prev.filter(item => item.id !== id)) - } catch { - // ignore - } - } - - const fetchStats = async () => { - try { - setLoading(true) - const res = await fetch(`${API_BASE}/policy-stats`) - - if (!res.ok) { - throw new Error('Fehler beim Laden der Statistiken') - } - - const data = await res.json() - setStats(data) - } catch (err) { - setError(err instanceof Error ? err.message : 'Unbekannter Fehler') - setStats({ - active_policies: 0, - allowed_sources: 0, - pii_rules: 0, - blocked_today: 0, - blocked_total: 0, - }) - } finally { - setLoading(false) - } - } - - const tabs: { id: TabId; name: string; icon: JSX.Element }[] = [ - { - id: 'dashboard', - name: 'Dashboard', - icon: ( - - - - ), - }, - { - id: 'sources', - name: 'Quellen', - icon: ( - - - - ), - }, - { - id: 'operations', - name: 'Operations', - icon: ( - - - - ), - }, - { - id: 'pii', - name: 'PII-Regeln', - icon: ( - - - - ), - }, - { - id: 'audit', - name: 'Audit', - icon: ( - - - - ), - }, - { - id: 'blocked', - name: 'Blockierte Inhalte', - icon: ( - - - - ), - }, + const tabs: { id: TabId; label: string }[] = [ + { id: 'overview', label: 'Uebersicht' }, + { id: 'sources', label: 'Quellen-Whitelist' }, + { id: 'operations', label: 'Berechtigungen' }, ] return (
- + {/* Header */} +
+

Quellen-Verwaltung

+

+ Definieren Sie welche externen Quellen in Ihre Knowledge Base aufgenommen werden duerfen. +

+
- {/* Error Display */} - {error && ( -
- {error} - -
- )} - - {/* Stats Cards */} + {/* Stats */} {stats && ( -
-
-
{stats.active_policies}
-
Aktive Policies
+
+
+
{stats.allowed_sources}
+
Zugelassene Quellen
-
-
{stats.allowed_sources}
-
Zugelassene Quellen
-
-
-
{stats.blocked_today}
-
Blockiert (heute)
-
-
-
{stats.pii_rules}
-
PII-Regeln
+
+
{stats.active_policies}
+
Aktive Policies
)} {/* Tabs */} -
- {tabs.map((tab) => ( - ))}
- {/* Tab Content */} - <> - {activeTab === 'dashboard' && stats && ( -
-
-

Quellen-Uebersicht

-
-
- Zugelassene Quellen - {stats.allowed_sources} -
-
- Aktive Policies - {stats.active_policies} -
-
-
0 ? Math.min((stats.active_policies / stats.allowed_sources) * 100, 100) : 0}%` }} - /> -
-
+ {/* Tab: Uebersicht */} + {activeTab === 'overview' && ( +
+

Was ist die Quellen-Verwaltung?

+

+ Die Quellen-Verwaltung kontrolliert welche externen Dokumente und Rechtsquellen + in Ihre lokale RAG-Pipeline (Knowledge Base) aufgenommen werden duerfen. +

+
+
+

Quellen-Whitelist

+

+ Definieren Sie vertrauenswuerdige Quellen: EUR-Lex, BSI Grundschutz, + Behoerden-Leitfaeden, eigene Dokumente. +

- -
-

Datenschutz-Regeln

-
-
- PII-Regeln aktiv - {stats.pii_rules} -
-
- Blockiert (heute) - 0 ? 'text-red-600' : 'text-green-600'}`}> - {stats.blocked_today} - -
-
- Blockiert (gesamt) - {stats.blocked_total} -
-
+
+

Berechtigungen

+

+ Pro Quelle festlegen: Darf sie ingested, durchsucht, exportiert + oder mit Dritten geteilt werden? +

- -
-

Compliance-Status

-
-
-
Quellen konfiguriert
-
- {stats.allowed_sources > 0 ? 'Ja' : 'Nein'} -
-
-
-
PII-Schutz aktiv
-
- {stats.pii_rules > 0 ? 'Ja' : 'Nein'} -
-
-
-
Policies definiert
-
- {stats.active_policies > 0 ? 'Ja' : 'Nein'} -
-
-
+
+

Lizenzen

+

+ Jede Quelle wird mit Lizenzinformationen versehen + (DL-DE-BY, CC-BY, CC0, eigene Dokumente). +

- )} - {activeTab === 'dashboard' && !stats && loading && ( -
Lade Dashboard...
- )} - {activeTab === 'sources' && } - {activeTab === 'operations' && } - {activeTab === 'pii' && } - {activeTab === 'audit' && } - {activeTab === 'blocked' && ( -
-
-

Blockierte Inhalte

- + {stats && stats.allowed_sources === 0 && ( +
+

+ Noch keine Quellen konfiguriert. Wechseln Sie zum Tab "Quellen-Whitelist" + um Ihre ersten Quellen hinzuzufuegen. +

+ )} +
+ )} - {blockedLoading ? ( -
Lade blockierte Inhalte...
- ) : blockedContent.length === 0 ? ( -
-
- - - -
-

Keine blockierten Inhalte vorhanden.

-
- ) : ( - - - - - - - - - - - - {blockedContent.map(item => ( - - - - - - - - - ))} - -
TypMuster / PatternGrundBlockiert amQuelle -
- - {item.content_type} - - - {item.pattern} - {item.reason} - {new Date(item.blocked_at).toLocaleDateString('de-DE')} - {item.source || '—'} - -
- )} -
- )} - + {/* Tab: Quellen */} + {activeTab === 'sources' && { + fetch(`${API_BASE}/policy-stats`).then(r => r.ok ? r.json() : null).then(setStats).catch(() => {}) + }} />} + + {/* Tab: Berechtigungen */} + {activeTab === 'operations' && }
) } diff --git a/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx b/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx index 91e9b7c..f824670 100644 --- a/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx +++ b/admin-compliance/components/sdk/Sidebar/SidebarModuleList.tsx @@ -107,6 +107,7 @@ export function SidebarModuleList({ collapsed, projectId, pendingCRCount }: Side } label="Workshop" isActive={pathname === '/sdk/workshop'} collapsed={collapsed} projectId={projectId} /> } label="Portfolio" isActive={pathname === '/sdk/portfolio'} collapsed={collapsed} projectId={projectId} /> } label="Roadmap" isActive={pathname === '/sdk/roadmap'} collapsed={collapsed} projectId={projectId} /> + } label="Quellen-Verwaltung" isActive={pathname?.startsWith('/sdk/source-policy') ?? false} collapsed={collapsed} projectId={projectId} /> } label="ISMS (ISO 27001)" isActive={pathname === '/sdk/isms'} collapsed={collapsed} projectId={projectId} /> } label="LLM Audit" isActive={pathname === '/sdk/audit-llm'} collapsed={collapsed} projectId={projectId} /> } label="RBAC Admin" isActive={pathname === '/sdk/rbac'} collapsed={collapsed} projectId={projectId} /> diff --git a/admin-compliance/lib/sdk/types/sdk-steps.ts b/admin-compliance/lib/sdk/types/sdk-steps.ts index bbb75f5..f2f3e4a 100644 --- a/admin-compliance/lib/sdk/types/sdk-steps.ts +++ b/admin-compliance/lib/sdk/types/sdk-steps.ts @@ -89,13 +89,13 @@ export const SDK_STEPS: SDKStep[] = [ phase: 1, package: 'vorbereitung', order: 7, - name: 'Source Policy', + name: 'Quellen-Verwaltung', nameShort: 'Quellen', - description: 'Datenquellen-Governance & Whitelist', + description: 'RAG Quellen-Whitelist (Enterprise)', url: '/sdk/source-policy', checkpointId: 'CP-SPOL', prerequisiteSteps: ['modules'], - isOptional: false }, + isOptional: true }, // PAKET 2: ANALYSE (Assessment) { @@ -109,7 +109,7 @@ export const SDK_STEPS: SDKStep[] = [ description: 'Pr\u00fcfaspekte aus Regulierungen ableiten', url: '/sdk/requirements', checkpointId: 'CP-REQ', - prerequisiteSteps: ['source-policy'], + prerequisiteSteps: ['modules'], isOptional: false }, { id: 'controls',