Chamados

Realm interno (operadores do escritório) dos chamados de suporte abertos pelas empresas no Portal do Cliente. Por aqui o time lista e filtra a fila, conversa na thread (respostas públicas e notas internas), anexa arquivos, muda o status do chamado e registra a avaliação interna da empresa.

Superfície do cliente

Este router atende só o realm interno. A superfície do cliente é registrada separadamente, sob /portal/chamados, com o token do Portal (não com API Key nem JWT interno) e sem os escopos abaixo. Ela fica documentada na página Portal do Cliente. Os dois conjuntos de rotas leem os mesmos dados de propósito: uma rota única com os dois principals exigiria ramificar o corpo por tipo de usuário.

Base path

Todos os endpoints abaixo são montados sob o prefixo:

/api/v1/chamados

A URL completa em produção é https://api.contabilidadealcance.com.br/api/v1/chamados.

Escopos necessários

O router é montado com _SCOPE_DEP, que deriva o escopo do primeiro segmento após /api/v1/ e do método HTTP (GET = read; POST/PUT/DELETE = write). O mesmo _SCOPE_DEP aplica o gate de senha provisória: um JWT de usuário cuja senha vigente foi definida por outra pessoa recebe 403 até o titular definir uma senha própria (o gate não se aplica a API Key).

EscopoOperações permitidas
chamados:readGET /, GET /cliente/{id_cliente}, GET /resumo, GET /nao-lidas, GET /avaliacao-interna/resumo, GET /{chamado_id}, GET /{chamado_id}/avaliacao, GET /{chamado_id}/avaliacao-interna, GET /{chamado_id}/mensagens, GET /mensagens/{mensagem_id}, GET /anexos/{anexo_id}, GET /{chamado_id}/anexos
chamados:writePOST /, PUT /{chamado_id}, DELETE /{chamado_id}, POST /{chamado_id}/leitura, POST /{chamado_id}/avaliacao-interna, POST /{chamado_id}/mensagens, PUT /mensagens/{mensagem_id}, DELETE /mensagens/{mensagem_id}, DELETE /anexos/{anexo_id}, POST /{chamado_id}/anexos

Além do escopo, algumas rotas têm guard próprio:

RotaGuard adicional
DELETE /chamados/{chamado_id}Perfil administrador ou diretoria (require_perfil). Demais perfis recebem 403.
DELETE /chamados/anexos/{anexo_id}Perfil administrador ou diretoria (require_perfil).
DELETE /chamados/mensagens/{mensagem_id}Por autoria: o operador apaga só as próprias mensagens; administrador/diretoria apagam qualquer uma. Sem perfil exigido na frente.
POST /chamados/{chamado_id}/avaliacao-internaGestão (administrador, diretoria, gestor) avalia qualquer chamado; o responsável atual avalia se ainda não há nota ou se a nota é dele.

Envelope de resposta

As rotas respondem com success_response: { "status": "success", "message": "...", "data": ... }. Erros de validação e de regra saem como HTTPException ({ "detail": ... }) com os status descritos em cada rota.

Status e tipos do chamado

O vocabulário vive em StatusChamado e TipoChamado. As colunas são varchar livres no banco; a restrição é aplicada na borda (schemas de escrita), de forma fail-closed: valor desconhecido vira 422.

StatusSignificado
abertoChamado sem triagem - ninguém respondeu publicamente ainda.
em_andamentoAtendimento em curso, incluindo a espera por retorno do cliente.
concluidoEncerrado. Não aceita mensagens nem anexos novos até ser reaberto.

Na escrita (PUT), o campo status aceita também as grafias em andamento e fechado (este vira concluido), com comparação sem acento e sem diferenciar maiúsculas. O status aguardando_cliente existiu até a v5.199.0 e foi removido.

TipoGrafias aceitas na escrita
problemaproblema, bug, erro (default na criação)
solicitacaosolicitacao
duvidaduvida
sugestaosugestao

