Files
breakpilot-lehrer/admin-lehrer/app/(admin)/ai/test-quality/page.tsx
Benjamin Admin 9ba420fa91
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-school (push) Successful in 42s
CI / test-go-edu-search (push) Successful in 34s
CI / test-python-klausur (push) Failing after 2m51s
CI / test-python-agent-core (push) Successful in 21s
CI / test-nodejs-website (push) Successful in 29s
Fix: Remove broken getKlausurApiUrl and clean up empty lines
sed replacement left orphaned hostname references in story page
and empty lines in getApiBase functions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 16:02:04 +02:00

214 lines
6.5 KiB
TypeScript

'use client'
/**
* Test Quality Dashboard - BQAS (Breakpilot Quality Assurance System)
*
* Umfassendes Qualitaetssicherungs-Dashboard mit:
* - Golden Test Suite Ergebnisse
* - Synthetic Test Generierung
* - Regression Tracking
* - Test Run Historie
* - RAG Correction Tests
*/
import Link from 'next/link'
import { PagePurpose } from '@/components/common/PagePurpose'
import { AIToolsSidebarResponsive } from '@/components/ai/AIToolsSidebar'
import type { TabType } from './types'
import { useTestQuality } from './useTestQuality'
import {
ToastContainer,
TestRunsTable,
OverviewTab,
GoldenTab,
RagTab,
SyntheticTab,
GuideTab,
} from './_components'
const TABS: { id: TabType; label: string; highlight?: boolean }[] = [
{ id: 'overview', label: 'Uebersicht' },
{ id: 'golden', label: 'Golden Suite' },
{ id: 'rag', label: 'RAG/Korrektur' },
{ id: 'synthetic', label: 'Synthetic' },
{ id: 'history', label: 'Historie' },
{ id: 'guide', label: 'Anleitung', highlight: true },
]
export default function TestQualityPage() {
const {
activeTab,
setActiveTab,
isLoading,
error,
toasts,
removeToast,
goldenMetrics,
syntheticMetrics,
ragMetrics,
testRuns,
trendData,
isRunningGolden,
isRunningSynthetic,
isRunningRag,
fetchData,
runGoldenTests,
runSyntheticTests,
runRagTests,
} = useTestQuality()
const renderTabContent = () => {
switch (activeTab) {
case 'overview':
return (
<OverviewTab
goldenMetrics={goldenMetrics}
syntheticMetrics={syntheticMetrics}
ragMetrics={ragMetrics}
trendData={trendData}
testRuns={testRuns}
isRunningGolden={isRunningGolden}
isRunningSynthetic={isRunningSynthetic}
isRunningRag={isRunningRag}
runGoldenTests={runGoldenTests}
runSyntheticTests={runSyntheticTests}
runRagTests={runRagTests}
/>
)
case 'golden':
return (
<GoldenTab
goldenMetrics={goldenMetrics}
isRunningGolden={isRunningGolden}
runGoldenTests={runGoldenTests}
/>
)
case 'rag':
return (
<RagTab
ragMetrics={ragMetrics}
isRunningRag={isRunningRag}
runRagTests={runRagTests}
/>
)
case 'synthetic':
return (
<SyntheticTab
syntheticMetrics={syntheticMetrics}
isRunningSynthetic={isRunningSynthetic}
runSyntheticTests={runSyntheticTests}
/>
)
case 'history':
return (
<div className="bg-white rounded-xl border border-slate-200 p-6">
<h3 className="text-lg font-semibold text-slate-900 mb-6">Test Run Historie</h3>
<TestRunsTable runs={testRuns} />
</div>
)
case 'guide':
return <GuideTab />
default:
return null
}
}
return (
<div className="space-y-6">
<ToastContainer toasts={toasts} onDismiss={removeToast} />
<PagePurpose
title="Test Quality (BQAS)"
purpose="BQAS Dashboard mit Golden Suite (97 Referenz-Tests), RAG/Korrektur Tests und Synthetic Test Generierung. Ueberwacht die Qualitaet der KI-Ausgaben und identifiziert Regressions."
audience={['Entwickler', 'Data Scientists', 'QA', 'Auditoren']}
architecture={{
services: ['voice-service (Port 8091)', 'embedding-service'],
databases: ['Qdrant', 'PostgreSQL'],
}}
relatedPages={[
{ name: 'GPU Infrastruktur', href: '/ai/gpu', description: 'GPU-Ressourcen verwalten' },
{ name: 'RAG Management', href: '/ai/rag', description: 'Training Data & RAG Pipelines' },
]}
collapsible={true}
defaultCollapsed={true}
/>
<AIToolsSidebarResponsive currentTool="test-quality" />
{error && (
<div className="p-4 bg-red-50 border border-red-200 rounded-lg text-red-700 flex items-center gap-3">
<svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span>{error}</span>
<button onClick={fetchData} className="ml-auto text-red-600 hover:text-red-800 text-sm font-medium">
Erneut versuchen
</button>
</div>
)}
<div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
<div className="border-b border-slate-200">
<nav className="flex gap-6 px-6">
{TABS.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`py-4 text-sm font-medium border-b-2 transition-colors ${
activeTab === tab.id
? 'border-teal-600 text-teal-600'
: tab.highlight
? 'border-transparent text-blue-500 hover:text-blue-600'
: 'border-transparent text-slate-500 hover:text-slate-700'
}`}
>
{tab.label}
</button>
))}
</nav>
</div>
<div className="p-6">
{isLoading ? (
<div className="flex items-center justify-center py-12">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-teal-600"></div>
</div>
) : (
renderTabContent()
)}
</div>
</div>
<div className="flex items-center justify-between text-sm text-slate-500 px-2">
<div>
<span className="font-medium">Voice Service:</span> voice-service:8091
</div>
<div className="flex items-center gap-4">
<Link href="/infrastructure/ci-cd" className="text-teal-600 hover:text-teal-700">
Scheduler (CI/CD)
</Link>
<Link href="/ai/quality" className="text-teal-600 hover:text-teal-700">
Compliance Audit
</Link>
</div>
</div>
<style jsx>{`
@keyframes slide-in {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.animate-slide-in {
animation: slide-in 0.3s ease-out;
}
`}</style>
</div>
)
}