Website (14 monoliths split): - compliance/page.tsx (1,519 → 9), docs/audit (1,262 → 20) - quality (1,231 → 16), alerts (1,203 → 10), docs (1,202 → 11) - i18n.ts (1,173 → 8 language files) - unity-bridge (1,094 → 12), backlog (1,087 → 6) - training (1,066 → 8), rag (1,063 → 8) - Deleted index_original.ts (4,899 LOC dead backup) Studio-v2 (5 monoliths split): - meet/page.tsx (1,481 → 9), messages (1,166 → 9) - AlertsB2BContext.tsx (1,165 → 5 modules) - alerts-b2b/page.tsx (1,019 → 6), korrektur/archiv (1,001 → 6) All existing imports preserved. Zero new TypeScript errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
267 lines
11 KiB
TypeScript
267 lines
11 KiB
TypeScript
import { SchedulerStatusCard } from './SchedulerStatusCard'
|
|
import { SpinnerIcon } from './SpinnerIcon'
|
|
|
|
export function SchedulerTab({
|
|
isRunningGolden,
|
|
isRunningRag,
|
|
isRunningSynthetic,
|
|
runGoldenTests,
|
|
runRagTests,
|
|
runSyntheticTests,
|
|
}: {
|
|
isRunningGolden: boolean
|
|
isRunningRag: boolean
|
|
isRunningSynthetic: boolean
|
|
runGoldenTests: () => void
|
|
runRagTests: () => void
|
|
runSyntheticTests: () => void
|
|
}) {
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Status Overview */}
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<SchedulerStatusCard
|
|
title="launchd Job"
|
|
status="active"
|
|
description="Taeglich um 07:00 Uhr automatisch"
|
|
icon={
|
|
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
}
|
|
/>
|
|
<SchedulerStatusCard
|
|
title="Git Hook"
|
|
status="active"
|
|
description="Quick Tests bei voice-service Aenderungen"
|
|
icon={
|
|
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
</svg>
|
|
}
|
|
/>
|
|
<SchedulerStatusCard
|
|
title="Benachrichtigungen"
|
|
status="active"
|
|
description="Desktop-Alerts bei Fehlern aktiviert"
|
|
icon={
|
|
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
|
|
</svg>
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
{/* Quick Actions */}
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
|
<h3 className="text-lg font-semibold text-slate-900 mb-4">Quick Actions</h3>
|
|
<div className="flex flex-wrap gap-3">
|
|
<QuickActionButton
|
|
label="Golden Suite starten"
|
|
isRunning={isRunningGolden}
|
|
onClick={runGoldenTests}
|
|
colorClass="bg-blue-600 hover:bg-blue-700"
|
|
/>
|
|
<QuickActionButton
|
|
label="RAG Tests starten"
|
|
isRunning={isRunningRag}
|
|
onClick={runRagTests}
|
|
colorClass="bg-purple-600 hover:bg-purple-700"
|
|
/>
|
|
<QuickActionButton
|
|
label="Synthetic Tests"
|
|
isRunning={isRunningSynthetic}
|
|
onClick={runSyntheticTests}
|
|
colorClass="bg-emerald-600 hover:bg-emerald-700"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* GitHub Actions vs Local - Comparison */}
|
|
<ComparisonTable />
|
|
|
|
{/* Configuration Details */}
|
|
<ConfigurationSection />
|
|
|
|
{/* Detailed Explanation */}
|
|
<ExplanationSection />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function QuickActionButton({
|
|
label,
|
|
isRunning,
|
|
onClick,
|
|
colorClass,
|
|
}: {
|
|
label: string
|
|
isRunning: boolean
|
|
onClick: () => void
|
|
colorClass: string
|
|
}) {
|
|
return (
|
|
<button
|
|
onClick={onClick}
|
|
disabled={isRunning}
|
|
className={`px-4 py-2 ${colorClass} text-white rounded-lg disabled:bg-slate-300 flex items-center gap-2`}
|
|
>
|
|
{isRunning ? (
|
|
<SpinnerIcon />
|
|
) : (
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
)}
|
|
{label}
|
|
</button>
|
|
)
|
|
}
|
|
|
|
function ComparisonTable() {
|
|
const rows = [
|
|
{ feature: 'Taegliche Tests (07:00)', gh: 'schedule: cron', local: 'macOS launchd', localColor: 'emerald' },
|
|
{ feature: 'Push-basierte Tests', gh: 'on: push', local: 'Git post-commit Hook', localColor: 'emerald' },
|
|
{ feature: 'PR-basierte Tests', gh: 'on: pull_request', ghColor: 'emerald', local: 'Nicht moeglich', localColor: 'amber' },
|
|
{ feature: 'Regression-Check', gh: 'API-Call', local: 'Identischer API-Call', localColor: 'emerald' },
|
|
{ feature: 'Benachrichtigungen', gh: 'GitHub Issues', local: 'Desktop/Slack/Email', localColor: 'emerald' },
|
|
{ feature: 'DSGVO-Konformitaet', gh: 'Daten bei GitHub (US)', ghColor: 'amber', local: '100% lokal', localColor: 'emerald' },
|
|
{ feature: 'Offline-Faehig', gh: 'Nein', ghColor: 'red', local: 'Ja', localColor: 'emerald' },
|
|
]
|
|
|
|
return (
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
|
<h3 className="text-lg font-semibold text-slate-900 mb-4">GitHub Actions Alternative</h3>
|
|
<p className="text-slate-600 mb-4">
|
|
Der lokale BQAS Scheduler ersetzt GitHub Actions und bietet DSGVO-konforme, vollstaendig lokale Test-Ausfuehrung.
|
|
</p>
|
|
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-sm">
|
|
<thead>
|
|
<tr className="border-b border-slate-200 bg-slate-50">
|
|
<th className="text-left py-3 px-4 font-medium text-slate-700">Feature</th>
|
|
<th className="text-center py-3 px-4 font-medium text-slate-700">GitHub Actions</th>
|
|
<th className="text-center py-3 px-4 font-medium text-slate-700">Lokaler Scheduler</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{rows.map((row) => (
|
|
<tr key={row.feature} className="border-b border-slate-100">
|
|
<td className="py-3 px-4 text-slate-600">{row.feature}</td>
|
|
<td className="py-3 px-4 text-center">
|
|
{row.ghColor ? (
|
|
<span className={`px-2 py-1 bg-${row.ghColor}-100 text-${row.ghColor}-700 rounded text-xs font-medium`}>
|
|
{row.gh}
|
|
</span>
|
|
) : (
|
|
<span className="text-slate-600">{row.gh}</span>
|
|
)}
|
|
</td>
|
|
<td className="py-3 px-4 text-center">
|
|
<span className={`px-2 py-1 bg-${row.localColor}-100 text-${row.localColor}-700 rounded text-xs font-medium`}>
|
|
{row.local}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function ConfigurationSection() {
|
|
return (
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
|
<h3 className="text-lg font-semibold text-slate-900 mb-4">Konfiguration</h3>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
{/* launchd Configuration */}
|
|
<div>
|
|
<h4 className="font-medium text-slate-800 mb-3">launchd Job</h4>
|
|
<div className="bg-slate-900 rounded-lg p-4 font-mono text-sm text-slate-100 overflow-x-auto">
|
|
<pre>{`# ~/Library/LaunchAgents/com.breakpilot.bqas.plist
|
|
Label: com.breakpilot.bqas
|
|
Schedule: 07:00 taeglich
|
|
Script: /voice-service/scripts/run_bqas.sh
|
|
Logs: /var/log/bqas/`}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Environment Variables */}
|
|
<div>
|
|
<h4 className="font-medium text-slate-800 mb-3">Umgebungsvariablen</h4>
|
|
<div className="space-y-2 text-sm">
|
|
{[
|
|
{ key: 'BQAS_SERVICE_URL', value: 'http://localhost:8091', color: 'text-slate-900' },
|
|
{ key: 'BQAS_REGRESSION_THRESHOLD', value: '0.1', color: 'text-slate-900' },
|
|
{ key: 'BQAS_NOTIFY_DESKTOP', value: 'true', color: 'text-emerald-600 font-medium' },
|
|
{ key: 'BQAS_NOTIFY_SLACK', value: 'false', color: 'text-slate-400' },
|
|
].map((env) => (
|
|
<div key={env.key} className="flex justify-between p-2 bg-slate-50 rounded">
|
|
<span className="font-mono text-slate-600">{env.key}</span>
|
|
<span className={env.color}>{env.value}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function ExplanationSection() {
|
|
return (
|
|
<div className="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl border border-blue-200 p-6">
|
|
<h3 className="text-lg font-semibold text-slate-900 mb-4 flex items-center gap-2">
|
|
<svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
Detaillierte Erklaerung
|
|
</h3>
|
|
|
|
<div className="prose prose-sm max-w-none text-slate-700">
|
|
<h4 className="text-base font-semibold mt-4 mb-2">Warum ein lokaler Scheduler?</h4>
|
|
<p className="mb-4">
|
|
Der lokale BQAS Scheduler wurde entwickelt, um die gleiche Funktionalitaet wie GitHub Actions zu bieten,
|
|
aber mit dem entscheidenden Vorteil, dass <strong>alle Daten zu 100% auf dem lokalen Mac Mini verbleiben</strong>.
|
|
Dies ist besonders wichtig fuer DSGVO-Konformitaet, da keine Schuelerdaten oder Testergebnisse an externe Server uebertragen werden.
|
|
</p>
|
|
|
|
<h4 className="text-base font-semibold mt-4 mb-2">Komponenten</h4>
|
|
<ul className="list-disc list-inside space-y-2 mb-4">
|
|
<li>
|
|
<strong>run_bqas.sh</strong> - Hauptscript das pytest ausfuehrt, Regression-Checks macht und Benachrichtigungen versendet
|
|
</li>
|
|
<li>
|
|
<strong>launchd Job</strong> - macOS-nativer Scheduler der das Script taeglich um 07:00 Uhr startet
|
|
</li>
|
|
<li>
|
|
<strong>Git Hook</strong> - post-commit Hook der bei Aenderungen im voice-service automatisch Quick-Tests startet
|
|
</li>
|
|
<li>
|
|
<strong>Notifier</strong> - Python-Modul das Desktop-, Slack- und E-Mail-Benachrichtigungen versendet
|
|
</li>
|
|
</ul>
|
|
|
|
<h4 className="text-base font-semibold mt-4 mb-2">Installation</h4>
|
|
<div className="bg-slate-900 rounded-lg p-3 font-mono text-sm text-slate-100 mb-4">
|
|
<code>./voice-service/scripts/install_bqas_scheduler.sh install</code>
|
|
</div>
|
|
|
|
<h4 className="text-base font-semibold mt-4 mb-2">Vorteile gegenueber GitHub Actions</h4>
|
|
<ul className="list-disc list-inside space-y-1">
|
|
<li>100% DSGVO-konform - alle Daten bleiben lokal</li>
|
|
<li>Keine Internet-Abhaengigkeit - funktioniert auch offline</li>
|
|
<li>Keine GitHub-Kosten fuer private Repositories</li>
|
|
<li>Schnellere Ausfuehrung ohne Cloud-Overhead</li>
|
|
<li>Volle Kontrolle ueber Scheduling und Benachrichtigungen</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|