portal-modumfiscal-web/docs/api-backend.md
gabrielb 6635030d53 feat: mock system + documentação de API
- `src/mocks/mockInterceptor.js` — interceptor Axios que substitui chamadas HTTP
  por dados falsos (400–800ms de latência simulada). Cobre todos os endpoints do
  portal: certidão, IPTU, primeiro acesso, credenciamento, painel, débitos,
  certidões, alvarás, pagamentos e dados cadastrais.
- `src/main.js` — carrega mock condicionalmente via `VITE_USE_MOCK=true`; em modo
  mock, pula `bootstrapPrefeitura` e injeta sessão fake no authStore.
- `.env.development` — documenta a variável `VITE_USE_MOCK` como template.
- `docs/api-backend.md` — especificação completa de todos os endpoints necessários
  (request/response, tipos, status possíveis, tabela de implementação).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 01:14:00 -03:00

15 KiB

API Backend — portal-modumfiscal-web

Documentação dos endpoints que o portal consome. Base URL: https://sistema.modumfiscal.com.br/api/v1.

Envelope padrão de resposta (sucesso):

{
  "timestamp": "2025-05-18T10:00:00Z",
  "statusCode": 200,
  "responseType": "SUCCESS",
  "message": "OK",
  "data": { }
}

Envelope de erro:

{
  "statusCode": 422,
  "message": "Unprocessable Entity",
  "internalCode": "119",
  "description": "Registro não foi encontrado."
}

Respostas binárias (PDF) retornam Content-Type: application/pdf direto — sem envelope.


Módulo Público — sem autenticação

Headers obrigatórios em toda requisição:

  • X-Municipio: <id_municipio>
  • X-Dominio: <subdominio>

Prefeitura (bootstrap)

GET /publico/prefeitura/{dominio}

Retorna a configuração visual e institucional da prefeitura.

Response data:

{
  "idMunicipio": 1,
  "nomePrefeitura": "Prefeitura Municipal de Tutóia",
  "nomeMunicipio": "Tutóia",
  "uf": "MA",
  "template": "tutoia",
  "pathLogo": "/logos/tutoia.png",
  "pathBackground": "/backgrounds/tutoia.jpeg",
  "corPrimaria": "#F59E0B",
  "cnpj": "12.345.678/0001-90",
  "site": "https://tutoia.ma.gov.br",
  "email": "atendimento@tutoia.ma.gov.br",
  "telefone": "(98) 3478-1234"
}

pathLogo e pathBackground são paths relativos — o frontend resolve para URL absoluta via resolverUrl().


Certidão Pública

GET /publico/certidao/consultar

Consulta a situação fiscal do contribuinte.

Query params:

Param Tipo Obrigatório Descrição
documento string sim CPF (11 dígitos) ou CNPJ (14 dígitos) sem formatação

Response data:

{
  "situacao": "NEGATIVA",
  "nomeContribuinte": "João da Silva Santos"
}

situacao possíveis: NEGATIVA · POSITIVA · POSITIVA_EFEITOS_NEGATIVA


GET /publico/certidao/emitir

Emite a certidão em PDF.

Query params:

Param Tipo Obrigatório Descrição
documento string sim CPF/CNPJ sem formatação
tipoCertidao string sim NEGATIVA · POSITIVA · POSITIVA_EFEITOS_NEGATIVA

Response: application/pdf (binário direto, sem envelope)


IPTU Público

GET /publico/iptu/consultar

Retorna todos os imóveis e débitos de IPTU do contribuinte ou de uma inscrição específica.

Query params:

Param Tipo Obrigatório Descrição
documento string condicional CPF/CNPJ sem formatação (informar documento ou inscricao)
inscricao string condicional Inscrição imobiliária (ex: 0001.001.0001.001)

Response data:

{
  "content": [
    {
      "inscricaoImobiliaria": "0001.001.0001.001",
      "enderecoCompleto": "Rua das Flores, 100 — Centro",
      "debitos": [
        {
          "id": "d1",
          "descricao": "IPTU 2025 — Cota 4/10",
          "vencimento": "30/04/2025",
          "valor": 125.90,
          "valorAtualizado": 138.49,
          "status": "VENCIDO"
        }
      ]
    }
  ]
}

