'use client' import { Scale, Landmark, GitMerge, FileText } from 'lucide-react' import { SeverityBadge, ObligationTypeBadge, ExtractionMethodBadge, type CanonicalControl, type ObligationInfo, type DocumentReference, type MergedDuplicate, type RegulationSummary, } from './helpers' interface TraceabilityData { control_id: string title: string is_atomic: boolean parent_links: Array<{ parent_control_id: string parent_title: string link_type: string confidence: number source_regulation: string | null source_article: string | null parent_citation: Record | null obligation: { text: string; action: string; object: string; normative_strength: string } | null }> children: Array<{ control_id: string; title: string; category: string; severity: string; decomposition_method: string }> source_count: number obligations?: ObligationInfo[] obligation_count?: number document_references?: DocumentReference[] merged_duplicates?: MergedDuplicate[] merged_duplicates_count?: number regulations_summary?: RegulationSummary[] } interface ControlTraceabilityProps { ctrl: CanonicalControl traceability: TraceabilityData | null loadingTrace: boolean onNavigateToControl?: (controlId: string) => void } export function ControlTraceability({ ctrl, traceability, loadingTrace, onNavigateToControl }: ControlTraceabilityProps) { const ControlLink = ({ controlId }: { controlId: string }) => { if (onNavigateToControl) { return ( ) } return {controlId} } return ( <> {/* Regulatorische Abdeckung (Eigenentwicklung) covered by parent */} {/* Rechtsgrundlagen / Traceability */} {traceability && traceability.parent_links.length > 0 && (

Rechtsgrundlagen ({traceability.source_count} {traceability.source_count === 1 ? 'Quelle' : 'Quellen'})

{traceability.regulations_summary?.map(rs => ( {rs.regulation_code} ))} {loadingTrace && Laden...}
{traceability.parent_links.map((link, i) => (
{link.source_regulation && {link.source_regulation}} {link.source_article && {link.source_article}} {!link.source_regulation && link.parent_citation?.source && ( {link.parent_citation.source}{link.parent_citation.article && ` — ${link.parent_citation.article}`} )} {link.link_type === 'decomposition' ? 'Ableitung' : link.link_type === 'dedup_merge' ? 'Dedup' : link.link_type}

via {link.parent_title && — {link.parent_title}}

{link.obligation && (

{link.obligation.normative_strength === 'must' ? 'MUSS' : link.obligation.normative_strength === 'should' ? 'SOLL' : 'KANN'} {link.obligation.text.slice(0, 200)}{link.obligation.text.length > 200 ? '...' : ''}

)}
))}
)} {/* Fallback: simple parent display */} {ctrl.parent_control_uuid && (!traceability || traceability.parent_links.length === 0) && !loadingTrace && (

Atomares Control

Abgeleitet aus Eltern-Control{' '} {ctrl.parent_control_id || ctrl.parent_control_uuid} {ctrl.parent_control_title && — {ctrl.parent_control_title}}

)} {/* Document References */} {traceability?.is_atomic && traceability.document_references && traceability.document_references.length > 0 && (

Original-Dokumente ({traceability.document_references.length})

{traceability.document_references.map((dr, i) => (
{dr.regulation_code} {dr.article && {dr.article}} {dr.paragraph && {dr.paragraph}} {dr.confidence !== null && {(dr.confidence * 100).toFixed(0)}%}
))}
)} {/* Obligations */} {traceability && !traceability.is_atomic && traceability.obligations && traceability.obligations.length > 0 && (

Abgeleitete Pflichten ({traceability.obligation_count ?? traceability.obligations.length})

{traceability.obligations.map((ob) => (
{ob.candidate_id} {ob.normative_strength === 'must' ? 'MUSS' : ob.normative_strength === 'should' ? 'SOLL' : 'KANN'} {ob.action && {ob.action}} {ob.object && → {ob.object}}

{ob.obligation_text.slice(0, 300)}{ob.obligation_text.length > 300 ? '...' : ''}

))}
)} {/* Merged Duplicates */} {traceability?.merged_duplicates && traceability.merged_duplicates.length > 0 && (

Zusammengefuehrte Duplikate ({traceability.merged_duplicates_count ?? traceability.merged_duplicates.length})

{traceability.merged_duplicates.map((dup) => (
{dup.title} {dup.source_regulation && {dup.source_regulation}}
))}
)} {/* Child controls */} {traceability && traceability.children.length > 0 && (

Abgeleitete Controls ({traceability.children.length})

{traceability.children.map((child) => (
{child.title}
))}
)} ) }