API Reference: Membros

Base URL: /api/membros

Todos os endpoints deste modulo requerem autenticacao (AuthGuard aplicado no controller inteiro). As queries operam sobre membros_nucleos com JOIN para usuarios, suportando o modelo de multi-membership.


GET /api/membros/pendentes

Lista todos os cadastros/pedidos pendentes de aprovacao no nucleo do usuario logado. Inclui tanto cadastros novos (nucleo de origem) quanto pedidos de acesso de convidados de outros nucleos.

Permissao

COORDENADOR ou ADMINISTRADOR (AuthGuard + RolesGuard)

Response 200

[
  {
    "id": "uuid-do-usuario",
    "membershipId": "uuid-da-membership",
    "nome": "Maria Santos",
    "email": "maria@email.com",
    "cpf": "987.654.321-00",
    "telefone": "(27) 98888-8888",
    "cidade": "Vitoria",
    "criado_em": "2026-03-28T15:30:00Z",
    "is_convidado": false,
    "nucleo_origem_nome": null
  },
  {
    "id": "uuid-do-usuario-2",
    "membershipId": "uuid-da-membership-2",
    "nome": "Pedro Souza",
    "email": "pedro@email.com",
    "cpf": "111.222.333-44",
    "telefone": "(27) 97777-7777",
    "cidade": "Serra",
    "criado_em": "2026-03-29T10:00:00Z",
    "is_convidado": true,
    "nucleo_origem_nome": "MBL Vitoria"
  }
]

Campos Relevantes

CampoTipoDescricao
idstringUUID do usuario (retrocompat com frontend)
membershipIdstringUUID da linha em membros_nucleos
is_convidadobooleantrue se o usuario ja pertence a outro nucleo
nucleo_origem_nomestring | nullNome do nucleo de origem (apenas para convidados)
cidadestring | nullExtraido de endereco.cidade do usuario

GET /api/membros

Lista membros do nucleo com paginacao e filtros. Faz query via membros_nucleoscom JOIN para usuarios e planos. Para convidados, busca o nome do nucleo de origem para exibir badge.

Permissao

COORDENADOR ou ADMINISTRADOR (AuthGuard + RolesGuard)

Query Params

ParamTipoDefaultDescricao
statusstring-Filtrar por status (ATIVO, INATIVO, PENDENTE, SUSPENSO)
cargostring-Filtrar por cargo (MEMBRO, LIDER_PROJETO, PORTA_VOZ, COORDENADOR, ADMINISTRADOR)
searchstring-Busca por nome (ilike, case-insensitive via foreign table)
pagenumber1Pagina atual
limitnumber20Itens por pagina

Response 200

