From 5cc213e46bd0a3e1dd6f938a25228bbe73a9fa65 Mon Sep 17 00:00:00 2001 From: Paco Cartones <253313177+pacocartones@users.noreply.github.com> Date: Wed, 26 Aug 2026 13:09:43 +0200 Subject: [PATCH] fix(dashboard): preserve combo success percentage scale (#11595) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merged via /merge-batch (lote 2026-08-26, v3.8.51). Boarded no worktree combinado junto com outras ~30 PRs; validação única: typecheck/complexity/cognitive-complexity/changelog-integrity verdes, file-size rebaseado onde necessário (crescimento legítimo), lint com os mesmos 228 achados pré-existentes confirmados via sonda contra o tip puro (não introduzidos por este lote), e ~370 testes focados (unit + vitest) passando. Obrigado pela contribuição. --- .../fixes/11595-combo-success-rate-scale.md | 1 + .../dashboard/provider-stats/page.tsx | 6 ++- src/lib/usage/providerStatsFormatters.ts | 3 ++ tests/unit/provider-stats-formatters.test.ts | 38 +++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 changelog.d/fixes/11595-combo-success-rate-scale.md create mode 100644 src/lib/usage/providerStatsFormatters.ts create mode 100644 tests/unit/provider-stats-formatters.test.ts diff --git a/changelog.d/fixes/11595-combo-success-rate-scale.md b/changelog.d/fixes/11595-combo-success-rate-scale.md new file mode 100644 index 0000000000..b9802ee5a5 --- /dev/null +++ b/changelog.d/fixes/11595-combo-success-rate-scale.md @@ -0,0 +1 @@ +- **fix(dashboard):** Provider Stats now displays combo success rates on their native 0–100 percentage scale instead of multiplying them twice ([#11595](https://github.com/diegosouzapw/OmniRoute/pull/11595)) — thanks @pacocartones diff --git a/src/app/(dashboard)/dashboard/provider-stats/page.tsx b/src/app/(dashboard)/dashboard/provider-stats/page.tsx index bdc1e54cee..96e22cf9b5 100644 --- a/src/app/(dashboard)/dashboard/provider-stats/page.tsx +++ b/src/app/(dashboard)/dashboard/provider-stats/page.tsx @@ -9,8 +9,10 @@ import { useState, useEffect, useCallback, Fragment } from "react"; import { useTranslations } from "next-intl"; -import { Card } from "@/shared/components"; + import { useProviderNodeMap, resolveProviderName } from "@/lib/display/useProviderNodeMap"; +import { formatComboSuccessRate } from "@/lib/usage/providerStatsFormatters"; +import { Card } from "@/shared/components"; interface ProviderStat { provider: string; @@ -493,7 +495,7 @@ export default function ProviderStatsPage() { {typeof m.successRate === "number" - ? `${(m.successRate * 100).toFixed(1)}%` + ? formatComboSuccessRate(m.successRate) : "—"} diff --git a/src/lib/usage/providerStatsFormatters.ts b/src/lib/usage/providerStatsFormatters.ts new file mode 100644 index 0000000000..d61622e852 --- /dev/null +++ b/src/lib/usage/providerStatsFormatters.ts @@ -0,0 +1,3 @@ +export function formatComboSuccessRate(successRatePercent: number): string { + return `${successRatePercent.toFixed(1)}%`; +} diff --git a/tests/unit/provider-stats-formatters.test.ts b/tests/unit/provider-stats-formatters.test.ts new file mode 100644 index 0000000000..7f36e5a1fb --- /dev/null +++ b/tests/unit/provider-stats-formatters.test.ts @@ -0,0 +1,38 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; +import test from "node:test"; + +import { + getComboMetrics, + recordComboRequest, + resetAllComboMetrics, +} from "../../open-sse/services/comboMetrics.ts"; +import { formatComboSuccessRate } from "../../src/lib/usage/providerStatsFormatters.ts"; + +test.after(resetAllComboMetrics); + +test("formatComboSuccessRate preserves the producer's 0-100 percentage scale", () => { + resetAllComboMetrics(); + recordComboRequest("format-test", "openai/gpt-4o-mini", { + success: true, + latencyMs: 10, + }); + + const metrics = getComboMetrics("format-test"); + assert.ok(metrics); + assert.equal(metrics.successRate, 100); + assert.equal(formatComboSuccessRate(metrics.successRate), "100.0%"); + assert.equal(formatComboSuccessRate(50), "50.0%"); + assert.equal(formatComboSuccessRate(0), "0.0%"); +}); + +test("Provider Stats renders combo metrics through the percentage-scale formatter", () => { + const source = fs.readFileSync( + path.resolve("src/app/(dashboard)/dashboard/provider-stats/page.tsx"), + "utf8" + ); + + assert.match(source, /formatComboSuccessRate\(m\.successRate\)/); + assert.doesNotMatch(source, /m\.successRate\s*\*\s*100/); +});