fix(memory): auto-check Qdrant health on mount and stop false-red badge

The Qdrant engine card on /dashboard/memory?tab=engine showed a red
"Error" badge after every page refresh even when Qdrant was healthy:
the badge derives its state from a health check, but the mount effect
only fetched settings + embedding models — health started as null and
the render treated `health?.ok` (undefined) as a failure. Clicking
"Test connection" (which runs the same server-side /readyz check)
immediately turned it green, proving the connection was fine.

Two changes:
- Auto-run the health check on mount once settings load and Qdrant is
  enabled, so a refreshed page reflects the real state (verified live:
  /api/settings/qdrant/health returns ok:true in ~2ms on a healthy
  compose deployment).
- While health has not been checked yet (null), render a neutral gray
  "Testing..." state instead of red — red is now reserved for an
  actual failed health check.

Regression test added (fails on the old code): with enabled settings
and a healthy mock, the card must hit /api/settings/qdrant/health on
mount and show statusActive, never statusError.
This commit is contained in:
Rouzbeh
2026-08-15 17:11:27 +00:00
parent ee221d870c
commit 02bc4538d7
2 changed files with 125 additions and 59 deletions

View File

@@ -123,6 +123,16 @@ export default function QdrantConfigCard() {
}
}, []);
// Auto-check on mount once settings load: without this the status badge
// renders red after a page refresh because `health` starts as null and the
// old code treated "not checked yet" the same as "failed". The Test
// connection button still drives the same check manually.
useEffect(() => {
if (!loading && qdrant.enabled && health === null) {
void checkHealth();
}
}, [loading, qdrant.enabled, health, checkHealth]);
const runSearch = useCallback(async () => {
const q = searchQuery.trim();
if (!q) return;
@@ -185,18 +195,32 @@ export default function QdrantConfigCard() {
</div>
<span
className={`inline-flex items-center gap-1.5 text-xs font-medium ${
qdrant.enabled ? (health?.ok ? "text-emerald-500" : "text-red-500") : "text-text-muted"
!qdrant.enabled
? "text-text-muted"
: health === null
? "text-text-muted"
: health.ok
? "text-emerald-500"
: "text-red-500"
}`}
>
<span
className={`inline-block w-2.5 h-2.5 rounded-full ${
qdrant.enabled ? (health?.ok ? "bg-emerald-500" : "bg-red-500") : "bg-border"
!qdrant.enabled
? "bg-border"
: health === null
? "bg-border"
: health.ok
? "bg-emerald-500"
: "bg-red-500"
}`}
/>
{qdrant.enabled
? health?.ok
? t("qdrant.statusActive")
: t("qdrant.statusError")
? health === null
? t("qdrant.testing")
: health.ok
? t("qdrant.statusActive")
: t("qdrant.statusError")
: t("qdrant.statusDisabled")}
</span>
</div>