Expose DEB quality guidance

This commit is contained in:
2569718930@qq.com
2026-06-07 23:57:47 +08:00
parent 4389d4a40d
commit bbe3871b7c
9 changed files with 264 additions and 3 deletions
@@ -38,6 +38,50 @@ function highLabel(label: string, isEn: boolean) {
return isEn ? (HIGH_LABEL_EN[label] || label) : label;
}
type DebQuality = {
quality_tier?: string | null;
recommendation?: string | null;
recent_hit_rate?: number | null;
recent_samples?: number | null;
};
function debQualityLabel(quality: DebQuality | null | undefined, isEn: boolean) {
const recommendation = quality?.recommendation;
if (recommendation === "primary") return isEn ? "Primary" : "主用";
if (recommendation === "supporting") return isEn ? "Support" : "辅助";
if (recommendation === "context_only") return isEn ? "Context" : "参考";
if (recommendation === "insufficient") return isEn ? "Thin" : "样本少";
return "";
}
function debQualityClass(quality: DebQuality | null | undefined) {
const tier = quality?.quality_tier;
if (tier === "high") return "border-emerald-200 bg-emerald-50 text-emerald-700";
if (tier === "medium") return "border-amber-200 bg-amber-50 text-amber-700";
if (tier === "low") return "border-rose-200 bg-rose-50 text-rose-700";
return "border-slate-200 bg-slate-50 text-slate-500";
}
function DebQualityBadge({ quality, isEn }: { quality?: DebQuality | null; isEn: boolean }) {
const label = debQualityLabel(quality, isEn);
if (!label) return null;
const hitRate = quality?.recent_hit_rate;
const samples = quality?.recent_samples;
const titleParts = [
isEn ? `DEB recommendation: ${label}` : `DEB 建议:${label}`,
hitRate == null ? null : `${hitRate.toFixed(0)}%`,
samples == null ? null : `n=${samples}`,
].filter(Boolean);
return (
<span
className={clsx("ml-1.5 inline-flex items-center rounded border px-1.5 py-0.5 text-[9px] font-black uppercase leading-none", debQualityClass(quality))}
title={titleParts.join(" · ")}
>
{label}
</span>
);
}
function buildStatsLabels({
isEn,
isShenzhen,
@@ -82,6 +126,7 @@ export function TemperatureStatsBars({
observedHighRunway,
wundergroundDailyHigh,
debVal,
debQuality,
modelMin,
modelMax,
spread,
@@ -104,6 +149,7 @@ export function TemperatureStatsBars({
observedHighRunway: number | null;
wundergroundDailyHigh: number | null;
debVal: number | null;
debQuality?: DebQuality | null;
modelMin: number | null;
modelMax: number | null;
spread: number | null;
@@ -139,6 +185,7 @@ export function TemperatureStatsBars({
<div className="flex items-center gap-4 text-[11px]">
<span className="font-semibold text-slate-500">
DEB: <strong className="text-orange-600 font-mono">{temp(debVal, tempSymbol)}</strong>
<DebQualityBadge quality={debQuality} isEn={isEn} />
</span>
{modelMin !== null && modelMax !== null && (
<>
@@ -187,6 +234,7 @@ export function TemperatureStatsBars({
<div className="flex flex-col">
<span className="text-[11px] font-semibold text-slate-500 uppercase tracking-wider">
DEB Max
<DebQualityBadge quality={debQuality} isEn={isEn} />
</span>
<span className="text-2xl font-bold font-mono text-orange-600 mt-1">
{temp(debVal, tempSymbol)}
@@ -237,6 +285,7 @@ export function TemperatureStatsBars({
</span>
<strong className="text-blue-600 font-bold">
{temp(debVal, tempSymbol)}
<DebQualityBadge quality={debQuality} isEn={isEn} />
</strong>
</div>
<div className="flex flex-col gap-0.5">
@@ -263,3 +312,4 @@ export function TemperatureStatsBars({
}
export const __buildTemperatureStatsLabelsForTest = buildStatsLabels;
export const __buildDebQualityLabelForTest = debQualityLabel;