Transições

  • Automática: quando um operador posta mensagem com visibilidade: "publica" em chamado aberto, o chamado passa para em_andamento. Nota interna e mensagem do cliente não movem o status.
  • Manual (PUT /chamados/{chamado_id}): o código não impõe matriz de transição - qualquer valor do vocabulário pode ser enviado. O que muda é o efeito sobre o trio do fechamento (data_hora_fechamento, id_usuario_fechamento, motivo_fechamento):
    • entrando em concluido: grava a data (horário de São Paulo), o usuário que fez a ação e o motivo (opcional);
    • saindo de concluido (reabertura): limpa os três;
    • já concluido, reenviando status: "concluido" com motivo_fechamento: reescreve só o motivo, sem mover a data;
    • demais casos: não toca no trio.
  • motivo_fechamento sem status: "concluido" no mesmo corpo é 422.
  • O cliente também pode encerrar o chamado pela superfície do Portal; reabrir é sempre um PUT interno.

Endpoints

GET /chamados/

Lista os chamados, opcionalmente filtrados. Sem sort_by, ordena do mais recente para o mais antigo. Cada item vem enriquecido com nao_lidas e ultima_mensagem_em do operador logado (mensagens do cliente ainda não vistas por ele, só em chamados não concluídos e do escopo dele: responsável por ele, sem responsável ou com responsável de conta inativa).

A paginação é opt-in: sem page e per_page, data é um array de ChamadoRead (caminho legado, com limit/offset). Com os dois, data é o envelope PaginatedChamados e limit/offset são ignorados. Informar só um deles mantém o caminho legado. Lista vazia no caminho legado retorna 200 OK com data: [] e a mensagem "Nenhum chamado encontrado.".

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
id_clienteintquerynãoFiltra por empresa.
statusstrquerynãoFiltra por status. Comparação exata: use o valor canônico (aberto, em_andamento, concluido).
tipostrquerynãoFiltra por tipo. Comparação exata: use o valor canônico.
id_usuario_responsavelintquerynãoFiltra por responsável.
buscastrquerynãoBusca em titulo e detalhamento. Termo só de dígitos casa também o número do chamado. % e _ são literais.
sort_bystrquerynãodata_hora_criacao, titulo, tipo ou status. Fora disso, 422.
sort_dirstrquerynãoasc ou desc (default desc).
pageintquerynãoPágina (1-based, >= 1). Ativa a paginação junto de per_page.
per_pageintquerynãoItens por página (1 a 100). Ativa a paginação junto de page.
limitintquerynãoCaminho legado: 1 a 500 (default 100).
offsetintquerynãoCaminho legado: >= 0 (default 0).

Request

Sem corpo de requisição.

Response 200 OK (com page=1&per_page=20)

{
  "status": "success",
  "message": "Chamados recuperados com sucesso",
  "data": {
    "items": [
      {
        "id": 318,
        "titulo": "Guia do DAS não aparece",
        "detalhamento": "A guia de setembro não está disponível na área de documentos.",
        "tipo": "problema",
        "id_cliente": 1234,
        "id_portal_user": 57,
        "status": "em_andamento",
        "id_usuario_responsavel": 42,
        "id_usuario_fechamento": null,
        "data_hora_criacao": "2026-10-14T09:12:00",
        "data_hora_edicao": "2026-10-14T10:03:00",
        "data_hora_fechamento": null,
        "motivo_fechamento": null,
        "nao_lidas": 1,
        "ultima_mensagem_em": "2026-10-14T15:40:00"
      }
    ],
    "total": 1,
    "total_pages": 1,
    "current_page": 1,
    "per_page": 20
  }
}

total reflete o conjunto já filtrado. Escopo: chamados:read

GET /chamados/cliente/{id_cliente}

Lista os chamados de uma empresa. Ordenação padrão (mais recente primeiro). Esta rota não calcula nao_lidas/ultima_mensagem_em, que vêm com o default (0 e null). Sem resultados, retorna 200 OK com data: [] e a mensagem "Nenhum chamado encontrado para esta empresa.".

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
id_clienteintpathsimID da empresa.
statusstrquerynãoFiltra por status (valor canônico).
limitintquerynão1 a 500 (default 100).
offsetintquerynão>= 0 (default 0).

Request

Sem corpo de requisição.

Response 200 OK

Array de ChamadoRead em data, com a mensagem "Chamados recuperados com sucesso".

Escopo: chamados:read

GET /chamados/resumo

