refactor(admin): split whistleblower page.tsx + restore scope helpers
Whistleblower (1220 -> 349 LOC) split into 6 colocated components:
TabNavigation, StatCard, FilterBar, ReportCard, WhistleblowerCreateModal,
CaseDetailPanel. All under the 300 LOC soft target.
Drive-by fix: the earlier fc6a330 split of compliance-scope-types.ts
dropped several helper exports that downstream consumers still import
(lib/sdk/index.ts, compliance-scope-engine.ts, obligations page,
compliance-scope page, constraint-enforcer, drafting-engine validate).
Restored them in the appropriate domain modules:
- core-levels.ts: maxDepthLevel, getDepthLevelNumeric, depthLevelFromNumeric
- state.ts: createEmptyScopeState
- decisions.ts: createEmptyScopeDecision + ApplicableRegulation,
RegulationObligation, RegulationAssessmentResult, SupervisoryAuthorityInfo
Verification: next build clean (142 pages generated), /sdk/whistleblower
still builds at ~11.5 kB.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,3 +27,42 @@ export interface ComplianceScores {
|
||||
/** Zusammengesetzter Score (0-100): Gewichtete Kombination aller Scores */
|
||||
composite_score: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt das höhere von zwei Depth Levels zurück.
|
||||
*/
|
||||
export function maxDepthLevel(
|
||||
a: ComplianceDepthLevel,
|
||||
b: ComplianceDepthLevel
|
||||
): ComplianceDepthLevel {
|
||||
const levels: ComplianceDepthLevel[] = ['L1', 'L2', 'L3', 'L4'];
|
||||
const indexA = levels.indexOf(a);
|
||||
const indexB = levels.indexOf(b);
|
||||
return levels[Math.max(indexA, indexB)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert Depth Level zu numerischem Wert (1-4).
|
||||
*/
|
||||
export function getDepthLevelNumeric(level: ComplianceDepthLevel): number {
|
||||
const map: Record<ComplianceDepthLevel, number> = {
|
||||
L1: 1,
|
||||
L2: 2,
|
||||
L3: 3,
|
||||
L4: 4,
|
||||
};
|
||||
return map[level];
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert numerischen Wert (1-4) zu Depth Level.
|
||||
*/
|
||||
export function depthLevelFromNumeric(n: number): ComplianceDepthLevel {
|
||||
const map: Record<number, ComplianceDepthLevel> = {
|
||||
1: 'L1',
|
||||
2: 'L2',
|
||||
3: 'L3',
|
||||
4: 'L4',
|
||||
};
|
||||
return map[Math.max(1, Math.min(4, Math.round(n)))] || 'L1';
|
||||
}
|
||||
|
||||
@@ -109,3 +109,79 @@ export interface ScopeReasoning {
|
||||
/** Auswirkung */
|
||||
impact: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine leere ScopeDecision mit Default-Werten.
|
||||
*/
|
||||
export function createEmptyScopeDecision(): ScopeDecision {
|
||||
return {
|
||||
id: `decision_${Date.now()}`,
|
||||
determinedLevel: 'L1',
|
||||
scores: {
|
||||
risk_score: 0,
|
||||
complexity_score: 0,
|
||||
assurance_need: 0,
|
||||
composite_score: 0,
|
||||
},
|
||||
triggeredHardTriggers: [],
|
||||
requiredDocuments: [],
|
||||
riskFlags: [],
|
||||
gaps: [],
|
||||
nextActions: [],
|
||||
reasoning: [],
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Regulation Assessment Types (from Go AI SDK /assess-from-scope)
|
||||
// ============================================================================
|
||||
|
||||
/** Eine anwendbare Regulierung (aus Go SDK ApplicableRegulation). */
|
||||
export interface ApplicableRegulation {
|
||||
id: string
|
||||
name: string
|
||||
classification: string
|
||||
reason: string
|
||||
obligation_count: number
|
||||
control_count: number
|
||||
}
|
||||
|
||||
/** Einzelne Pflicht aus dem Go SDK. */
|
||||
export interface RegulationObligation {
|
||||
id: string
|
||||
regulation_id: string
|
||||
title: string
|
||||
description: string
|
||||
category: string
|
||||
responsible: string
|
||||
priority: string
|
||||
legal_basis?: Array<{ article: string; name: string }>
|
||||
how_to_implement?: string
|
||||
breakpilot_feature?: string
|
||||
}
|
||||
|
||||
/** Ergebnis der Regulierungs-Bewertung vom Go AI SDK. */
|
||||
export interface RegulationAssessmentResult {
|
||||
applicable_regulations: ApplicableRegulation[]
|
||||
obligations: RegulationObligation[]
|
||||
executive_summary: {
|
||||
total_regulations: number
|
||||
total_obligations: number
|
||||
critical_obligations: number
|
||||
compliance_score: number
|
||||
key_risks: string[]
|
||||
recommended_actions: string[]
|
||||
}
|
||||
}
|
||||
|
||||
/** Aufsichtsbehoerden-Ergebnis. */
|
||||
export interface SupervisoryAuthorityInfo {
|
||||
domain: string
|
||||
authority: {
|
||||
name: string
|
||||
abbreviation: string
|
||||
url: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,3 +20,15 @@ export interface ComplianceScopeState {
|
||||
/** Sind alle Pflichtfragen beantwortet? */
|
||||
isComplete: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen leeren ComplianceScopeState mit Default-Werten.
|
||||
*/
|
||||
export function createEmptyScopeState(): ComplianceScopeState {
|
||||
return {
|
||||
answers: [],
|
||||
decision: null,
|
||||
lastEvaluatedAt: null,
|
||||
isComplete: false,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user