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

700 lines
15 KiB
Markdown

# 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):**
```json
{
"timestamp": "2025-05-18T10:00:00Z",
"statusCode": 200,
"responseType": "SUCCESS",
"message": "OK",
"data": { }
}
```
**Envelope de erro:**
```json
{
"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`:**
```json
{
"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`:**
```json
{
"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`:**
```json
{
"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`:**
```json
{
"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:**
```json
{
"documento": "12345678900",
"canal": "EMAIL"
}
```
**Response `data`:**
```json
{ "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:**
```json
{
"documento": "12345678900",
"codigo": "123456"
}
```
**Response `data`:**
```json
{ "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:**
```json
{
"token": "eyJhb...",
"senha": "MinhaS3nha!"
}
```
**Response `data`:**
```json
{ "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`:**
```json
{ "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`:**
```json
{
"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):**
```json
{
"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):**
```json
{
"tipoPessoa": "JURIDICA",
"razaoSocial": "Empresa LTDA",
"nomeFantasia": "Empresa",
"inscricaoEstadual": "12345678",
"representanteLegal": {
"nomeCompleto": "João da Silva",
"cpf": "12345678900",
"cargo": "Diretor"
}
}
```
**Response `data`:**
```json
{ "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`:**
```json
{
"totalDebitos": 1250.90,
"certidoesAtivas": 2,
"alvarasAndamento": 2,
"ultimoPagamento": 430.00,
"debitosVencidos": 1
}
```
---
#### `GET /contribuinte/painel/atividades`
Lista das últimas atividades do contribuinte.
**Response `data`:**
```json
{
"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`:**
```json
{
"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`:**
```json
{
"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`:**
```json
{
"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`:**
```json
{
"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):**
```json
{
"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):**
```json
{
"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:**
```json
{
"email": "novo@email.com",
"telefone": "98991234567",
"whatsapp": true
}
```
`telefone` deve ser enviado **sem formatação** (apenas dígitos).
**Response `data`:**
```json
{ "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:**
```json
{
"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 | — |