Users

Endpoints da WebApiAlcance para a gestão de usuários - os operadores internos da Alcance Contabilidade (funcionários, responsáveis por carteiras, gestão). Cobrem listagem geral, detalhamento por ID, criação, atualização e exclusão. Para os dados do usuário autenticado, use GET /auth/me (ver Auth).

Todos os endpoints exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs.

Domínio sensível - nunca exponha ao MCP

Gestão de usuários lida com credenciais e privilégios de acesso. As operações de escrita (criar, atualizar, excluir) têm um guard de perfil próprio, além do escopo (ver Notas). Esse domínio não deve ser exposto ao gateway MCP nem a clientes IA.

Base path

/api/v1/users

Escopos necessários

  • users:read - listagem e detalhamento
  • users:write - criação, atualização e exclusão

O escopo é derivado da rota: o prefixo /users vira o recurso users, e o método HTTP define a ação (read para GET, write para POST/PUT/DELETE).

Escopo não é suficiente para escrita

Ter users:write não basta para mutar usuários. As rotas POST, PUT e DELETE exigem adicionalmente que o usuário autenticado tenha perfil administrador ou diretoria (require_perfil). Perfil funcionario recebe 403 Forbidden ao tentar criar, editar ou excluir usuários.

Endpoints

GET /users/me foi removida

A rota GET /users/me foi removida da WebApiAlcance. A identidade do usuário autenticado no realm interno é servida exclusivamente por GET /auth/me (ver Auth), que devolve o mesmo tipo de dado (incluindo grupo, username, sub, exp e imagem_perfil) sem exigir o escopo users:read - use-a no lugar desta rota.

POST /users/

Cria um novo usuário no sistema. Além do escopo, exige perfil de gestão (administrador ou diretoria).

Parâmetros

Este endpoint não recebe parâmetros de rota ou query - os dados vão no corpo da requisição (UserCreate): nome, email, login, grupo, telefone e senha (obrigatórios), além de cargo, setor, ativo, role e perfil (opcionais).

Request

{
  "nome": "João Lima",
  "email": "joao.lima@alcancecontabilidade.com.br",
  "login": "joao.lima",
  "grupo": "Operações",
  "telefone": "71988887777",
  "cargo": "Assistente",
  "setor": "Contábil",
  "senha": "SenhaForte123"
}

Response 201 Created

{
  "success": true,
  "message": "Usuário criado com sucesso",
  "data": {
    "id": 42,
    "nome": "João Lima",
    "email": "joao.lima@alcancecontabilidade.com.br",
    "login": "joao.lima",
    "grupo": "Operações",
    "telefone": "71988887777",
    "cargo": "Assistente",
    "setor": "Contábil",
    "ativo": "1",
    "role": "user",
    "perfil": "funcionario"
  }
}

Erros de validação de regra de negócio retornam o envelope de erro (success: false).

Escopo: users:write + perfil administrador ou diretoria

GET /users/

Lista todos os usuários cadastrados no sistema. Lista vazia é um estado válido - retorna 200 OK com data: [] e a mensagem "Nenhum usuário encontrado.".

Parâmetros

Este endpoint não recebe parâmetros de rota ou query.

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Lista de usuários recuperada com sucesso",
  "data": [
    { "id": 1, "nome": "Administrador", "login": "admin", "perfil": "administrador" },
    { "id": 7, "nome": "Maria Souza", "login": "maria.souza", "perfil": "funcionario" }
  ]
}

Escopo: users:read

GET /users/{user_id}

Detalha um usuário pelo ID inteiro. O data é um UserRead.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
user_idintpathsimID interno do usuário

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Usuário encontrado com sucesso",
  "data": {
    "id": 7,
    "nome": "Maria Souza",
    "email": "maria.souza@alcancecontabilidade.com.br",
    "login": "maria.souza",
    "grupo": "Operações",
    "telefone": "71999998888",
    "cargo": "Analista Contábil",
    "setor": "Fiscal",
    "ativo": "1",
    "role": "user",
    "perfil": "funcionario"
  }
}

Quando não encontrado, retorna o envelope de erro com message: "Usuário não encontrado.".

Escopo: users:read

PUT /users/{user_id}

Atualiza um usuário existente. O body é um UserUpdate com campos parciais - somente o que vier preenchido é alterado. Além do escopo, exige perfil de gestão (administrador ou diretoria).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
user_idintpathsimID do usuário

Request (UserUpdate - todos os campos opcionais, incluindo senha, role e perfil)

