feat(bd-2vw): display raw lore data in debug view

Add DebugView component to show raw lore status data for visual
verification that the data pipeline works end-to-end:
- Frontend -> Tauri IPC -> Rust backend -> lore CLI -> parsed data

New files:
- src/components/DebugView.tsx - Debug component with health indicator
- src/hooks/useLoreData.ts - TanStack Query hook for lore status
- tests/components/DebugView.test.tsx - Component tests
- tests/hooks/useLoreData.test.ts - Hook tests

Modified:
- src/App.tsx - Add QueryClientProvider wrapper
- src/stores/nav-store.ts - Add 'debug' ViewId
- src/components/AppShell.tsx - Add Debug nav tab and view routing
- tests/components/AppShell.test.tsx - Update tests for new nav
This commit is contained in:
teernisse
2026-02-26 11:01:44 -05:00
parent 4654f9063f
commit 251ae44a56
8 changed files with 533 additions and 23 deletions

View File

@@ -0,0 +1,113 @@
/**
* DebugView -- displays raw lore data for debugging.
*
* Shows the raw JSON response from get_lore_status for visual
* verification that the data pipeline is working end-to-end.
* Access via the debug view in the navigation.
*/
import { useLoreData } from "@/hooks/useLoreData";
export function DebugView(): React.ReactElement {
const { data, isLoading, error, refetch } = useLoreData();
if (isLoading) {
return (
<div className="flex min-h-[calc(100vh-3rem)] items-center justify-center">
<div className="text-zinc-500">Loading lore data...</div>
</div>
);
}
if (error) {
return (
<div className="flex min-h-[calc(100vh-3rem)] flex-col items-center justify-center gap-4">
<div className="text-red-500">Error: {error.message}</div>
<button
onClick={() => refetch()}
className="rounded bg-zinc-700 px-3 py-1.5 text-sm text-zinc-200 hover:bg-zinc-600"
>
Retry
</button>
</div>
);
}
return (
<div className="p-4">
<div className="mb-4 flex items-center justify-between">
<h2 className="text-lg font-semibold text-zinc-200">Lore Debug</h2>
<button
onClick={() => refetch()}
className="rounded bg-zinc-700 px-3 py-1.5 text-sm text-zinc-200 hover:bg-zinc-600"
>
Refresh
</button>
</div>
{/* Status overview */}
<div className="mb-6 rounded-lg border border-zinc-800 bg-zinc-900 p-4">
<h3 className="mb-3 text-sm font-medium text-zinc-400">Status</h3>
<div className="space-y-2">
<div className="flex items-center gap-2">
<span className="text-zinc-500">Health:</span>
<div
data-testid="health-indicator"
className={`h-2.5 w-2.5 rounded-full ${
data?.is_healthy ? "bg-green-500" : "bg-red-500"
}`}
/>
<span className="text-zinc-300">
{data?.is_healthy ? "Healthy" : "Unhealthy"}
</span>
</div>
<div className="flex items-center gap-2">
<span className="text-zinc-500">Last Sync:</span>
<span className="font-mono text-zinc-300">
{data?.last_sync ?? "never"}
</span>
</div>
<div className="flex items-center gap-2">
<span className="text-zinc-500">Message:</span>
<span className="text-zinc-300">{data?.message}</span>
</div>
</div>
</div>
{/* Summary counts */}
{data?.summary && (
<div className="mb-6 rounded-lg border border-zinc-800 bg-zinc-900 p-4">
<h3 className="mb-3 text-sm font-medium text-zinc-400">Summary</h3>
<div className="grid grid-cols-3 gap-4">
<div className="text-center">
<div className="text-2xl font-semibold text-zinc-200">
{data.summary.open_issues}
</div>
<div className="text-sm text-zinc-500">Open Issues</div>
</div>
<div className="text-center">
<div className="text-2xl font-semibold text-zinc-200">
{data.summary.authored_mrs}
</div>
<div className="text-sm text-zinc-500">Authored MRs</div>
</div>
<div className="text-center">
<div className="text-2xl font-semibold text-zinc-200">
{data.summary.reviewing_mrs}
</div>
<div className="text-sm text-zinc-500">Reviewing MRs</div>
</div>
</div>
</div>
)}
{/* Raw JSON output */}
<div className="rounded-lg border border-zinc-800 bg-zinc-900 p-4">
<h3 className="mb-3 text-sm font-medium text-zinc-400">Raw Response</h3>
<pre className="overflow-x-auto whitespace-pre-wrap font-mono text-xs text-zinc-300">
{JSON.stringify(data, null, 2)}
</pre>
</div>
</div>
);
}