Documentação
Limites do plano
Aplicação server-side de limites do plano com o catálogo de billing e checkLimit().
O Motoko Base define limites numéricos do plano em src/lib/billing/config/plans.ts (PLAN_CATALOG). A página de configurações de Usage exibe o progresso em relação a esses limites. A aplicação acontece no servidor nas mutações de features — nunca apenas na UI.
Architecture
PLAN_CATALOG.limits
↓
getBillingSummary(userId) → summaryGetLimit()
↓
checkLimit(userId, limitId, currentUsage, delta)
↓
Server Action / route handler rejects or allows mutationOs limites são resolvidos a partir do resumo de billing do usuário. Usuários sem acesso pago (incluindo past_due) recebem limites do plano Free. Quando o Polar não está configurado, checkLimit() permite mutações para que o desenvolvimento local com configuração mínima continue funcionando.
checkLimit API
import { checkLimit } from "@/lib/billing";
const result = await checkLimit(userId, "links", currentCount, 1);
if (result.status === "limit_reached") {
// reject mutation with user-facing message
}
if (result.status === "unavailable") {
// billing lookup failed — fail closed with safe error
}Resultados:
| Status | Meaning |
|---|---|
allowed | A mutação pode prosseguir (limit: null = ilimitado) |
limit_reached | Ultrapassaria o limite do plano |
unavailable | Não foi possível resolver o resumo de billing |
Shipped enforcement
| Feature | Boundary | Notes |
|---|---|---|
| Links | createLinkAction | Update/delete não são bloqueados pelo limite |
| Storage | createUploadAction + confirmUploadAction | Pré-verificação no init; verificação definitiva no confirm (ciclo de vida de upload presignado) |
O uso de storage conta linhas files com status = "ready", somando sizeBytes. Uploads pendentes são incluídos apenas na pré-verificação do init.
Usage metrics registry
A exibição de uso (src/lib/billing/usage.ts) lê métricas de um registro. Cada feature registra sua medida:
// src/features/links/usage-metric.ts
registerUsageMetric({
id: "links",
limitId: "links",
label: "Links",
measure: countLinksForUser,
});Importe @/features/dashboard/lib/bootstrap-usage-metrics (ou os módulos individuais usage-metric.ts) antes de chamar getUsageSnapshot() para que as métricas estejam registradas.
Remover um demo: exclua a pasta do feature e seu usage-metric.ts. Não é necessário editar src/lib/billing/usage.ts.
Adding limits to a new feature
- Adicione um
LimitIde um valor de limite aoPLAN_CATALOGemconfig/plans.ts. - Exporte uma função
measure(userId)das queries do seu feature. - Registre a métrica em
<feature>/usage-metric.ts. - Chame
checkLimit()na mutação do servidor antes de persistir o novo estado que consome quota. - Passe o uso
currentcomo parâmetro — não hardcode limites do plano no feature.
Concurrency
Links e storage usam aplicação best-effort: duas criações concorrentes perto do limite podem ter sucesso brevemente. Isso é aceitável para o starter e documentado com honestidade. Aplicação estrita exigiria transações ou locks por usuário — adicione isso no seu produto se precisar de garantias rígidas.
Uploads concorrentes de storage seguem o mesmo modelo: a verificação definitiva roda no confirm/finalização, mas dois confirms perto do limite podem passar ambos em condições de corrida.
Related docs
- Payments (Polar) — resumo de billing e entitlements
- Storage — ciclo de vida de upload
src/lib/security/README.md— padrões de segurança