Planos e entitlements
Todo recurso ou limite que depende do plano é uma chave do catálogo de entitlements. O catálogo é declarado no código de cada módulo; os valores ficam no banco e são editados aqui, sem deploy. Uma feature nova aparece sozinha nas telas de plano quando é publicada.
Cada chave tem um tipo:
| Tipo | O que é | Erro para o tenant |
|---|---|---|
| Feature | Liga ou desliga um recurso | 403 plan.feature_unavailable |
| Limit | Teto (ou piso) de um valor que o tenant configura | 400 plan.limit_exceeded no campo |
| Quota | Contagem de recursos, com o uso calculado pela plataforma | 422 quota-exceeded, code quota.exceeded |
| Choice | Uma opção de uma lista fechada | Depende do módulo |
O valor efetivo de uma organização segue a ordem: override válido da organização, depois o valor do plano e, por fim, o padrão da definição. Uma mudança vale para as organizações em segundos. Quando um valor é reduzido, os recursos que a organização já tem continuam funcionando; a regra nova vale para o que for criado ou alterado depois.
Chaves atuais
| Chave | Tipo | Faixa e observações | Starter | Pro | Business | Enterprise |
|---|---|---|---|---|---|---|
quota.projects | Quota | 3 | 10 | 50 | 200 | |
quota.environmentsPerProject | Quota | Conta por projeto | 4 | 6 | 10 | 20 |
quota.applications | Quota | 5 | 25 | 100 | 500 | |
quota.instances | Quota | 4 | 50 | 200 | 1.000 | |
quota.vCpuMillis | Quota | Milicores | 4.000 | 16.000 | 64.000 | 256.000 |
quota.memoryMiB | Quota | MiB | 8.192 | 32.768 | 131.072 | 524.288 |
quota.storageGiB | Quota | GiB | 20 | 100 | 500 | 2.000 |
quota.buildMinutesMonthly | Quota | Minutos por mês | 300 | 1.500 | 6.000 | 20.000 |
quota.customDomains | Quota | 1 | 10 | 50 | 200 | |
gateway.routeRateLimitDefault | Limit | Requisições por minuto | 60 | 300 | 1.200 | 6.000 |
gateway.routeRateLimitMax | Limit | Requisições por minuto | 120 | 600 | 3.000 | 20.000 |
waf.customization | Feature | Não | Sim | Sim | Sim | |
waf.maxExceptions | Quota | Depende de waf.customization | 0 | 5 | 50 | 50 |
waf.maxBodySizeMb | Limit | 1 a 1024 MB | 10 | 50 | 100 | 200 |
waf.eventRetentionDays | Limit | 7 a 365 dias | 30 | 30 | 90 | 180 |
apiTokens.maxServiceAccounts | Quota | 0 a 1.000; conta ativas e desativadas | 2 | 10 | 50 | 200 |
apiTokens.requestsPerMinute | Limit | 60 a 6.000 por minuto, por token; vale na hora | 600 | 600 | 600 | 600 |
apiTokens.mutationsPerMinute | Limit | 10 a 600 por minuto, por token; vale na hora | 60 | 60 | 60 | 60 |
exec.enabled | Feature | Desligar encerra as sessões abertas | Sim | Sim | Sim | Sim |
exec.maxConcurrentSessions | Quota | 1 a 500 sessões abertas na organização | 1 | 10 | 30 | 100 |
exec.recordingRetentionDays | Limit | 1 a 365 dias; fixado no fechamento da sessão | 7 | 30 | 90 | 365 |
mcp.enabled | Feature | Checado a cada chamada MCP; desligado, as ferramentas da organização devolvem plan.feature_unavailable | Sim | Sim | Sim | Sim |
mcp.callsPerMinute | Limit | 10 a 10.000 chamadas MCP por minuto, total da organização; vale na hora | 60 | 300 | 1.200 | 3.000 |
Os valores dos quatro planos padrão são o seed inicial e reproduzem exatamente os limites que existiam antes do catálogo. O seed é aplicado uma única vez por chave e plano: depois que você edita um valor, nenhum deploy o sobrescreve. Planos criados pelo admin não recebem seed e usam o padrão de cada definição até serem editados.
Uma chave com dependência (como waf.maxExceptions, que depende de waf.customization) só aceita valor acima de zero quando a feature de que depende está ligada.
Recursos e limites de um plano
Em Planos › <plano>, a aba Recursos e limites é gerada a partir do catálogo:
- As chaves aparecem agrupadas por módulo (core, gateway, WAF e os que vierem), com um controle por tipo: interruptor para Feature, número com unidade e faixa para Limit e Quota, lista para Choice.
- Cada chave mostra a origem do valor: definido no plano ou herdado do padrão da definição.
- Restaurar padrão volta uma chave ao padrão da definição.
- Valores inválidos (fora da faixa, chave desconhecida ou dependência desligada) aparecem como erro no próprio campo.
Prévia de impacto
Salvar abre antes a prévia de impacto, e nada é gravado sem a confirmação. A prévia mostra quantas organizações estão no plano e, para cada quota reduzida, quantas ficariam acima do novo limite (por exemplo, "afeta 12 organizações; 2 ficarão acima do limite"). As organizações acima do limite continuam com o que já têm e passam a aparecer no cartão Organizações acima de quota da visão geral.
Edição concorrente
A leitura dos valores devolve a versão no ETag, e a gravação exige If-Match com essa versão. Se outra pessoa salvou antes, a gravação responde 412 com o estado atual, e a tela pede para revisar e salvar de novo. Sem o cabeçalho, a API responde 428.
Cada gravação entra na auditoria como plan.entitlements_updated, com o valor anterior e o novo de cada chave alterada.
Comparar planos
A aba Comparar planos em Planos mostra a matriz dos planos ativos por chave. Cada célula é editável e usa a mesma prévia de impacto antes de salvar. É o jeito mais rápido de conferir se os planos estão em ordem crescente e de achar valores fora da faixa.
Plano padrão e disponível para escolha
- Tornar padrão: existe sempre exatamente um plano padrão ativo. Uma organização criada sem escolher plano nasce nele. O plano padrão não pode ser desativado (409); torne outro plano padrão antes.
- Disponível para escolha: marca os planos que aparecem como cartões no diálogo Nova organização. O Starter nasce disponível e padrão; os demais planos padrão e os planos criados pelo admin nascem fora da escolha. Enquanto não houver cobrança obrigatória na escolha, deixe disponível só o plano que pode ser usado sem pagamento.
O cartão Planos da visão geral avisa quando o plano padrão está fora da escolha.
Entitlements de uma organização
Em Organizações › <organização>, a aba Entitlements mostra o valor efetivo de cada chave, a origem (OVERRIDE, PLAN ou DEFAULT) e o uso das quotas.
Overrides
Um override dá à organização um valor diferente do plano: contrato especial, trial, cortesia ou restrição por abuso.
- Motivo obrigatório, de 10 a 500 caracteres. Ele só aparece para a equipe da plataforma; o tenant vê o selo "Concedido até DD/MM" no Plano e uso, sem o motivo.
- Validade opcional. No vencimento, o override expira sozinho e a organização volta ao valor do plano.
- O valor passa pela mesma validação da definição, com as dependências avaliadas sobre os valores efetivos da organização.
- Há no máximo um override ativo por chave. Remover um override também volta a organização ao valor do plano.
Overrides sem validade aparecem na visão geral, para não ficarem esquecidos. A auditoria registra organization.entitlement_override_set, organization.entitlement_override_removed e organization.entitlement_override_expired.
Cortesias
Um pacote de cortesia é um modelo nomeado de overrides, por exemplo "Piloto 30 dias: WAF completo e 5 domínios". Cadastre os pacotes em Cortesias (/admin/courtesy-packages), com nome, descrição, itens (chave e valor, validados contra o catálogo) e duração padrão em dias.
- Aplicar cortesia (na organização): escolha o pacote, informe o motivo e, se quiser, uma validade diferente da duração do pacote. Cada item vira um override marcado com o pacote. O tenant vê o selo "Cortesia: <pacote> até DD/MM".
- Conflito: se a organização já tem override numa das chaves do pacote, a aplicação responde 409 com as chaves em conflito. Para substituir esses overrides, confirme a substituição (
replace: true). - Remover: remove de uma vez todos os overrides daquela aplicação.
- Expiração: igual à dos overrides.
- Alterar um pacote depois não muda as aplicações já feitas.
A auditoria registra organization.courtesy_applied, organization.courtesy_removed e organization.courtesy_expired, com o pacote e as chaves. Cortesias concedem recursos, não descontos no preço.
API
Todas as rotas exigem platform_admin e recusam campos desconhecidos no corpo.
| Método e rota | O que faz |
|---|---|
GET /api/v1/admin/entitlements/catalog | Definições do catálogo: tipo, faixa, unidade, módulo, dependências e visibilidade |
GET /api/v1/admin/plans/{planId}/entitlements | Valores do plano com a origem; versão no ETag |
PATCH /api/v1/admin/plans/{planId}/entitlements | Grava { "values": { "<chave>": <valor> } }; exige If-Match (412 com o estado atual, 428 sem o cabeçalho) |
POST /api/v1/admin/plans/{planId}/entitlements/preview | Mesmo corpo do PATCH; devolve as organizações afetadas e quantas ficariam acima de cada quota reduzida, sem gravar |
GET /api/v1/admin/plans/entitlements-matrix | Matriz dos planos ativos por chave |
POST /api/v1/admin/plans/{planId}/make-default | Torna o plano o padrão |
GET /api/v1/admin/orgs/{orgId}/entitlements | Valores efetivos da organização com origem, validade e motivo |
PUT /api/v1/admin/orgs/{orgId}/entitlements/overrides/{key} | Cria ou troca o override (value, reason, expiresAt opcional) |
DELETE /api/v1/admin/orgs/{orgId}/entitlements/overrides/{key} | Remove o override |
GET, POST /api/v1/admin/courtesy-packages e GET, PUT /api/v1/admin/courtesy-packages/{packageId} | Lista, cria, lê e altera pacotes de cortesia |
POST /api/v1/admin/orgs/{orgId}/courtesies | Aplica um pacote (packageId, reason, expiresAt opcional, replace opcional) |
DELETE /api/v1/admin/orgs/{orgId}/courtesies/{applicationId} | Remove a cortesia aplicada |
GET /api/v1/admin/overview | Cartões da visão geral |
{
"value": 3,
"reason": "Piloto acordado com o cliente até o fim do mês",
"expiresAt": "2026-11-15T23:59:59Z"
}
A visão do tenant (o que ele vê, os erros e a escolha do plano) está em Planos, recursos e limites.