Single Source of Truth: Frontend/Backend-Ungereimtheiten ausgeraeumt (Review 15.07.)
Backend (Wahrheit reparieren): - gateway_reachable() prueft jetzt den ECHTEN mc2-gateway (:9010 via V1_UPSTREAM) statt nur die Engine - toter Denkpfad war in Health/Cockpit unsichtbar - /api/system/services vollstaendig: + LLM-Gateway, + Steuerpult, + Waechter (mc2-steward via is-active); scope-Feld (user/system); mc2-gateway/mc2-steward in die Restart-Allowlist - Connect-Health Leitung 1 prueft den Client-Pfad (V1_UPSTREAM statt llama-swap) - agent_status liefert pc_executor_url (UI zeigte hartcodierte IP/Ports) - SSE-Endlosschleife gefixt: /api/auftragsbuch schrieb announce-branches bei JEDEM Aufruf neu -> mtime-Bump -> invalidate -> Refetch im 3-s-Takt je Client; jetzt nur noch bei echter Aenderung Frontend (ein Datenweg): - SystemDrawer komplett auf React-Query-Hooks (vorher eigenes 3-s-setInterval auf dieselben Endpunkte inkl. teurem Updates-Check); Dienste-Liste = Backend-Antwort (SERVICES-UI-Kopie geloescht); useDialog statt Eigenbau; fmtBytes statt Duplikat - useLucyHealth: Dienst-Matching per systemd-unit statt Namensfragment; Gateway- Reparatur zielt auf mc2-gateway; neuer Waechter-Check; Backend-tot => ehrliches rotes Verdikt statt eingefrorener letzter Stand (auch Sidebar) - Toter Code raus: views/models/Cockpit.tsx (908 Z.) + RoleAssignModal + Placeholder; LaneEditor (Routing-Policy) + WarmSetManager damit ZURUECK im UI als Tab "Routing & Warm-Set" im Modell-Manager - Cockpit: blockierte Ideen-Karten erscheinen in "Braucht dich" + Kachel-Hint; Verbinden-Kachel zeigt 3 Leitungen live statt hartem "Zed" - Maschinenraum: ehrliches "frei" (reale Belegung) + eigenes KV-Cache-Segment - AgentView: Ports/PC-Adresse aus der API; Guide lehrt Lanes chat/coding - queries.ts: useModels nutzt SSE-relax; Chronik-Limit im Query-Key; useJobs/useZeitmaschine mit enabled-Schalter Verifiziert: tsc+vite gruen, Backend-Smoke beide Gateway-Modi, UI live gegen die Box (Cockpit/Werkbank/Routing-Tab/Drawer rendern mit Echtdaten). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+22
-14
@@ -3,7 +3,6 @@ import { Command as CommandIcon, ChevronLeft, ChevronRight, Loader2, Menu, X } f
|
||||
import { NAV, type ViewId } from "@/nav"
|
||||
import { CommandPalette } from "@/components/CommandPalette"
|
||||
import { ExpertToggle } from "@/components/ExpertToggle"
|
||||
import { Placeholder } from "@/views/Placeholder"
|
||||
import { SystemDrawer } from "@/components/SystemDrawer"
|
||||
import { useHealth, useSystemStatus } from "@/lib/queries"
|
||||
import type { Health, SystemStatus } from "@/lib/api"
|
||||
@@ -54,7 +53,9 @@ export default function App() {
|
||||
const [drawerOpen, setDrawerOpen] = useState(false)
|
||||
const [drawerTab, setDrawerTab] = useState<"maintenance" | "logs">("maintenance")
|
||||
|
||||
const { data: health } = useHealth()
|
||||
// isError mitnehmen: React Query behält bei Fehlern die letzten Daten — ohne den
|
||||
// Fehler-Blick zeigte die Sidebar bei totem Backend ewig den letzten grünen Stand.
|
||||
const { data: health, isError: backendDown } = useHealth()
|
||||
const { data: sysStatus } = useSystemStatus()
|
||||
|
||||
useEffect(() => {
|
||||
@@ -129,6 +130,7 @@ export default function App() {
|
||||
}}
|
||||
view={view}
|
||||
health={health}
|
||||
backendDown={backendDown}
|
||||
sysStatus={sysStatus}
|
||||
/>
|
||||
</aside>
|
||||
@@ -151,6 +153,7 @@ export default function App() {
|
||||
onClose={() => setMobileNavOpen(false)}
|
||||
view={view}
|
||||
health={health}
|
||||
backendDown={backendDown}
|
||||
sysStatus={sysStatus}
|
||||
/>
|
||||
</aside>
|
||||
@@ -208,9 +211,6 @@ export default function App() {
|
||||
{view === "agent" && <AgentView />}
|
||||
{view === "konsole" && <KonsoleView />}
|
||||
{view === "guide" && <GuideView />}
|
||||
{!["dashboard", "auftraege", "eigenleben", "models", "connect", "memory", "wissen", "chronik", "agent", "konsole", "guide"].includes(view) && (
|
||||
<Placeholder title={active.label} hint={active.hint} />
|
||||
)}
|
||||
</Suspense>
|
||||
</main>
|
||||
</div>
|
||||
@@ -221,13 +221,14 @@ export default function App() {
|
||||
// Sidebar-Inhalt (Logo, Navigation, Status-Fuß) — geteilt zwischen Desktop-Leiste
|
||||
// und Mobile-Off-Canvas, damit beide immer identisch bleiben.
|
||||
function SidebarContent({
|
||||
collapsed, onToggleCollapse, onClose, view, health, sysStatus,
|
||||
collapsed, onToggleCollapse, onClose, view, health, backendDown, sysStatus,
|
||||
}: {
|
||||
collapsed: boolean
|
||||
onToggleCollapse?: () => void
|
||||
onClose?: () => void
|
||||
view: ViewId
|
||||
health: Health | undefined
|
||||
backendDown: boolean
|
||||
sysStatus: SystemStatus | undefined
|
||||
}) {
|
||||
return (
|
||||
@@ -308,18 +309,25 @@ function SidebarContent({
|
||||
<div className="flex justify-center">
|
||||
<span className={cn(
|
||||
"h-2.5 w-2.5 rounded-full ring-2 ring-black/40",
|
||||
health
|
||||
? (!health.engine_reachable ? "bg-amber-500"
|
||||
backendDown || !health
|
||||
? "bg-red-500"
|
||||
: (!health.engine_reachable ? "bg-amber-500"
|
||||
: (health.brain && !health.brain.ready ? "bg-amber-500 animate-pulse" : "bg-emerald-500 animate-pulse"))
|
||||
: "bg-red-500"
|
||||
)} title={health
|
||||
? (!health.engine_reachable ? "Engine offline"
|
||||
: (health.brain && !health.brain.ready ? `Hirn offline (${health.brain.model ?? "fast"})` : "Engine + Hirn online"))
|
||||
: "Backend offline"} />
|
||||
)} title={backendDown
|
||||
? "Zentrale antwortet nicht — Anzeigen evtl. veraltet"
|
||||
: health
|
||||
? (!health.engine_reachable ? "Engine offline"
|
||||
: (health.brain && !health.brain.ready ? `Hirn offline (${health.brain.model ?? "fast"})` : "Engine + Hirn online"))
|
||||
: "Backend offline"} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2 text-left">
|
||||
{health ? (
|
||||
{backendDown ? (
|
||||
<span className="flex items-center gap-2 text-red-400">
|
||||
<span className="h-2 w-2 rounded-full bg-red-500 animate-pulse" />
|
||||
<span className="truncate">Zentrale antwortet nicht</span>
|
||||
</span>
|
||||
) : health ? (
|
||||
<>
|
||||
<span className="flex items-center gap-2">
|
||||
<span className={cn("h-2 w-2 rounded-full animate-pulse", health.engine_reachable ? "bg-emerald-500" : "bg-amber-500")} />
|
||||
|
||||
Reference in New Issue
Block a user