Contagem da fila por status, para a faixa de abas ("Todos / Aberto / Em andamento / Concluído"). Os filtros compõem com a listagem: o resumo conta exatamente o conjunto que GET /chamados/ pagina. Não aceita status de propósito - a faixa precisa do número de todas as abas o tempo todo; se enviado, é ignorado. Todos os status vêm com zero explícito, e total é a soma.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
id_clienteintquerynãoFiltra por empresa.
tipostrquerynãoFiltra por tipo.
id_usuario_responsavelintquerynãoFiltra por responsável.
buscastrquerynãoMesma busca textual da listagem.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Resumo recuperado com sucesso",
  "data": {
    "aberto": 4,
    "em_andamento": 7,
    "concluido": 112,
    "total": 123
  }
}

Escopo: chamados:read

GET /chamados/nao-lidas

Números do badge da fila para o operador logado. Conta só mensagens do cliente ainda não vistas por ele (nota interna e resposta de colega não contam), ignora chamados concluídos e considera só o escopo do operador (responsável por ele, sem responsável ou com responsável de conta inativa). chamados_com_novidade bate com a quantidade de linhas com nao_lidas > 0 em GET /chamados/ para o mesmo usuário.

Parâmetros

Este endpoint não recebe parâmetros. O operador é o usuário autenticado.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Contagem recuperada com sucesso",
  "data": {
    "nao_lidas": 3,
    "chamados_com_novidade": 2
  }
}

Escopo: chamados:read

GET /chamados/avaliacao-interna/resumo

Nota geral de uma empresa a partir das avaliações internas (o escritório avaliando a empresa). media tem uma casa decimal e é null quando não há avaliação.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
id_clienteintquerysimEmpresa avaliada.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Nota geral recuperada com sucesso",
  "data": {
    "media": 4.5,
    "quantidade": 8
  }
}

Escopo: chamados:read

GET /chamados/{chamado_id}

Retorna um chamado pelo ID. Inexistente: 404 Not Found ("Chamado não encontrado.").

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Request

Sem corpo de requisição.

Response 200 OK

ChamadoRead em data, com a mensagem "Chamado recuperado com sucesso". Nesta rota nao_lidas e ultima_mensagem_em vêm com o default (0 e null).

Escopo: chamados:read

POST /chamados/

Abre um chamado pelo realm interno, em nome de uma empresa (id_cliente obrigatório; no Portal a empresa vem da sessão). O chamado nasce com status aberto.

Parâmetros

Sem parâmetros de rota ou query. Corpo ChamadoCreate.

Request

{
  "id_cliente": 1234,
  "titulo": "Envio do extrato de setembro",
  "detalhamento": "Cliente pediu por telefone para registrar o envio do extrato bancário.",
  "tipo": "solicitacao",
  "id_usuario_responsavel": 42
}

Response 201 Created

{
  "status": "success",
  "message": "Chamado criado com sucesso",
  "data": {
    "id": 319,
    "titulo": "Envio do extrato de setembro",
    "detalhamento": "Cliente pediu por telefone para registrar o envio do extrato bancário.",
    "tipo": "solicitacao",
    "id_cliente": 1234,
    "id_portal_user": null,
    "status": "aberto",
    "id_usuario_responsavel": 42,
    "id_usuario_fechamento": null,
    "data_hora_criacao": "2026-10-15T08:30:00",
    "data_hora_edicao": null,
    "data_hora_fechamento": null,
    "motivo_fechamento": null,
    "nao_lidas": 0,
    "ultima_mensagem_em": null
  }
}

id_cliente ou id_usuario_responsavel inexistente: 404 (mensagem com "não encontrado") ou 422 para os demais erros de valor. Campos fora do vocabulário ou fora dos limites: 422. Escopo: chamados:write

PUT /chamados/{chamado_id}

Atualiza um chamado, inclusive a transição de status (ver a seção "Transições" acima). Patch parcial: só os campos enviados mudam. Não aceita id_cliente nem id_portal_user - mover chamado de empresa não é permitido.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Corpo ChamadoUpdate.

Request

{
  "status": "concluido",
  "motivo_fechamento": "Guia reenviada por e-mail e disponibilizada no Portal."
}