status possíveis: VENCIDO · A_VENCER · PAGO · PARCELADO


GET /publico/iptu/carne

Emite o carnê completo de IPTU em PDF.

Query params:

Param Tipo Obrigatório Descrição
inscricao string sim Inscrição imobiliária

Response: application/pdf


GET /publico/iptu/boleto

Emite o boleto avulso de uma parcela.

Query params:

Param Tipo Obrigatório Descrição
idDebito string sim ID do débito retornado por /consultar

Response: application/pdf


Primeiro Acesso

Fluxo de 4 etapas para o contribuinte criar senha de acesso ao portal.

GET /publico/primeiro-acesso/verificar

Valida se o documento tem cadastro e retorna os canais disponíveis para envio do código.

Query params:

Param Tipo Obrigatório
documento string sim

Response data:

{
  "nome": "Maria Aparecida Santos",
  "canais": [
    { "tipo": "EMAIL",    "valor": "ma***@gmail.com" },
    { "tipo": "WHATSAPP", "valor": "(98) *****-8901" },
    { "tipo": "SMS",      "valor": "(98) *****-8901" }
  ]
}

tipo possíveis: EMAIL · WHATSAPP · SMS


POST /publico/primeiro-acesso/codigo

Envia o código de 6 dígitos para o canal escolhido.

Request body:

{
  "documento": "12345678900",
  "canal": "EMAIL"
}

Response data:

{ "enviado": true }

POST /publico/primeiro-acesso/validar

Valida o código digitado e retorna um token temporário para definição de senha.

Request body:

{
  "documento": "12345678900",
  "codigo": "123456"
}

Response data:

{ "token": "eyJhb..." }

Erros: 422 se código inválido ou expirado.


POST /publico/primeiro-acesso/senha

Define a nova senha usando o token temporário.

Request body:

{
  "token": "eyJhb...",
  "senha": "MinhaS3nha!"
}

Response data:

{ "sucesso": true }

Credenciamento

Fluxo para novo contribuinte solicitar cadastro no sistema.

GET /publico/credenciamento/verificar

Verifica se o documento já tem cadastro ou pode ser credenciado.

Query params:

Param Tipo Obrigatório
documento string sim

Response data:

{ "situacao": "APTO" }

situacao possíveis:

  • APTO — pode prosseguir com o credenciamento
  • JA_CREDENCIADO — já tem acesso ao sistema
  • BLOQUEADO — documento bloqueado (contatar prefeitura)

GET /publico/cep/{cep}

Busca endereço por CEP para auto-preenchimento no formulário de credenciamento.

Path param: cep — 8 dígitos sem hífen

Response data:

{
  "logradouro": "Rua das Acácias",
  "bairro": "Centro",
  "localidade": "Tutóia",
  "uf": "MA"
}

POST /publico/credenciamento/solicitar

Envia a solicitação de credenciamento para análise da prefeitura.

Request body (Pessoa Física):

{
  "documento": "12345678900",
  "tipoPessoa": "FISICA",
  "nomeCompleto": "João da Silva Santos",
  "dataNascimento": "1990-05-15",
  "email": "joao@email.com",
  "emailConfirmacao": "joao@email.com",
  "telefone": "98991234567",
  "whatsapp": true,
  "endereco": {
    "cep": "65900000",
    "logradouro": "Rua das Flores",
    "numero": "100",
    "complemento": "Apto 201",
    "bairro": "Centro",
    "cidade": "Tutóia",
    "uf": "MA"
  }
}

Request body adicional (Pessoa Jurídica):

{
  "tipoPessoa": "JURIDICA",
  "razaoSocial": "Empresa LTDA",
  "nomeFantasia": "Empresa",
  "inscricaoEstadual": "12345678",
  "representanteLegal": {
    "nomeCompleto": "João da Silva",
    "cpf": "12345678900",
    "cargo": "Diretor"
  }
}

Response data:

{ "protocolo": "CRED-2025-00123" }

Módulo Portal — requer autenticação

Header obrigatório além dos de tenant:

  • Authorization: Bearer <jwt_keycloak>

