Bucket é uma pasta com regra na porta
Todo arquivo no SuperDB mora dentro de um bucket. O bucket não é só uma pasta: é onde ficam as três decisões que valem para tudo que entra nele — quem pode ler, qual o tamanho máximo e que tipo de arquivo é aceito.
Os buckets de um projeto são isolados dos buckets de outro por construção: o nome real recebe o prefixo do seu schema (proj_<slug>_) e o token de acesso carrega esse schema. Um token do projeto A não enxerga bucket do projeto B nem sabendo o nome.
Se você vem do Supabase, o modelo é o mesmo — inclusive os nomes dos campos. O que muda é que aqui o prefixo do projeto é obrigatório e aplicado no servidor.
Público ou privado — a decisão que mais importa
Buckets nascem privados. É o padrão certo: um bucket privado exige um token válido em toda leitura, então um arquivo que vazou de URL continua protegido.
| Privado (padrão) | Público | |
|---|---|---|
| Leitura | Exige token | Qualquer um com a URL |
| Escrita | Exige token | Exige token |
| Cache | Não cacheável | Cacheável — mais rápido e mais barato |
| Use para | Documento, laudo, contrato, foto de usuário | Logo, banner, capa de post, asset do site |
A regra prática: público é para arquivo que você colocaria numa página aberta. Qualquer coisa que identifique uma pessoa fica privada — e no Brasil isso não é preferência, é LGPD.
Criar um bucket
curl -X POST https://auth.superdb.com.br/platform/v1/projects/<projectId>/storage/buckets \
-H "Authorization: Bearer <seu token>" \
-H "Content-Type: application/json" \
-d '{
"name": "avatares",
"public": true,
"file_size_limit": 5242880
}'
Sem public, o bucket nasce privado. Sem file_size_limit, vale o teto da plataforma (50 MB por arquivo).
Tamanho máximo por bucket
file_size_limit é em bytes e vale por arquivo, não por bucket. Um bucket de avatares com 5 MB rejeita o upload de 40 MB antes de gravar qualquer coisa.
| Para | Sugestão | Em bytes |
|---|---|---|
| Avatar, ícone | 2 MB | 2097152 |
| Imagem de produto | 5 MB | 5242880 |
| PDF, documento | 20 MB | 20971520 |
| Teto da plataforma | 50 MB | 52428800 |
Definir um limite apertado no bucket é a defesa mais barata que existe contra alguém entupir sua cota. O limite de 50 MB da plataforma é teto, não recomendação.
O que conta na sua cota
O espaço somado de todos os buckets do projeto conta como armazenamento do seu plano. O tráfego de download conta como tráfego.
Quando o uso passa de 80%, as respostas da API passam a trazer o cabeçalho X-SuperDB-Quota-Warning — dá para acender um alerta no seu monitoramento antes de a coisa apertar.
Passando do limite: plano pago continua funcionando e o excedente entra na fatura. No plano grátis o upload passa a ser recusado com 402 quota_exceeded, porque ali não há a quem cobrar. Nenhum arquivo já enviado é apagado em nenhum dos casos.
Controle fino: RLS nos objetos
Público e privado resolvem os dois extremos. Entre eles — "cada usuário lê só a própria pasta", "só quem é da clínica X vê o laudo" — a régua é RLS na tabela storage.objects, exatamente como em qualquer tabela sua.
-- cada usuário só enxerga o que está na pasta com o próprio id
create policy "usuario_le_sua_pasta"
on storage.objects for select
to authenticated
using (
bucket_id = 'proj_meuapp_documentos'
and (storage.foldername(name))[1] = auth.uid()::text
);
Nomes de bucket
Só minúsculas, números, - e _, até 40 caracteres. Você usa o nome curto (avatares) e o servidor resolve o nome completo com o prefixo do seu projeto.
Evite _ a mais no nome. O prefixo do projeto já usa _ como separador, e um nome como meu_bucket_teste deixa a resolução ambígua. Prefira meu-bucket-teste.
O que ainda não fazemos
Sendo direto, para você não descobrir no meio da implementação:
- Restrição de MIME type por bucket — ainda não. Valide o tipo no seu app antes de subir.
- Transformação de imagem na URL (resize, crop) — ainda não.
- Upload retomável para arquivos grandes — ainda não; o teto por arquivo é 50 MB.