Response 200 OK

ChamadoRead atualizado em data, com a mensagem "Chamado atualizado com sucesso". Ao concluir, data_hora_fechamento e id_usuario_fechamento vêm preenchidos.

Inexistente: 404. id_usuario_responsavel inexistente: 404/422. motivo_fechamento sem status: "concluido": 422. Escopo: chamados:write

DELETE /chamados/{chamado_id}

Exclui o chamado e, em cascata, toda a thread (mensagens, anexos). Operação destrutiva e irreversível: o caminho normal para encerrar é PUT com status: "concluido", que preserva o histórico.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Chamado removido com sucesso",
  "data": null
}

Perfil sem permissão: 403. Inexistente: 404. Escopo: chamados:write + perfil administrador ou diretoria.

POST /chamados/{chamado_id}/leitura

Marca até onde o operador logado leu a thread. Sem corpo: o servidor grava a data da última mensagem existente no chamado (de qualquer autor e visibilidade), nunca o horário atual nem uma data enviada. Idempotente e monotônica - a marca nunca retrocede. ultima_mensagem_lida_em vem null quando o chamado ainda não tem mensagens.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Leitura registrada com sucesso",
  "data": {
    "ultima_mensagem_lida_em": "2026-10-14T15:40:00"
  }
}

Inexistente: 404. Escopo: chamados:write (é um POST, embora não altere o chamado).

GET /chamados/{chamado_id}/avaliacao

Avaliação que o cliente deu ao atendimento (gravada pelo Portal; aqui é só leitura). Chamado ainda não avaliado retorna 200 OK com data: null - ausência de registro, não recurso inexistente.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Avaliação recuperada com sucesso",
  "data": {
    "nota": 5,
    "comentario": "Resolveram no mesmo dia.",
    "data_hora_criacao": "2026-10-14T17:02:00",
    "data_hora_edicao": null
  }
}

Chamado inexistente: 404. Escopo: chamados:read

GET /chamados/{chamado_id}/avaliacao-interna

Avaliação que o escritório deu à empresa neste chamado, ou data: null se ainda não houver. Não existe rota equivalente no Portal.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Avaliação interna recuperada com sucesso",
  "data": {
    "nota": 4,
    "comentario": "Enviou a documentação completa após o primeiro pedido.",
    "id_usuario": 42,
    "data_hora_criacao": "2026-10-14T17:30:00",
    "data_hora_edicao": null
  }
}

Chamado inexistente: 404. Escopo: chamados:read

POST /chamados/{chamado_id}/avaliacao-interna

Grava (upsert) a avaliação interna da empresa no chamado. A autoria vem do usuário logado. Só é aceita em chamado concluido.

Quem pode gravar:

  • gestão (administrador, diretoria, gestor): qualquer chamado;
  • responsável atual do chamado (inclusive funcionario): se ainda não há nota ou se a nota existente é dele;
  • demais usuários: nunca.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Corpo ChamadoAvaliacaoInternaCreate (campos extras são rejeitados).

Request

{
  "nota": 4,
  "comentario": "Enviou a documentação completa após o primeiro pedido."
}

Response 200 OK

ChamadoAvaliacaoInternaRead em data, com a mensagem "Avaliação interna registrada com sucesso".

Chamado inexistente: 404. Chamado não concluído: 409. Sem permissão: 403. Nota fora de 1 a 5 ou campo extra: 422. Escopo: chamados:write

GET /chamados/{chamado_id}/mensagens

Retorna a thread completa, em ordem cronológica. O realm interno enxerga também as notas internas (visibilidade: "interna"). Sem mensagens, retorna 200 OK com data: [] e a mensagem "Nenhuma mensagem encontrada.".

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.
limitintquerynão1 a 500 (default 100).
offsetintquerynão>= 0 (default 0).

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Mensagens recuperadas com sucesso",
  "data": [
    {
      "id": 901,
      "id_chamado": 318,
      "autor_realm": "portal",
      "id_portal_user": 57,
      "id_usuario": null,
      "texto": "A guia de setembro não aparece para mim.",
      "visibilidade": "publica",
      "data_hora_criacao": "2026-10-14T09:12:00",
      "autor_nome": null,
      "autor_foto_url": null
    },
    {
      "id": 902,
      "id_chamado": 318,
      "autor_realm": "interno",
      "id_portal_user": null,
      "id_usuario": 42,
      "texto": "Conferir se a guia foi gerada no lote de ontem.",
      "visibilidade": "interna",
      "data_hora_criacao": "2026-10-14T09:40:00",
      "autor_nome": null,
      "autor_foto_url": null
    }
  ]
}

