feat(frontend): Platform > IA > Providers/Modelos/Uso/Custos + achado real de autorização
Providers/Modelos reaproveitam os endpoints /ai/providers e /ai/models já existentes (só filtram scope GLOBAL na tela); Modelos expõe custo unitário (inputCost/outputCost/audioCost) que a tela de tenant nunca mostra, porque só platform precisa cadastrar preço. GET /platform/ai-usage (novo) agrega uso bruto de AIUsageRecord de todos os tenants no mês corrente (Uso) e estima custo casando cada registro com o AIModel correspondente (Custos) — quando não dá pra casar, o registro fica de fora da soma e o tenant é marcado costIncomplete, nunca um número inventado. Achado real de autorização ao revisar AIModelsController antes de construir a tela de Modelos: POST/DELETE /ai/models não checava isPlatformUser quando o alvo era scope=GLOBAL — como a RLS híbrida (OR tenant_id IS NULL) deixa qualquer tenant ENXERGAR um provider/modelo GLOBAL, qualquer Tenant Admin com `ai.manage` (permission de escopo TENANT) conseguia injetar um modelo no catálogo global ou desabilitar um modelo GLOBAL só sabendo o id. O endpoint irmão (AIProvidersController) já tinha o check certo; corrigido com o mesmo padrão. Confirmado com um teste de ataque real: 403 depois do fix (era 201/sucesso antes), com regressão confirmando que BYOK do próprio tenant continua funcionando normalmente. Testado ponta a ponta: provider+modelo GLOBAL com custo real, uso de teste inserido direto no Postgres, /platform/ai-usage devolvendo o valor exato esperado (bate com a conta manual), tudo removido no final. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
@@ -93,7 +93,28 @@ export const PLATFORM_NAV: NavSection[] = [
|
||||
{
|
||||
label: "IA",
|
||||
icon: Sparkles,
|
||||
children: [{ label: "Providers" }, { label: "Modelos" }, { label: "Uso" }, { label: "Custos" }],
|
||||
children: [
|
||||
{
|
||||
label: "Providers",
|
||||
href: "/platform/ia/providers",
|
||||
description: "Providers de IA globais, visíveis por qualquer tenant",
|
||||
},
|
||||
{
|
||||
label: "Modelos",
|
||||
href: "/platform/ia/modelos",
|
||||
description: "Modelos dos providers globais, com custo unitário",
|
||||
},
|
||||
{
|
||||
label: "Uso",
|
||||
href: "/platform/ia/uso",
|
||||
description: "Uso bruto de IA de todos os tenants no mês corrente",
|
||||
},
|
||||
{
|
||||
label: "Custos",
|
||||
href: "/platform/ia/custos",
|
||||
description: "Uso × custo unitário — estimado, nunca um número fixo",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Sistema",
|
||||
|
||||
Reference in New Issue
Block a user