Logo

Grupos e Permissões - Endpoints

Referência completa dos endpoints de grupos e sistema RBAC do Sinapse

Endpoints de Grupos e Permissões

O sistema de grupos e permissões (RBAC - Role-Based Access Control) do Sinapse permite gerenciar acessos de forma granular e escalável.

Conceitos Fundamentais

Hierarquia de Permissões

Usuário
  ├── Grupos (múltiplos)
  │   └── Permissões do Grupo
  └── Permissões Diretas
      
Permissões Efetivas = Grupos + Diretas + Admin

Grupos Padrão

GrupoDescriçãoPermissões Típicas
adminAdministradoresAcesso total
gestorGestores de equipeGerenciar usuários e recursos
analistaAnalistas de dadosCriar e analisar dados
usuarioUsuário padrãoAcesso básico
visualizadorApenas leituraVisualizar dados

Listar Grupos

Lista todos os grupos disponíveis no sistema.

GET /api/v1/grupos
Authorization: Bearer {access_token}

Query Parameters:

ParâmetroTipoDescrição
pageintegerNúmero da página (padrão: 1)
sizeintegerItens por página (padrão: 50)
searchstringBuscar por nome ou descrição
ativobooleanFiltrar por status
sortstringCampo para ordenação [Em breve]
orderstringDireção: asc, desc [Em breve]

Permissão necessária: grupos.listar

Success Response (200):

{
  "total": 10,
  "page": 1,
  "size": 50,
  "pages": 1,
  "grupos": [
    {
      "id": 1,
      "nome": "admin",
      "descricao": "Administradores do sistema",
      "ativo": true,
      "criado_em": "2025-01-01T10:00:00-03:00",
      "atualizado_em": "2025-07-29T14:30:00-03:00",
      "total_usuarios": 5,
      "permissoes": [
        {
          "id": 1,
          "nome": "admin",
          "descricao": "Acesso administrativo total"
        }
      ]
    },
    {
      "id": 2,
      "nome": "gestor",
      "descricao": "Gestores de equipe",
      "ativo": true,
      "total_usuarios": 20,
      "permissoes": [
        {
          "id": 10,
          "nome": "usuarios.listar",
          "descricao": "Listar usuários"
        },
        {
          "id": 11,
          "nome": "usuarios.criar",
          "descricao": "Criar usuários"
        }
      ]
    }
  ]
}

Python - Listar Grupos com Detalhes:

import requests

def listar_grupos_detalhados(token):
    headers = {"Authorization": f"Bearer {token}"}
    
    response = requests.get(
        "https://api.sinapse.org.br/v1/grupos",
        headers=headers,
        params={"size": 100}
    )
    
    if response.status_code == 200:
        grupos = response.json()
        
        print(f"Total de grupos: {grupos['total']}")
        print("\nResumo de Grupos:")
        print("-" * 60)
        
        for grupo in grupos['items']:
            print(f"\n{grupo['nome'].upper()}")
            print(f"  Descrição: {grupo['descricao']}")
            print(f"  Usuários: {grupo['usuarios_count']}")
            print(f"  Permissões: {grupo['permissoes_count']}")
            
            if grupo['permissoes_count'] <= 5:
                # Mostrar permissões se poucas
                for perm in grupo['permissoes']:
                    print(f"    - {perm['nome']}")
        
        return grupos['items']

JavaScript - Buscar Grupo Específico:

async function buscarGrupoPorNome(nome) {
  const response = await fetch(
    `/api/v1/grupos?nome=${encodeURIComponent(nome)}`,
    {
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    }
  );
  
  if (response.ok) {
    const dados = await response.json();
    return dados.items.find(g => g.nome === nome);
  }
  
  return null;
}

// Uso
const grupoAnalista = await buscarGrupoPorNome('analista');
console.log(`Grupo tem ${grupoAnalista.usuarios_count} usuários`);

Criar Grupo

Cria um novo grupo no sistema.

POST /api/v1/grupos
Authorization: Bearer {access_token}
Content-Type: application/json

Body Parameters:

{
  "nome": "coordenadores",
  "descricao": "Coordenadores regionais de saúde",
  "ativo": true,
  "permissoes_ids": [10, 11, 20, 21, 30]
}

Validações:

  • Nome único no sistema
  • Nome deve ser lowercase, sem espaços
  • Permissões devem existir

Permissão necessária: grupos.criar

Success Response (201):