Chamado inexistente: 404. Escopo: chamados:read

POST /chamados/{chamado_id}/mensagens

Posta uma mensagem na thread como operador (autor_realm: "interno", autoria do usuário logado). visibilidade tem default interna (fail-closed): para responder ao cliente é preciso enviar "publica" explicitamente. Resposta pública em chamado aberto move o chamado para em_andamento.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.

Corpo ChamadoMensagemCreate.

Request

{
  "texto": "A guia foi gerada e já está disponível na área de documentos.",
  "visibilidade": "publica"
}

Response 201 Created

ChamadoMensagemRead em data, com a mensagem "Mensagem postada com sucesso".

Chamado inexistente: 404. Chamado concluido: 409 ("Chamado concluído não aceita novas mensagens. Reabra o chamado antes."). Escopo: chamados:write

GET /chamados/mensagens/{mensagem_id}

Retorna uma mensagem pelo ID (qualquer visibilidade). Inexistente: 404 ("Mensagem não encontrada.").

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
mensagem_idintpathsimID da mensagem.

Request

Sem corpo de requisição.

Response 200 OK

ChamadoMensagemRead em data, com a mensagem "Mensagem recuperada com sucesso".

Escopo: chamados:read

PUT /chamados/mensagens/{mensagem_id}

Edita o texto e/ou a visibilidade de uma mensagem. Não aceita id_chamado - mover mensagem de thread mudaria quem a enxerga. Esta rota não verifica autoria nem perfil além do escopo.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
mensagem_idintpathsimID da mensagem.

Corpo ChamadoMensagemUpdate.

Request

{
  "visibilidade": "publica"
}

Response 200 OK

ChamadoMensagemRead atualizado em data, com a mensagem "Mensagem atualizada com sucesso".

Inexistente: 404. Visibilidade fora do vocabulário: 422. Escopo: chamados:write

DELETE /chamados/mensagens/{mensagem_id}

Exclui uma mensagem e, em cascata, os anexos presos a ela. Regra por autoria: o operador apaga só as mensagens que ele mesmo escreveu (autor_realm: "interno" e id_usuario igual ao dele); administrador e diretoria apagam qualquer uma, inclusive as do cliente. Mensagem alheia retorna 403 (não 404), porque a thread já é legível no realm interno.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
mensagem_idintpathsimID da mensagem.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Mensagem removida com sucesso",
  "data": null
}

Inexistente: 404. Sem autoria nem acesso total: 403 ("Você só pode apagar mensagens de sua autoria."). Escopo: chamados:write

GET /chamados/anexos/{anexo_id}

Baixa um anexo com conteudo_base64. É a única rota que expõe o conteúdo do arquivo; as listagens trazem só metadados.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
anexo_idintpathsimID do anexo.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Anexo recuperado com sucesso",
  "data": {
    "id": 77,
    "id_chamado": 318,
    "id_mensagem": 903,
    "nome_arquivo": "print_documentos.png",
    "mime_type": "image/png",
    "tamanho_bytes": 184320,
    "data_hora_criacao": "2026-10-14T10:05:00",
    "conteudo_base64": "iVBORw0KGgoAAAANSUhEUgAA..."
  }
}

Inexistente: 404 ("Anexo não encontrado."). Escopo: chamados:read

DELETE /chamados/anexos/{anexo_id}

Exclui um anexo.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
anexo_idintpathsimID do anexo.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Anexo removido com sucesso",
  "data": null
}

Perfil sem permissão: 403. Inexistente: 404. Escopo: chamados:write + perfil administrador ou diretoria.

GET /chamados/{chamado_id}/anexos