Painel

GET /contribuinte/painel/resumo

Dados do card de resumo do dashboard.

Response data:

{
  "totalDebitos": 1250.90,
  "certidoesAtivas": 2,
  "alvarasAndamento": 2,
  "ultimoPagamento": 430.00,
  "debitosVencidos": 1
}

GET /contribuinte/painel/atividades

Lista das últimas atividades do contribuinte.

Response data:

{
  "content": [
    {
      "tipo": "PAGAMENTO",
      "descricao": "IPTU 2025 — Parcela 3/10 paga",
      "data": "15/05/2025"
    },
    {
      "tipo": "CERTIDAO",
      "descricao": "Certidão Negativa emitida",
      "data": "10/05/2025"
    }
  ]
}

tipo possíveis: PAGAMENTO · CERTIDAO · DEBITO · ALVARA · CADASTRO


Débitos

GET /contribuinte/debitos

Lista os débitos do contribuinte com filtros opcionais.

Query params:

Param Tipo Obrigatório Descrição
tipo string não IPTU · ISS · TAXA · MULTA
status string não VENCIDO · A_VENCER · PARCELADO

Response data:

{
  "content": [
    {
      "id": "deb1",
      "descricao": "IPTU 2025 — Cota 4/10",
      "tipo": "IPTU",
      "referencia": "ABR/2025",
      "vencimento": "30/04/2025",
      "valor": 125.90,
      "valorAtualizado": 138.49,
      "status": "VENCIDO"
    }
  ]
}

valorAtualizado inclui juros e multa (pode ser igual a valor se em dia).


GET /contribuinte/debitos/{id}/guia

Emite a guia de pagamento (boleto/DAM) de um débito específico em PDF.

Path param: id — ID do débito

Response: application/pdf


Certidões

GET /contribuinte/certidoes

Lista todas as certidões emitidas pelo contribuinte.

Response data:

{
  "content": [
    {
      "id": "cert1",
      "tipo": "Certidão Negativa de Débitos",
      "numero": "CN-2025-00481",
      "dataEmissao": "10/05/2025",
      "dataValidade": "07/11/2025",
      "status": "ATIVA"
    }
  ]
}

status possíveis: ATIVA · VENCIDA · CANCELADA


GET /contribuinte/certidoes/{id}/pdf

Reemite uma certidão em PDF.

Path param: id — ID da certidão

Response: application/pdf

Retorna 422 se a certidão estiver com status CANCELADA.


Alvarás

GET /contribuinte/alvaras

Lista os processos de alvará do contribuinte.

Query params:

Param Tipo Obrigatório Descrição
status string não Filtro por status do processo

Response data:

{
  "content": [
    {
      "id": "alv1",
      "tipo": "Alvará de Funcionamento — Comércio Varejista",
      "numeroProcesso": "ALV-2025-00342",
      "status": "EM_ANALISE",
      "ultimaAtualizacao": "14/05/2025",
      "etapas": [
        { "nome": "Protocolo", "concluida": true,  "atual": false },
        { "nome": "Análise",   "concluida": false, "atual": true  },
        { "nome": "Vistoria",  "concluida": false, "atual": false },
        { "nome": "Emissão",   "concluida": false, "atual": false }
      ]
    }
  ]
}

status possíveis: EM_ANALISE · AGUARDANDO_DOCUMENTOS · DEFERIDO · INDEFERIDO · CANCELADO


Pagamentos

GET /contribuinte/pagamentos

Histórico de pagamentos do contribuinte, filtrável por ano.

Query params:

Param Tipo Obrigatório Descrição
ano integer não Ano de referência (padrão: ano atual)

Response data:

{
  "content": [
    {
      "id": "pag1",
      "descricao": "IPTU 2025 — Cota 3/10",
      "referencia": "MAR/2025",
      "dataPagamento": "28/03/2025",
      "formaPagamento": "PIX",
      "valor": 125.90
    }
  ]
}

formaPagamento possíveis: BOLETO · PIX · CARTAO · TRANSFERENCIA · ESPECIE


GET /contribuinte/pagamentos/{id}/comprovante

Baixa o comprovante de um pagamento em PDF.

