feat(quota): explain key-enable + exclusive behavior in concept card

This commit is contained in:
diegosouzapw
2026-05-31 10:41:22 -03:00
parent 767fad3d5c
commit bbc4c575e0
4 changed files with 44 additions and 0 deletions

View File

@@ -33,6 +33,16 @@ export default function QuotaConceptCard() {
<ConceptItem icon="trending_up" text={t("conceptBorrowing")} />
<ConceptItem icon="lock" text={t("conceptGlobalCap")} />
<ConceptItem icon="schedule" text={t("conceptWindows")} />
<ConceptItemWithDesc
icon="vpn_key"
title={t("conceptKeyHowTitle")}
desc={t("conceptKeyHowDesc")}
/>
<ConceptItemWithDesc
icon="block"
title={t("conceptExclusiveTitle")}
desc={t("conceptExclusiveDesc")}
/>
</div>
</div>
)}
@@ -50,3 +60,17 @@ function ConceptItem({ icon, text }: { icon: string; text: string }) {
</div>
);
}
function ConceptItemWithDesc({ icon, title, desc }: { icon: string; title: string; desc: string }) {
return (
<div className="flex items-start gap-1.5 rounded-md bg-bg-subtle/40 p-2">
<span className="material-symbols-outlined text-[16px] text-primary shrink-0 mt-0.5">
{icon}
</span>
<div className="flex flex-col gap-0.5">
<span className="font-semibold text-text-main">{title}</span>
<span className="text-text-muted">{desc}</span>
</div>
</div>
);
}

View File

@@ -7855,6 +7855,10 @@
"conceptBorrowing": "Borrowing: keys can consume free balance from others without breaching the cap",
"conceptGlobalCap": "Hard global cap: the provider's absolute limit is never exceeded",
"conceptWindows": "Windows: 5h, hourly, daily, weekly, monthly — each tracked independently",
"conceptKeyHowTitle": "Enabling a key for quota",
"conceptKeyHowDesc": "Create the key normally in the API Manager — it appears in the wizard's key step automatically. Tick Exclusive there to make it quota-only. No separate enable step.",
"conceptExclusiveTitle": "What \"Exclusive\" does",
"conceptExclusiveDesc": "An exclusive key only sees/uses the pool's quotaShared-* models — every other model is hidden from its /v1/models and blocked.",
"burnRateTitle": "Burn rate",
"burnRateExhaustsIn": "Exhausts in",
"dimensionResetIn": "Resets in",

View File

@@ -5365,6 +5365,10 @@
"conceptBorrowing": "Empréstimo: keys podem usar saldo livre de outras sem ultrapassar o teto",
"conceptGlobalCap": "Teto intransponível: o cap absoluto do provider nunca é excedido",
"conceptWindows": "Janelas: 5h, horária, diária, semanal, mensal — cada uma rastreada independentemente",
"conceptKeyHowTitle": "Habilitando uma key para cota",
"conceptKeyHowDesc": "Crie a key normalmente no Gerenciador de APIs — ela aparece automaticamente na etapa de keys do wizard. Marque Exclusiva lá para torná-la somente-cota. Não há etapa de ativação separada.",
"conceptExclusiveTitle": "O que \"Exclusiva\" faz",
"conceptExclusiveDesc": "Uma key exclusiva enxerga/usa apenas os modelos quotaShared-* do pool — todos os outros modelos ficam ocultos no seu /v1/models e bloqueados.",
"burnRateTitle": "Taxa de consumo",
"burnRateExhaustsIn": "Esgota em",
"dimensionResetIn": "Reset em",

View File

@@ -0,0 +1,12 @@
import test from "node:test";
import assert from "node:assert/strict";
import en from "../../src/i18n/messages/en.json" with { type: "json" };
import pt from "../../src/i18n/messages/pt-BR.json" with { type: "json" };
const KEYS = ["conceptKeyHowTitle","conceptKeyHowDesc","conceptExclusiveTitle","conceptExclusiveDesc"];
test("explanatory card i18n keys exist + parity", () => {
for (const k of KEYS) {
assert.equal(typeof (en as any).quotaShare[k], "string", `en missing ${k}`);
assert.equal(typeof (pt as any).quotaShare[k], "string", `pt missing ${k}`);
}
});