Lista os anexos do chamado (só metadados, sem conteudo_base64). Sem id_mensagem, traz todos os anexos do chamado; com ele, só os de uma mensagem. Sem anexos, retorna 200 OK com data: [] e a mensagem "Nenhum anexo encontrado.".

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.
id_mensagemintquerynãoRestringe aos anexos de uma mensagem.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Anexos recuperados com sucesso",
  "data": [
    {
      "id": 77,
      "id_chamado": 318,
      "id_mensagem": 903,
      "nome_arquivo": "print_documentos.png",
      "mime_type": "image/png",
      "tamanho_bytes": 184320,
      "data_hora_criacao": "2026-10-14T10:05:00"
    }
  ]
}

Chamado inexistente: 404. Escopo: chamados:read

POST /chamados/{chamado_id}/anexos

Anexa um arquivo em base64 ao chamado (anexo da abertura, sem id_mensagem) ou a uma mensagem dele. A mensagem informada precisa pertencer ao mesmo chamado. O nome do arquivo é sanitizado no servidor (componentes de caminho e caracteres fora de letras, dígitos, ., _, - e espaço são removidos ou trocados por _).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
chamado_idintpathsimID do chamado.
id_mensagemintquerynãoPrende o anexo a uma mensagem; omitido = anexo da abertura.

Corpo ChamadoAnexoCreate.

Request

{
  "nome_arquivo": "guia_das_setembro.pdf",
  "mime_type": "application/pdf",
  "conteudo_base64": "JVBERi0xLjQKJcfsj6IKNSAwIG9iago8PC9MZW5ndGggNiAwIFIv..."
}

Response 201 Created

ChamadoAnexoRead em data (sem o conteúdo), com a mensagem "Anexo enviado com sucesso".

Arquivo inválido (MIME, tamanho, base64, executável ou cota): 400 com a mensagem do motivo. Chamado inexistente, mensagem de outro chamado ou chamado concluido: 404 ("Chamado ou mensagem não encontrado, ou chamado já concluído."). Escopo: chamados:write

Limites de anexo

O servidor garante os limites abaixo independentemente do front - quem chama a API direto está sujeito às mesmas regras.

Limites de anexo

  • Tipos aceitos (allowlist): application/pdf, image/png e image/jpeg. Qualquer outro MIME é recusado.
  • Tamanho por arquivo: 5 MB, medidos no binário decodificado.
  • Quantidade: até 5 anexos por registro (abertura do chamado ou cada mensagem).
  • Cota agregada: 50 MB somando todos os anexos do chamado.
  • Assinatura de executável: conteúdo que começa como executável Windows (MZ), Linux (ELF) ou script com shebang é recusado, mesmo declarado com MIME permitido.

Schemas

ChamadoCreate

CampoTipoObrigatórioDescrição
id_clienteintsimEmpresa do chamado.
titulostrsim1 a 200 caracteres.
detalhamentostrsim1 a 20000 caracteres.
tipostrnãoVocabulário de tipos. Default problema.
id_usuario_responsavelint | nullnãoOperador responsável.

ChamadoUpdate

CampoTipoObrigatórioDescrição
titulostrnão1 a 200 caracteres.
detalhamentostrnão1 a 20000 caracteres.
tipostrnãoVocabulário de tipos.
statusstrnãoVocabulário de status.
id_usuario_responsavelint | nullnãoOperador responsável.
motivo_fechamentostr | nullnãoAté 20000 caracteres. Só junto de status: "concluido". Em branco vira null.

ChamadoRead

CampoTipoDescrição
idintNúmero do chamado.
titulostrTítulo.
detalhamentostrDescrição do chamado.
tipostrTipo.
id_clienteintEmpresa.
id_portal_userint | nullUsuário do Portal que abriu (nulo quando aberto pelo realm interno).
statusstrStatus.
id_usuario_responsavelint | nullOperador responsável.
id_usuario_fechamentoint | nullQuem concluiu.
data_hora_criacaodatetimeAbertura.
data_hora_edicaodatetime | nullÚltima edição.
data_hora_fechamentodatetime | nullConclusão.
motivo_fechamentostr | nullMotivo declarado na conclusão.
nao_lidasintMensagens do cliente não lidas pelo operador (só em GET /chamados/; default 0).
ultima_mensagem_emdatetime | nullData da última mensagem relevante (só em GET /chamados/; default null).