{
  "id": 6,
  "nome": "coordenadores",
  "descricao": "Coordenadores regionais de saúde",
  "ativo": true,
  "criado_em": "2025-07-29T15:00:00-03:00",
  "permissoes": [
    {
      "id": 10,
      "nome": "usuarios.listar"
    },
    {
      "id": 11,
      "nome": "usuarios.criar"
    }
  ],
  "mensagem": "Grupo criado com sucesso"
}

Error Response (422):

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Dados inválidos",
    "details": [
      {
        "field": "nome",
        "message": "Grupo com este nome já existe"
      },
      {
        "field": "permissoes_ids",
        "message": "Permissões inválidas: [99, 100]"
      }
    ]
  }
}

Criar Perfis de Acesso Customizados:

def criar_perfil_epidemiologista():
    """Cria grupo com permissões específicas para epidemiologistas"""
    
    # Definir permissões necessárias
    permissoes_epidemio = [
        "agravos.listar",
        "agravos.criar",
        "agravos.editar",
        "agravos.exportar",
        "relatorios.gerar",
        "relatorios.exportar",
        "noticias.listar",
        "dashboard.visualizar"
    ]
    
    # Buscar IDs das permissões
    permissoes_ids = []
    for perm_nome in permissoes_epidemio:
        perm = buscar_permissao_por_nome(perm_nome)
        if perm:
            permissoes_ids.append(perm['id'])
    
    # Criar grupo
    novo_grupo = {
        "nome": "epidemiologista",
        "descricao": "Profissionais de epidemiologia com acesso a dados de agravos",
        "ativo": True,
        "permissoes_ids": permissoes_ids
    }
    
    response = requests.post(
        f"{base_url}/grupos",
        headers=headers,
        json=novo_grupo
    )
    
    if response.status_code == 201:
        grupo = response.json()
        print(f"Grupo '{grupo['nome']}' criado com {len(permissoes_ids)} permissões")
        return grupo
    else:
        print(f"Erro ao criar grupo: {response.json()}")
        return None

Atualizar Grupo

Atualiza informações e permissões de um grupo.

PUT /api/v1/grupos/{id}
Authorization: Bearer {access_token}
Content-Type: application/json

Body Parameters:

{
  "descricao": "Coordenadores regionais e estaduais de saúde",
  "ativo": true
}

Campos especiais:

  • nome: Pode ser alterado (deve ser único)
  • permissoes_ids: Atualiza todas as permissões do grupo

Permissão necessária: grupos.editar

Success Response (200):

{
  "id": 6,
  "message": "Grupo atualizado com sucesso",
  "total_usuarios": 15
}

Deletar Grupo

Remove um grupo do sistema.

DELETE /api/v1/grupos/{id}
Authorization: Bearer {access_token}

Query Parameters:

ParâmetroTipoDescrição
transferir_usuariosintegerID do grupo para transferir usuários [Em breve]
forcebooleanForçar exclusão mesmo com usuários [Em breve]

Permissão necessária: grupos.deletar

Success Response (204):

Sem conteúdo

Nota: Atualmente, grupos com usuários não podem ser deletados.

Gerenciar Membros do Grupo

Adicionar Usuário ao Grupo

POST /api/v1/grupos/{grupo_id}/usuarios/{usuario_id}
Authorization: Bearer {access_token}

Permissão: usuarios.gerenciar_permissoes

Remover Usuário do Grupo

DELETE /api/v1/grupos/{grupo_id}/usuarios/{usuario_id}
Authorization: Bearer {access_token}

Listar Usuários do Grupo [Em breve]

GET /api/v1/grupos/{grupo_id}/usuarios
Authorization: Bearer {access_token}

Adicionar Múltiplos Usuários

def adicionar_usuarios_em_lote(grupo_id, usuarios_ids):
    """Adiciona múltiplos usuários a um grupo"""
    
    resultados = {
        "sucesso": [],
        "erros": []
    }
    
    for user_id in usuarios_ids:
        try:
            response = requests.post(
                f"{base_url}/grupos/{grupo_id}/usuarios/{user_id}",
                headers=headers
            )
            
            if response.status_code == 200:
                resultados["sucesso"].append(user_id)
            else:
                resultados["erros"].append({
                    "user_id": user_id,
                    "erro": response.json().get("error", "Erro desconhecido")
                })
        except Exception as e:
            resultados["erros"].append({
                "user_id": user_id,
                "erro": str(e)
            })
    
    print(f"Adicionados: {len(resultados['sucesso'])}")
    print(f"Erros: {len(resultados['erros'])}")
    
    return resultados

