fix(import+screening): GET-Alias, DELETE-Endpoint, ehrlicher Scan-Status
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 32s
CI / test-python-dsms-gateway (push) Has been cancelled
CI / test-python-document-crawler (push) Has been cancelled
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 32s
CI / test-python-dsms-gateway (push) Has been cancelled
CI / test-python-document-crawler (push) Has been cancelled
Import-Backend:
- GET /v1/import (Root-Alias) → list_documents; behebt URL-Mismatch im Proxy
- DELETE /v1/import/{document_id} → löscht Dokument + Gap-Analyse (mit Tenant-Isolierung)
- 6 neue Tests (65 total, alle grün)
Screening-Frontend:
- Simulierten Fortschrittsbalken (Math.random) entfernt — war inhaltlich falsch
- Ersetzt durch indeterminate Spinner + rotierende ehrliche Status-Texte
(z.B. "OSV.dev Datenbank wird abgefragt...") im 2-Sek.-Takt
- Kein scanProgress-State mehr benötigt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,38 +8,18 @@ import { useSDK, ScreeningResult, SecurityIssue, SBOMComponent, BacklogItem } fr
|
||||
// COMPONENTS
|
||||
// =============================================================================
|
||||
|
||||
function ScanProgress({ progress, status }: { progress: number; status: string }) {
|
||||
function ScanProgress({ status }: { status: string }) {
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-gray-200 p-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="relative w-16 h-16">
|
||||
<svg className="w-16 h-16 transform -rotate-90">
|
||||
<circle cx="32" cy="32" r="28" stroke="#e5e7eb" strokeWidth="4" fill="none" />
|
||||
<circle
|
||||
cx="32"
|
||||
cy="32"
|
||||
r="28"
|
||||
stroke="#9333ea"
|
||||
strokeWidth="4"
|
||||
fill="none"
|
||||
strokeDasharray={`${progress * 1.76} 176`}
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
<span className="absolute inset-0 flex items-center justify-center text-sm font-bold text-gray-900">
|
||||
{progress}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="w-10 h-10 border-4 border-gray-200 border-t-purple-600 rounded-full animate-spin flex-shrink-0" />
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-900">Scanning...</h3>
|
||||
<h3 className="font-semibold text-gray-900">Scan läuft...</h3>
|
||||
<p className="text-sm text-gray-500">{status}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 h-2 bg-gray-100 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-purple-600 rounded-full transition-all duration-500"
|
||||
style={{ width: `${progress}%` }}
|
||||
/>
|
||||
<div className="mt-4 h-1.5 bg-gray-100 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-purple-600 rounded-full animate-pulse w-full" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -166,7 +146,6 @@ export default function ScreeningPage() {
|
||||
const { state, dispatch } = useSDK()
|
||||
const router = useRouter()
|
||||
const [isScanning, setIsScanning] = useState(false)
|
||||
const [scanProgress, setScanProgress] = useState(0)
|
||||
const [scanStatus, setScanStatus] = useState('')
|
||||
const [scanError, setScanError] = useState<string | null>(null)
|
||||
const [scanHistory, setScanHistory] = useState<any[]>([])
|
||||
@@ -214,27 +193,22 @@ export default function ScreeningPage() {
|
||||
|
||||
const startScan = async (file: File) => {
|
||||
setIsScanning(true)
|
||||
setScanProgress(0)
|
||||
setScanStatus('Initialisierung...')
|
||||
setScanStatus('Abhängigkeiten werden analysiert...')
|
||||
setScanError(null)
|
||||
|
||||
// Show progress steps while API processes
|
||||
const progressInterval = setInterval(() => {
|
||||
setScanProgress(prev => {
|
||||
if (prev >= 90) return prev
|
||||
const step = Math.random() * 15 + 5
|
||||
const next = Math.min(prev + step, 90)
|
||||
const statuses = [
|
||||
'Abhaengigkeiten werden analysiert...',
|
||||
'SBOM wird generiert...',
|
||||
'Schwachstellenscan laeuft...',
|
||||
'OSV.dev Datenbank wird abgefragt...',
|
||||
'Lizenzpruefung...',
|
||||
]
|
||||
setScanStatus(statuses[Math.min(Math.floor(next / 20), statuses.length - 1)])
|
||||
return next
|
||||
})
|
||||
}, 600)
|
||||
// Rotate through honest status messages while backend processes
|
||||
const statusMessages = [
|
||||
'Abhängigkeiten werden analysiert...',
|
||||
'SBOM wird generiert...',
|
||||
'Schwachstellenscan läuft...',
|
||||
'OSV.dev Datenbank wird abgefragt...',
|
||||
'Lizenzprüfung...',
|
||||
]
|
||||
let statusIdx = 0
|
||||
const statusInterval = setInterval(() => {
|
||||
statusIdx = (statusIdx + 1) % statusMessages.length
|
||||
setScanStatus(statusMessages[statusIdx])
|
||||
}, 2000)
|
||||
|
||||
try {
|
||||
const formData = new FormData()
|
||||
@@ -246,7 +220,7 @@ export default function ScreeningPage() {
|
||||
body: formData,
|
||||
})
|
||||
|
||||
clearInterval(progressInterval)
|
||||
clearInterval(statusInterval)
|
||||
|
||||
if (!response.ok) {
|
||||
const err = await response.json().catch(() => ({ error: 'Unknown error' }))
|
||||
@@ -255,7 +229,6 @@ export default function ScreeningPage() {
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
setScanProgress(100)
|
||||
setScanStatus('Abgeschlossen!')
|
||||
|
||||
// Map backend response to ScreeningResult
|
||||
@@ -308,10 +281,9 @@ export default function ScreeningPage() {
|
||||
dispatch({ type: 'ADD_SECURITY_ISSUE', payload: issue })
|
||||
})
|
||||
} catch (error: any) {
|
||||
clearInterval(progressInterval)
|
||||
clearInterval(statusInterval)
|
||||
console.error('Screening scan failed:', error)
|
||||
setScanError(error.message || 'Scan fehlgeschlagen')
|
||||
setScanProgress(0)
|
||||
setScanStatus('')
|
||||
} finally {
|
||||
setIsScanning(false)
|
||||
@@ -369,7 +341,7 @@ export default function ScreeningPage() {
|
||||
)}
|
||||
|
||||
{/* Scan Progress */}
|
||||
{isScanning && <ScanProgress progress={scanProgress} status={scanStatus} />}
|
||||
{isScanning && <ScanProgress status={scanStatus} />}
|
||||
|
||||
{/* Results */}
|
||||
{state.screening && state.screening.status === 'COMPLETED' && (
|
||||
|
||||
Reference in New Issue
Block a user