Path param: id — ID do pagamento

Response: application/pdf


Dados Cadastrais

GET /contribuinte/dados

Retorna os dados cadastrais completos do contribuinte autenticado.

Response data (Pessoa Física):

{
  "tipoPessoa": "FISICA",
  "documento": "123.456.789-00",
  "nomeCompleto": "João da Silva Santos",
  "dataNascimento": "15/06/1975",
  "email": "joao.santos@email.com",
  "telefone": "(98) 99123-4567",
  "whatsapp": true,
  "endereco": {
    "cep": "65900-000",
    "logradouro": "Rua das Flores",
    "numero": "100",
    "complemento": "Apto 201",
    "bairro": "Centro",
    "cidade": "Tutóia",
    "uf": "MA"
  }
}

Campos adicionais (Pessoa Jurídica):

{
  "tipoPessoa": "JURIDICA",
  "documento": "12.345.678/0001-90",
  "razaoSocial": "Empresa LTDA",
  "nomeFantasia": "Empresa",
  "inscricaoEstadual": "12345678"
}

PUT /contribuinte/dados/contato

Atualiza os dados de contato editáveis (email, telefone, WhatsApp).

Request body:

{
  "email": "novo@email.com",
  "telefone": "98991234567",
  "whatsapp": true
}

telefone deve ser enviado sem formatação (apenas dígitos).

Response data:

{ "atualizado": true }

Avisos (pendente no backend)

GET /publico/avisos/{dominio}

Retorna os avisos/banners exibidos no carousel da Home.

Status: endpoint ainda não implementado no backend. O frontend usa dados estáticos hardcoded em HomeView.vue.

Response data esperada:

{
  "content": [
    {
      "id": "av1",
      "titulo": "IPTU 2025 — Prazo final",
      "descricao": "Últimas parcelas com desconto até 30 de junho.",
      "tipo": "ALERTA",
      "ativo": true
    }
  ]
}

tipo sugeridos: INFO · ALERTA · URGENTE


Fluxo de Autenticação

O portal usa Keycloak PKCE — nenhuma credencial trafega pelo frontend.

1. Usuário informa CPF/CNPJ na Home
2. LoginView monta — exibe doc mascarado + campo senha
3. entrar() → redireciona para Keycloak (PKCE code challenge)
4. Keycloak autentica e redireciona de volta com ?code=
5. authService troca code por access_token + refresh_token
6. authStore.setSession(token, userInfo) persiste sessão
7. router.push({ name: 'painel' })

Realm: modumfiscal-dev Client ID: portal-modumfiscal-web Grant type: authorization_code com PKCE (S256) Token endpoint: https://keycloakprod.modumfiscal.com.br/realms/modumfiscal-dev/protocol/openid-connect/token

O preferred_username do JWT é o CPF/CNPJ sem formatação — usado como identificador do contribuinte nas chamadas ao backend.


Status de Implementação dos Endpoints

Endpoint Frontend pronto Backend pronto Mock
GET /publico/prefeitura/{dominio}
GET /publico/certidao/consultar pendente
GET /publico/certidao/emitir pendente
GET /publico/iptu/consultar pendente
GET /publico/iptu/carne pendente
GET /publico/iptu/boleto pendente
GET /publico/primeiro-acesso/verificar pendente
POST /publico/primeiro-acesso/codigo pendente
POST /publico/primeiro-acesso/validar pendente
POST /publico/primeiro-acesso/senha pendente
GET /publico/credenciamento/verificar pendente
GET /publico/cep/{cep} pendente
POST /publico/credenciamento/solicitar pendente
GET /contribuinte/painel/resumo pendente
GET /contribuinte/painel/atividades pendente
GET /contribuinte/debitos pendente
GET /contribuinte/debitos/{id}/guia pendente
GET /contribuinte/certidoes pendente
GET /contribuinte/certidoes/{id}/pdf pendente
GET /contribuinte/alvaras pendente
GET /contribuinte/pagamentos pendente
GET /contribuinte/pagamentos/{id}/comprovante pendente
GET /contribuinte/dados pendente
PUT /contribuinte/dados/contato pendente
GET /publico/avisos/{dominio} parcial pendente