3ef8c9b247
CI / detect-changes (push) Successful in 7s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Failing after 4s
CI / validate-canonical-controls (push) Successful in 11s
CI / loc-budget (push) Successful in 14s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m24s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
User-Vorgabe: pro Slot transparent zeigen WAS wir tun:
1. Was wurde geprueft (MC-Coverage, collapsible)
2. Speedometer mit Severity-Verteilung
3. LLM-Eskalation-Log (wenn benutzt)
4. Findings sortiert HIGH->LOW, je Card:
- Methodik-Badge (MC / Regex / KB / LLM / Cross)
- Gesetzliche Basis (Norm-Block, violett)
- Befund (Zitat-Block, amber)
- Empfehlung -> 'Pflicht-Massnahme' bei HIGH,
'Best-Practice' bei MEDIUM/LOW, 'LLM-Vorschlag'
bei LLM-Quelle
5. Maszahmen-Plan (gerollupte Recommendations mit
related_finding_ids + Aufwand)
Refactor: ein File AgentTestTab.tsx (519 LOC) -> 7 Files:
_agentTypes.ts (Types + Methodik-Konstanten)
AgentSpeedometer.tsx
AgentMcCoverage.tsx
AgentFindingCard.tsx
AgentRecommendationCard.tsx
AgentSlotCard.tsx
AgentTestTab.tsx (Top-Level, schlank)
Plus Methodik-Info-Erklaerung am Tab-Anfang + Disclaimer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* Recommendation-Card: zeigt die gerollupten Maßnahmen.
|
|
* Eine Recommendation bündelt 1..N Findings mit gleicher Maßnahme.
|
|
*/
|
|
|
|
import React from 'react'
|
|
|
|
import type { Recommendation } from './_agentTypes'
|
|
import { SEVERITY_COLOR } from './_agentTypes'
|
|
|
|
export function AgentRecommendationCard({ r }: { r: Recommendation }) {
|
|
const color = SEVERITY_COLOR[r.severity]
|
|
return (
|
|
<div
|
|
className="rounded p-3 space-y-1 text-sm bg-emerald-50"
|
|
style={{ borderLeft: `3px solid ${color}` }}
|
|
>
|
|
<div className="flex items-baseline gap-2 flex-wrap">
|
|
<span
|
|
className="text-[10px] font-bold px-1.5 py-0.5 rounded text-white"
|
|
style={{ background: color }}
|
|
>
|
|
{r.severity}
|
|
</span>
|
|
<span className="font-semibold text-gray-900">{r.title}</span>
|
|
<span className="text-[10px] text-gray-500 ml-auto">
|
|
{r.related_finding_ids.length} Finding(s)
|
|
{' · '}
|
|
{r.estimated_effort_hours.toFixed(1)}h geschätzt
|
|
</span>
|
|
</div>
|
|
{r.body && r.body !== r.title && (
|
|
<div className="text-xs text-gray-700 whitespace-pre-wrap">
|
|
{r.body}
|
|
</div>
|
|
)}
|
|
{r.related_finding_ids.length > 0 && (
|
|
<details className="text-[10px] text-gray-500">
|
|
<summary className="cursor-pointer">Aus diesen Findings abgeleitet</summary>
|
|
<ul className="mt-1 list-disc ml-4 space-y-0.5">
|
|
{r.related_finding_ids.map(id => (
|
|
<li key={id}><code>{id}</code></li>
|
|
))}
|
|
</ul>
|
|
</details>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|