feat(cra): Flow-2 UI — Scanner-Repo wählen → echtes Assessment

- GET /v1/cra/scanner-repos: distinct repo_ids (+counts) vom Scanner-MCP für den Picker.
- useCRA: scannerRepo-State; bei Auswahl POST /assess-from-scanner (echte Findings),
  sonst by-iace/Demo wie bisher.
- ScannerRepoPicker im CRA/Cyber-Tab; leere Auswahl = Demo, Repo gewählt = echte Befunde.

Mapping repo_id↔Projekt aktuell UI-seitig (ephemeral); DB-Persistenz pro Projekt folgt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-16 05:49:15 +02:00
parent 926dc02a09
commit 90def4d857
4 changed files with 83 additions and 3 deletions
@@ -89,6 +89,7 @@ function merge(live: any): CRADemo {
export function useCRA(projectId?: string) {
const [data, setData] = useState<CRADemo | null>(null)
const [live, setLive] = useState(false)
const [scannerRepo, setScannerRepo] = useState('') // pull-flow: chosen scanner repo_id
const [weights, setWeights] = useState<Weights>({})
const [snapshots, setSnapshots] = useState<SnapshotMeta[]>([])
@@ -103,6 +104,20 @@ export function useCRA(projectId?: string) {
useEffect(() => {
let cancelled = false
;(async () => {
// 0. Pull-flow: a scanner repo is chosen → assess its real findings.
if (scannerRepo) {
try {
const r = await fetch('/api/v1/cra/assess-from-scanner', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ repo_id: scannerRepo, weights, safety_functions: SAFETY_FUNCTIONS }),
})
if (r.ok) {
const j = await r.json()
if (!cancelled) { setData(merge(j)); setLive(true) }
return
}
} catch { /* fall through */ }
}
// 1. Is a CRA project LINKED to this IACE project? Then show its real
// assessment (latest snapshot) instead of the demo scenario.
if (projectId) {
@@ -131,7 +146,7 @@ export function useCRA(projectId?: string) {
}
})()
return () => { cancelled = true }
}, [buildPayload, projectId])
}, [buildPayload, projectId, scannerRepo, weights])
const refreshSnapshots = useCallback(() => {
if (!projectId) return
@@ -156,5 +171,5 @@ export function useCRA(projectId?: string) {
return r.ok ? r.json() : null
}, [])
return { data, live, weights, setWeights, snapshots, saveSnapshot, viewSnapshot }
return { data, live, weights, setWeights, snapshots, saveSnapshot, viewSnapshot, scannerRepo, setScannerRepo }
}