Logosulfite.app
rafagazani/sulfite 999999

Relatórios

Endpoints de CRUD de relatórios do sulfite_server

Relatórios (CRUD)#

O servidor armazena definições de relatório e permite operações completas de criação, leitura, atualização e exclusão.

Em deploys multi-tenant, relatórios usam namespace para separar templates locais de templates globais:

  • tenant é o padrão e fica visível apenas para o tenant da requisição.
  • global é compartilhado entre todos os tenants e exige can_edit_global para criar, editar, excluir, assinar ou portar.

Veja também Multi-Tenancy.

Listar — GET /api/v1/reports#

Permissão: canList

Query params#

ParamTipoDescrição
qstringBusca full-text pelo nome/descrição
groupstringFiltra relatórios visíveis dentro de um grupo
pageintPágina (começa em 1)
limitintItens por página (1–100, default 20)

Quando group é informado, o resultado vem das associações do grupo para o tenant atual. Veja Grupos de relatórios para criar grupos, associar relatórios e entender o escopo tenant/global.

Resposta sem paginação#

[
  {
    "id": "uuid",
    "name": "Sales Report",
    "namespace": "tenant",
    "description": "Monthly sales overview",
    "createdAt": "2026-04-06T12:00:00.000Z",
    "updatedAt": "2026-04-06T12:00:00.000Z",
    "storageKind": "inline"
  }
]

Resposta com paginação#

{
  "data": [ ... ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "totalPages": 3
  }
}

Detalhes — GET /api/v1/reports/:id#

Permissão: canList

Retorna o relatório completo incluindo definitionJson, packageBytes, etc. No modo federado, o ID pode resolver um template global ou um relatório local do tenant atual.

StatusErroQuando
404not_foundID não encontrado

Criar — POST /api/v1/reports#

Permissão: canInsert

Body:

{
  "name": "My Report",
  "namespace": "tenant",
  "description": "Optional description",
  "definitionJson": "{ ... }",
  "packageBytes": "base64encoded..."
}
CampoObrigatórioDescrição
nameSimNome do relatório (não vazio)
namespace Não tenant por padrão; use global para criar template compartilhado
descriptionNãoDescrição
definitionJsonNãoJSON inline da definição
packageBytesNãoBase64 do pacote .sulfite

Resposta 201: Metadados do relatório criado (id, name, description, createdAt, updatedAt, storageKind).

StatusErroQuando
400 validation_error name ausente ou vazio
403forbiddenSem canInsert
403 forbidden "namespace": "global" sem can_edit_global
402quota_exceededQuota local do tenant excedida

Valores desconhecidos de namespace são normalizados para tenant. Templates globais não consomem reports.count nem storage.bytes dos tenants.

Criar template global#

curl -X POST http://localhost:8080/api/v1/reports \
  -H "Authorization: Bearer $OPERATOR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Invoice Template",
    "namespace": "global",
    "definitionJson": "{...}"
  }'

Atualizar — PUT /api/v1/reports/:id#

Permissão: canEdit

Body: Mesmos campos do POST (todos opcionais). Se name for fornecido, não pode ser vazio. O namespace não pode ser alterado depois da criação. Atualizar um relatório global exige can_edit_global.

Resposta 200: Metadados atualizados.

StatusErroQuando
400validation_errorname vazio
403 forbidden Relatório global sem can_edit_global
404not_foundID não encontrado
422 namespace_immutable Tentativa de trocar namespace
402 quota_exceeded Novo pacote excede storage.bytes local

Excluir — DELETE /api/v1/reports/:id#

Permissão: canDelete

Excluir um relatório global exige can_edit_global.

Resposta 204: Sem body.

StatusErroQuando
403 forbidden Relatório global sem can_edit_global
404not_foundID não encontrado

Exemplo: fluxo completo#

# Criar
curl -X POST http://localhost:8080/api/v1/reports \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Vendas Mensal", "namespace": "tenant", "definitionJson": "{...}"}'

# Listar
curl http://localhost:8080/api/v1/reports \
  -H "Authorization: Bearer $TOKEN"

# Buscar
curl "http://localhost:8080/api/v1/reports?q=vendas" \
  -H "Authorization: Bearer $TOKEN"

# Atualizar
curl -X PUT http://localhost:8080/api/v1/reports/$ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"description": "Atualizado"}'

# Excluir
curl -X DELETE http://localhost:8080/api/v1/reports/$ID \
  -H "Authorization: Bearer $TOKEN"