PaginatedChamados

CampoTipoDescrição
itemslist[ChamadoRead]Itens da página.
totalintTotal do conjunto filtrado.
total_pagesintTotal de páginas.
current_pageintPágina atual.
per_pageint | nullItens por página.

ChamadoMensagemCreate

CampoTipoObrigatórioDescrição
textostrsim1 a 20000 caracteres.
visibilidadestrnãopublica ou interna. Default interna.

ChamadoMensagemUpdate

CampoTipoObrigatórioDescrição
textostrnão1 a 20000 caracteres.
visibilidadestrnãopublica ou interna.

ChamadoMensagemRead

CampoTipoDescrição
idintID da mensagem.
id_chamadointChamado da thread.
autor_realmstrportal (cliente) ou interno (operador).
id_portal_userint | nullAutor do Portal.
id_usuarioint | nullAutor interno.
textostrConteúdo.
visibilidadestrpublica ou interna.
data_hora_criacaodatetimeEnvio.
autor_nomestr | nullPrimeiro nome do atendente - resolvido só no caminho do Portal.
autor_foto_urlstr | nullURL da foto do atendente - resolvida só no caminho do Portal.

ChamadoAnexoCreate

CampoTipoObrigatórioDescrição
nome_arquivostrsim1 a 255 caracteres (sanitizado no servidor).
mime_typestrsimapplication/pdf, image/png ou image/jpeg.
conteudo_base64strsimConteúdo do arquivo em base64.

ChamadoAnexoRead / ChamadoAnexoDownload

CampoTipoDescrição
idintID do anexo.
id_chamadointChamado.
id_mensagemint | nullMensagem à qual o anexo está preso (nulo = abertura).
nome_arquivostrNome sanitizado.
mime_typestrMIME declarado.
tamanho_bytesintTamanho do binário.
data_hora_criacaodatetimeEnvio.
conteudo_base64strSó em ChamadoAnexoDownload (GET /chamados/anexos/{anexo_id}).

ChamadoAvaliacaoRead

CampoTipoDescrição
notaint1 a 5.
comentariostr | nullComentário do cliente.
data_hora_criacaodatetimeAvaliação.
data_hora_edicaodatetime | nullÚltima alteração.

ChamadoAvaliacaoInternaCreate

CampoTipoObrigatórioDescrição
notaintsim1 a 5 (sem zero nem meia nota).
comentariostr | nullnãoAté 2000 caracteres. Em branco vira null.

Campos extras são rejeitados com 422.

ChamadoAvaliacaoInternaRead

CampoTipoDescrição
notaint1 a 5.
comentariostr | nullComentário.
id_usuariointQuem avaliou.
data_hora_criacaodatetimePrimeira gravação.
data_hora_edicaodatetime | nullÚltimo reenvio (nulo = nunca reenviada).

ChamadoAvaliacaoInternaResumo

CampoTipoDescrição
mediafloat | nullMédia com uma casa; null sem avaliação.
quantidadeintQuantidade de avaliações.

ChamadoResumoFila

CampoTipoDescrição
abertointChamados aberto.
em_andamentointChamados em_andamento.
concluidointChamados concluido.
totalintSoma dos três.

Notas

  • Consumidor: a fila interna é atendida no Hub - os comentários do código citam a faixa de abas e o badge do Hub, e as notificações de chamado apontam para a tela de atendimento do Hub.
  • Notificações: abertura de chamado e mensagem do cliente (ambas vindas do Portal) geram notificação interna best-effort no sistema hub. Chamado sem responsável notifica o time; com responsável, só ele. Mensagens de operador não notificam ninguém internamente.
  • Ordem das rotas: GET /chamados/resumo e GET /chamados/nao-lidas são declaradas antes de GET /chamados/{chamado_id} por necessidade - invertidas, o segmento literal cairia na rota dinâmica e daria 422.
  • Filtros de listagem (status, tipo) comparam o valor exato gravado no banco: use sempre o valor canônico. A normalização de grafias (fechado, em andamento, bug...) vale só nos schemas de escrita.
  • Exclusão de chamado e de anexo é restrita a administrador/diretoria. Para encerrar um atendimento, use PUT com status: "concluido".