Gerenciar Permissões do Grupo

Atualizar Permissões

Para atualizar as permissões de um grupo, use o endpoint PUT do grupo incluindo o campo permissoes_ids:

PUT /api/v1/grupos/{grupo_id}
Content-Type: application/json

{
  "permissoes_ids": [10, 11, 12, 20, 21]
}

Nota: Endpoints individuais para adicionar/remover permissões [Em breve].

Exemplo: Clonar Permissões

async function clonarPermissoes(grupoOrigemId, grupoDestinoId) {
  // 1. Buscar permissões do grupo origem
  const origem = await fetch(`/api/v1/grupos/${grupoOrigemId}`, {
    headers: { 'Authorization': `Bearer ${token}` }
  }).then(r => r.json());
  
  const permissoesIds = origem.permissoes.map(p => p.id);
  
  // 2. Aplicar ao grupo destino
  const response = await fetch(
    `/api/v1/grupos/${grupoDestinoId}/permissoes`,
    {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ permissoes_ids: permissoesIds })
    }
  );
  
  if (response.ok) {
    console.log(`${permissoesIds.length} permissões clonadas com sucesso`);
  }
}

Listar Permissões Disponíveis [Em breve]

Lista todas as permissões do sistema.

GET /api/v1/permissoes
Authorization: Bearer {access_token}

Response:

{
  "total": 50,
  "categorias": {
    "usuarios": [
      {
        "id": 10,
        "nome": "usuarios.listar",
        "descricao": "Visualizar lista de usuários",
        "categoria": "usuarios"
      },
      {
        "id": 11,
        "nome": "usuarios.criar",
        "descricao": "Criar novos usuários",
        "categoria": "usuarios"
      }
    ],
    "agravos": [
      {
        "id": 20,
        "nome": "agravos.listar",
        "descricao": "Visualizar casos de agravos",
        "categoria": "agravos"
      }
    ]
  }
}

Casos de Uso Práticos

1. Criar Estrutura de Permissões Regional

def criar_estrutura_regional(estado, municipios):
    """Cria grupos para gestão regional de saúde"""
    
    # 1. Criar grupo estadual
    grupo_estado = criar_grupo({
        "nome": f"gestor_{estado.lower()}",
        "descricao": f"Gestores estaduais de {estado}",
        "permissoes_ids": obter_permissoes_gestao_estadual()
    })
    
    # 2. Criar grupos municipais
    grupos_municipios = []
    for municipio in municipios:
        grupo_mun = criar_grupo({
            "nome": f"equipe_{municipio.lower().replace(' ', '_')}",
            "descricao": f"Equipe de saúde de {municipio}",
            "permissoes_ids": obter_permissoes_equipe_municipal()
        })
        grupos_municipios.append(grupo_mun)
    
    # 3. Criar hierarquia (se suportado)
    for grupo_mun in grupos_municipios:
        vincular_grupo_superior(grupo_mun['id'], grupo_estado['id'])
    
    return {
        "estado": grupo_estado,
        "municipios": grupos_municipios
    }

2. Auditoria de Permissões

async function auditarPermissoesGrupo(grupoId) {
  const grupo = await fetch(`/api/v1/grupos/${grupoId}`, {
    headers: { 'Authorization': `Bearer ${token}` }
  }).then(r => r.json());
  
  const usuarios = await fetch(`/api/v1/grupos/${grupoId}/usuarios`, {
    headers: { 'Authorization': `Bearer ${token}` }
  }).then(r => r.json());
  
  // Análise de riscos
  const permissoesAltoRisco = [
    'usuarios.deletar',
    'grupos.deletar',
    'admin'
  ];
  
  const riscos = grupo.permissoes
    .filter(p => permissoesAltoRisco.includes(p.nome))
    .map(p => ({
      permissao: p.nome,
      usuarios_afetados: usuarios.total
    }));
  
  if (riscos.length > 0) {
    console.warn('Permissões de alto risco detectadas:');
    console.table(riscos);
  }
  
  return {
    grupo: grupo.nome,
    total_usuarios: usuarios.total,
    total_permissoes: grupo.permissoes.length,
    riscos: riscos
  };
}

Perguntas Frequentes

Próximos Passos

On this page