{
  "data": [
    {
      "id": "uuid-do-usuario",
      "membershipId": "uuid-da-membership",
      "nome": "Joao da Silva",
      "email": "joao@email.com",
      "cargo": "MEMBRO",
      "status": "ATIVO",
      "saldo_capixacoins": 1500,
      "foto_url": null,
      "criado_em": "2026-03-01T10:00:00Z",
      "plano_origem": "manual",
      "data_validade_plano": "2027-03-01T10:00:00Z",
      "planos": { "nome": "Apoiador" },
      "is_nucleo_origem": true,
      "is_convidado": false,
      "nucleo_origem_nome": null
    },
    {
      "id": "uuid-do-usuario-2",
      "membershipId": "uuid-da-membership-2",
      "nome": "Ana Costa",
      "email": "ana@email.com",
      "cargo": "MEMBRO",
      "status": "ATIVO",
      "saldo_capixacoins": 300,
      "foto_url": "https://...",
      "criado_em": "2026-03-15T08:00:00Z",
      "plano_origem": "asaas_sync",
      "data_validade_plano": "2027-03-15T08:00:00Z",
      "planos": { "nome": "Militante" },
      "is_nucleo_origem": false,
      "is_convidado": true,
      "nucleo_origem_nome": "MBL Vitoria"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 47,
    "totalPages": 3
  }
}

GET /api/membros/:id

Retorna perfil completo de um membro no contexto do nucleo atual. Busca a membership em membros_nucleos e os dados do usuario em usuarios separadamente, depois mescla os campos.

Permissao

COORDENADOR ou ADMINISTRADOR (AuthGuard + RolesGuard)

Params

:id = UUID do usuario

Response 200

{
  "id": "uuid",
  "nome": "Joao da Silva",
  "email": "joao@email.com",
  "cpf": "123.456.789-00",
  "telefone": "(27) 99999-9999",
  "data_nascimento": "1990-05-15",
  "endereco": { "cidade": "Vitoria", "estado": "ES", ... },
  "codigo_referral": "MBL-ES-X7K2",
  "foto_url": null,
  "primeiro_login": false,
  "receber_whatsapp": true,
  "criado_em": "2026-03-01T10:00:00Z",
  "usuario_competencias": [...],
  "cargo": "MEMBRO",
  "status": "ATIVO",
  "saldo_capixacoins": 1500,
  "planos": { "id": "uuid", "nome": "Apoiador", "preco_real": 29.9 },
  "plano_origem": "manual",
  "plano_atribuido_em": "2026-04-01T12:00:00Z",
  "plano_atribuido_por": "uuid-admin",
  "plano_atribuido_por_nome": "Carlos Admin",
  "plano_asaas_payment_id": null,
  "data_validade_plano": "2027-04-01T12:00:00Z",
  "is_nucleo_origem": true,
  "is_convidado": false,
  "nucleo_origem_nome": null
}

Notas

  • Os campos cargo, status, saldo_capixacoins vem da membership (nao do usuario global)
  • Para convidados, nucleo_origem_nome contem o nome do nucleo de origem
  • Campos de plano (plano_origem, plano_atribuido_*, data_validade_plano) sao por nucleo

Erros

  • 404: Membro nao encontrado neste nucleo / Usuario nao encontrado

PATCH /api/membros/:id/cargo

Altera o cargo de um membro na membership do nucleo atual (tabela membros_nucleos).

Permissao

ADMINISTRADOR (apenas)

Params

:id = UUID do usuario

Body

{ "cargo": "COORDENADOR" }

Valores aceitos

MEMBRO, LIDER_PROJETO, PORTA_VOZ, COORDENADOR, ADMINISTRADOR

Response 200

{ "message": "Cargo atualizado para COORDENADOR" }

Erros

  • 400: Cargo invalido

PATCH /api/membros/:id/status

Altera o status de um membro na membership do nucleo atual (tabela membros_nucleos).

Permissao

COORDENADOR ou ADMINISTRADOR

Params

:id = UUID do usuario

Body

{ "status": "SUSPENSO" }

Valores aceitos

ATIVO, INATIVO, SUSPENSO

Response 200

{ "message": "Status atualizado para SUSPENSO" }

Erros

  • 400: Status invalido

Para aprovar/rejeitar cadastros pendentes, use POST /api/auth/approve e POST /api/auth/reject.


POST /api/membros/:id/plano

Atribuicao manual de plano a um membro no nucleo atual. Define validade de 1 ano a partir da data de atribuicao.

Permissao

COORDENADOR ou ADMINISTRADOR

Params

:id = UUID do usuario

Body

{ "planoId": "uuid-do-plano" }

Response 200

{
  "message": "Plano Apoiador atribuido a Joao da Silva ate 01/04/2027",
  "validadeAte": "2027-04-01T12:00:00.000Z"
}

Side Effects

  • Atualiza membros_nucleos com plano_id, plano_origem='manual', plano_atribuido_em, plano_atribuido_por, data_validade_plano
  • Notificacao enviada ao usuario informando o novo plano e validade

Erros

  • 404: Plano nao encontrado / Membro nao encontrado neste nucleo
  • 400: Plano nao pertence a este nucleo

POST /api/membros/sync-planos-asaas

Trigger manual para sincronizar planos com o Asaas. Busca pagamentos confirmados nos ultimos N dias (default 7) e casa com membros do nucleo via CPF/email. Se o valor bater exatamente com um plano, atribui automaticamente com plano_origem='asaas_sync'.

Permissao

COORDENADOR ou ADMINISTRADOR

Body (opcional)

{ "dias": 30 }

Response 200

{
  "atribuidos": 5,
  "ignorados": 12,
  "detalhes": [...]
}

Notas

  • Tambem roda automaticamente via CRON as 3h da manha (todos os nucleos com Asaas configurado)
  • O nucleo precisa ter asaas_api_key configurado

POST /api/membros/rebuild-financeiro-asaas

Rebuild completo dos lancamentos financeiros a partir dos pagamentos registrados. Agrupa parcelas, filtra pagamentos de teste e futuros.

Permissao

COORDENADOR ou ADMINISTRADOR

Body (opcional)

{
  "dias": 90,
  "ignorarTestes": true
}
CampoTipoDefaultDescricao
diasnumber-Periodo em dias para buscar pagamentos
ignorarTestesbooleantrueSe deve ignorar pagamentos de teste

Response 200

Retorna relatorio com totais reconstruidos.


POST /api/membros/limpar-lancamentos-sync-asaas

Limpa todos os lancamentos marcados com origem sync_asaas do nucleo. Operacao destrutiva para reprocessamento.

Permissao

ADMINISTRADOR (apenas)

Body

Nenhum (nucleoId extraido do token).

Response 200

Retorna contagem de lancamentos removidos.