{
  "cargo": "Analista Sênior",
  "setor": "Fiscal",
  "ativo": "1"
}

Response 200 OK

{
  "success": true,
  "message": "Usuário atualizado com sucesso",
  "data": {
    "id": 7,
    "nome": "Maria Souza",
    "email": "maria.souza@alcancecontabilidade.com.br",
    "login": "maria.souza",
    "grupo": "Operações",
    "telefone": "71999998888",
    "cargo": "Analista Sênior",
    "setor": "Fiscal",
    "ativo": "1",
    "role": "user",
    "perfil": "funcionario"
  }
}

Escopo: users:write + perfil administrador ou diretoria

DELETE /users/{user_id}

Remove um usuário do sistema. Operação sensível e destrutiva. Além do escopo, exige perfil de gestão (administrador ou diretoria).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
user_idintpathsimID do usuário

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Usuário deletado com sucesso"
}

Guard de perfil na exclusão

Além do escopo users:write, este endpoint exige perfil administrador ou diretoria (require_perfil). Exclusão de usuário nunca deve ser exposta ao MCP nem a clientes IA.

Escopo: users:write + perfil administrador ou diretoria

Schemas

UserCreate

Estende UserBase acrescentando senha.

CampoTipoObrigatórioObservações
nomestrsimNome completo do usuário.
emailEmailStrsimE-mail válido (validação estrita na escrita).
loginstrsimLogin de acesso.
grupostrsimGrupo/equipe do usuário.
telefonestrsimTelefone de contato.
senhastrsimSenha em texto. Nunca é retornada em respostas - ver Notas.
cargostrnãoCargo. Opcional.
setorstrnãoSetor. Opcional.
ativostrnãoSituação do usuário. Opcional.
rolestrnãoPapel legado. Default "user". Só concede acesso total quando vale exatamente "admin".
perfilPerfilUsuarionãoPrimitiva RBAC (ex.: administrador, diretoria, funcionario). Default não-privilegiado.

UserUpdate

Todos os campos são opcionais; apenas os enviados são atualizados.

CampoTipoObservações
nomestrNovo nome.
emailEmailStrNovo e-mail (validação estrita na escrita).
senhastrNova senha. Nunca retornada em respostas.
loginstrNovo login.
grupostrNovo grupo.
telefonestrNovo telefone.
cargostrNovo cargo.
setorstrNovo setor.
ativostrNova situação.
rolestrNovo papel legado.
perfilPerfilUsuarioNovo perfil RBAC.

UserRead

Estende UserBase acrescentando id. Não inclui senha - o campo simplesmente não existe no schema de leitura.

CampoTipoNotas
idintIdentificador do usuário.
nomestrNome completo.
emailstrE-mail. Na leitura é str (tolerante) e não EmailStr - ver Notas.
loginstrLogin de acesso.
grupostrGrupo/equipe.
telefonestrTelefone de contato.
cargostr | nullCargo, quando informado.
setorstr | nullSetor, quando informado.
ativostr | nullSituação do usuário.
rolestr | nullPapel legado.
perfilPerfilUsuarioPerfil RBAC do usuário.

Notas

Senha nunca é retornada

senha existe apenas nos schemas de escrita (UserCreate, UserUpdate). O schema de leitura UserRead não possui o campo - nenhum endpoint devolve senha, hash ou credencial em texto. Não há campo de credencial no envelope de resposta.

Escrita exige perfil de gestão

As rotas POST /users/, PUT /users/{user_id} e DELETE /users/{user_id} têm o guard require_perfil("administrador", "diretoria"). Perfil funcionario (ou qualquer não-gestão) recebe 403 Forbidden, mesmo com o escopo users:write. A leitura (GET) segue liberada para qualquer usuário autenticado com users:read.

Validação de e-mail assimétrica

Na escrita o email é EmailStr (validação estrita). Na leitura UserRead.email é apenas str: dados legados com domínios reservados (ex.: .local de usuários de QA) não derrubam a listagem inteira com 500. A validação rígida fica na fronteira de escrita, onde importa.

role vs. perfil (RBAC)

perfil é a primitiva RBAC atual (default não-privilegiado). role é legado e só concede acesso total quando vale exatamente "admin". O default de role é "user" justamente para evitar escalada silenciosa de privilégios em usuários criados sem role explícito.

  • Toda resposta segue o envelope { success, message, data } (ou { success: false, message, details } em erro).
  • Para os dados do usuário autenticado, use GET /auth/me - GET /users/me foi removida. Veja Auth.