["vannaF
return formatMarketLevel(level, "decimal");
}
-function formatAccountMode(accountMode: CollectorHealth["ibkr_account_mode"]): string {
- if (accountMode === "unknown") {
- return "Unknown";
- }
-
- return formatStatusLabel(accountMode);
-}
-
-function IvCell({ row }: { row: AnalyticsSnapshot["rows"][number] | null | undefined }) {
+function IvCell({
+ row,
+ comparisonSourceLabel
+}: {
+ row: AnalyticsSnapshot["rows"][number] | null | undefined;
+ comparisonSourceLabel: string;
+}) {
return (
|
{formatPercent(row?.custom_iv)}
{formatNumber(gamma, 5)}
- {status.label}
+ {statusLabel}
);
}
return (
- {ibkrValue !== "—" ? IBKR {ibkrValue} : null}
+ {ibkrValue !== "—" ? {sourceLabel} {ibkrValue} : null}
{diffValue !== "—" ? {diffValue} : null}
);
diff --git a/apps/web/lib/dashboardMetrics.ts b/apps/web/lib/dashboardMetrics.ts
index 7ef8abe..8c7cd12 100644
--- a/apps/web/lib/dashboardMetrics.ts
+++ b/apps/web/lib/dashboardMetrics.ts
@@ -241,6 +241,27 @@ export function getTransportStatusDisplay(status: LiveTransportStatus): Operatio
return { label: "Connecting", tone: "muted" };
}
+export function getCollectorSourceLabel(collectorHealth?: CollectorHealth | null): string {
+ const collectorId = collectorHealth?.collector_id.toLowerCase() ?? "";
+ const message = collectorHealth?.message.toLowerCase() ?? "";
+
+ if (collectorId.includes("moomoo") || message.includes("moomoo")) {
+ return "Moomoo";
+ }
+
+ return "IBKR";
+}
+
+export function getCollectorSourceDetail(collectorHealth: CollectorHealth): string {
+ const sourceLabel = getCollectorSourceLabel(collectorHealth);
+
+ if (sourceLabel === "Moomoo" && collectorHealth.ibkr_account_mode === "unknown") {
+ return "Moomoo Source";
+ }
+
+ return `${sourceLabel} ${formatCollectorAccountMode(collectorHealth.ibkr_account_mode)}`;
+}
+
export function getRowOperationalStatusDisplay(row: AnalyticsRow | null | undefined): OperationalStatusDisplay | null {
return getRowOperationalStatusDisplays(row)[0] ?? null;
}
@@ -363,7 +384,7 @@ export function deriveDataQuality(
collector: collectorHealth
? {
label: `Collector ${formatStatusLabel(collectorHealth.status)}`,
- detail: `IBKR ${formatCollectorAccountMode(collectorHealth.ibkr_account_mode)}`,
+ detail: getCollectorSourceDetail(collectorHealth),
tone: collectorHealth.status === "connected" ? "ok" : collectorStatusTone(collectorHealth.status)
}
: null,
diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts
index 268d608..830fb59 100644
--- a/apps/web/next-env.d.ts
+++ b/apps/web/next-env.d.ts
@@ -1,5 +1,6 @@
///
///
+///
-// This file is generated by Next.js. It is committed here so initial typechecks
-// work before the dev server has been run.
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/apps/web/tests/DashboardView.test.tsx b/apps/web/tests/DashboardView.test.tsx
index ae161ac..ed98b68 100644
--- a/apps/web/tests/DashboardView.test.tsx
+++ b/apps/web/tests/DashboardView.test.tsx
@@ -346,6 +346,28 @@ describe("DashboardView", () => {
expect(markup).toContain("IBKR market data delayed");
});
+ it("labels Moomoo compatibility collector data as Moomoo instead of IBKR", async () => {
+ const { DashboardView } = await import("../components/DashboardView");
+ const collectorHealth = {
+ schema_version: "1.0.0",
+ source: "ibkr",
+ collector_id: "local-moomoo",
+ status: "connected",
+ ibkr_account_mode: "unknown",
+ message: "Moomoo compatibility snapshot emitted",
+ event_time: "2026-04-30T15:00:00Z",
+ received_time: "2026-04-30T15:00:01Z"
+ } satisfies CollectorHealth;
+ const markup = renderToStaticMarkup();
+
+ expect(markup).toContain("Moomoo Source");
+ expect(markup).toContain("Moomoo compatibility snapshot emitted");
+ expect(markup).toContain("Moomoo 17.95%");
+ expect(markup).toContain("Moomoo 0.01986");
+ expect(markup).not.toContain("IBKR Unknown");
+ expect(markup).not.toContain("IBKR 17.95%");
+ });
+
it("renders transport status, operational notices, and row issue chips", async () => {
const { DashboardView } = await import("../components/DashboardView");
const degradedSnapshot = {
diff --git a/apps/web/tests/dashboardMetrics.test.ts b/apps/web/tests/dashboardMetrics.test.ts
index f49707d..3fcfdc7 100644
--- a/apps/web/tests/dashboardMetrics.test.ts
+++ b/apps/web/tests/dashboardMetrics.test.ts
@@ -385,6 +385,23 @@ describe("dashboard metrics", () => {
expect(getTransportStatusDisplay("reconnecting")).toEqual({ label: "Reconnecting", tone: "muted" });
});
+ it("derives Moomoo collector detail from the compatibility collector id", () => {
+ expect(deriveDataQuality(seedSnapshot, {
+ schema_version: "1.0.0",
+ source: "ibkr",
+ collector_id: "local-moomoo",
+ status: "connected",
+ ibkr_account_mode: "unknown",
+ message: "Moomoo compatibility snapshot emitted",
+ event_time: "2026-04-30T15:00:00Z",
+ received_time: "2026-04-30T15:00:01Z"
+ }, null, "realtime").collector).toMatchObject({
+ label: "Collector Connected",
+ detail: "Moomoo Source",
+ tone: "ok"
+ });
+ });
+
it("derives an explicit disconnected transport notice", () => {
expect(deriveOperationalNotices({ ...seedSnapshot, coverage_status: "full" }, null, "disconnected")).toEqual([
{
|