> ## Documentation Index
> Fetch the complete documentation index at: https://docs.patrimonion.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Contratos

> Ciclo de vida completo de contratos de locação. Criação com geração automática de parcelas, envio por e-mail, upload do PDF assinado e encerramento com validação de pré-requisitos.

## O objeto Contrato

```json theme={null}
{
  "id": "con789",
  "imovelId": "abc123",
  "locatarioId": "loc456",
  "dataInicio": "2025-02-01",
  "dataFim": "2026-01-31",
  "valorAluguel": 2500,
  "diaVencimento": 5,
  "numeroParcelas": 12,
  "ativo": true,
  "contratoAssinadoKey": "uid123/contratos/con789/contrato.pdf",
  "assinadoEm": "2025-02-01T14:00:00.000Z",
  "userId": "uid_do_usuario",
  "criadoEm": "2025-01-28T10:00:00.000Z",
  "imovel": {
    "id": "abc123",
    "nome": "Apto Centro",
    "endereco": "Rua das Flores, 123",
    "rua": "Rua das Flores",
    "numero": "123",
    "bairro": "Centro",
    "cidade": "São Paulo",
    "estado": "SP"
  },
  "locatario": {
    "id": "loc456",
    "nome": "João da Silva",
    "cpf": "123.456.789-00",
    "email": "joao@email.com",
    "telefone": "(11) 99999-0000"
  }
}
```

### Campos calculados no retorno

Todos os endpoints de busca retornam os objetos `imovel` e `locatario` embutidos no contrato, populados em paralelo via `Promise.all`. Nenhuma query extra é necessária no frontend.

***

## Criar contrato

A criação é executada em uma **Firestore Transaction**, garantindo consistência total. Em uma única operação atômica:

1. Valida que o imóvel existe, pertence ao usuário e está `DISPONIVEL`
2. Cria o documento do contrato
3. Atualiza o status do imóvel para `ALUGADO`
4. Gera uma cobrança de caução (se `valorCaucao` for informado)
5. Gera automaticamente todas as parcelas de aluguel com base na duração real do contrato

<ParamField body="imovelId" type="string" required>
  ID do imóvel. Deve estar com `status: DISPONIVEL`.
</ParamField>

<ParamField body="locatarioId" type="string" required>
  ID do locatário cadastrado.
</ParamField>

<ParamField body="dataInicio" type="string" required>
  Data de início no formato `YYYY-MM-DD`.
</ParamField>

<ParamField body="dataFim" type="string" required>
  Data de término. O número de parcelas é calculado a partir da diferença em meses.
</ParamField>

<ParamField body="valorAluguel" type="number" required>
  Valor mensal do aluguel em reais.
</ParamField>

<ParamField body="diaVencimento" type="number" required>
  Dia do mês para vencimento das parcelas (ex: `5` para dia 5).
</ParamField>

<ParamField body="valorCaucao" type="number">
  Valor do depósito caução. Se informado e maior que zero, cria uma cobrança do tipo `CAUCAO` com vencimento na `dataInicio`.
</ParamField>

```http theme={null}
POST /contratos
Cookie: imob_session=<session_cookie>
Content-Type: application/json

{
  "imovelId": "abc123",
  "locatarioId": "loc456",
  "dataInicio": "2025-02-01",
  "dataFim": "2026-01-31",
  "valorAluguel": 2500,
  "diaVencimento": 5,
  "valorCaucao": 5000
}
```

```json Resposta 201 theme={null}
{
  "message": "Contrato e parcelas geradas com sucesso.",
  "contratoId": "con789",
  "numeroParcelas": 12
}
```

<Warning>
  Tentativas de criar contrato para um imóvel com `status: ALUGADO` retornam `400 Bad Request` com a mensagem `"Este imóvel já está alugado"`.
</Warning>

***

## Listar contratos

Retorna todos os contratos do usuário com `imovel` e `locatario` populados.

```http theme={null}
GET /contratos
Cookie: imob_session=<session_cookie>
```

***

## Buscar contrato por ID

```http theme={null}
GET /contratos/:id
Cookie: imob_session=<session_cookie>
```

***

## Enviar contrato por e-mail

Envia o PDF do contrato como anexo para o e-mail do locatário via **Brevo**. As credenciais do Brevo são lidas de `configuracoes_notificacoes` do usuário autenticado.

<ParamField body="pdfBase64" type="string" required>
  PDF do contrato codificado em base64.
</ParamField>

```http theme={null}
POST /contratos/:id/enviar-email
Cookie: imob_session=<session_cookie>
Content-Type: application/json

{
  "pdfBase64": "JVBERi0xLjQKJcfs..."
}
```

```json Resposta 200 theme={null}
{
  "message": "Contrato enviado para joao@email.com com sucesso."
}
```

**Pré-condições para o envio:**

* Locatário deve ter `email` cadastrado — caso contrário retorna `422`
* `brevoApiKey` e `brevoEmailRemetente` devem estar configurados em **Configurações > Notificações** — caso contrário retorna `422`

***

## Registrar contrato assinado (URL)

Salva a URL de um contrato assinado já hospedado (MinIO ou outro storage).

<ParamField body="contratoAssinadoUrl" type="string" required>
  URL pública ou pressinada do PDF assinado.
</ParamField>

```http theme={null}
POST /contratos/:id/upload-assinado
Cookie: imob_session=<session_cookie>
Content-Type: application/json

{
  "contratoAssinadoUrl": "https://..."
}
```

<Info>
  Para fazer o upload direto do arquivo PDF, use `POST /upload/contrato/:contratoId`. Esse endpoint salva no MinIO e registra a key automaticamente.
</Info>

***

## Verificar status de encerramento

Retorna um diagnóstico completo sobre as condições para encerrar o contrato — sem fazer nenhuma alteração.

```http theme={null}
GET /contratos/:id/status-encerramento
Cookie: imob_session=<session_cookie>
```

```json Resposta 200 theme={null}
{
  "podeEncerrar": false,
  "alertaEncerramento": true,
  "bloqueios": {
    "vistoriaSaidaPendente": true,
    "pendenciasFinanceiras": 2,
    "imovelId": "abc123"
  },
  "info": {
    "contratoPrazoVencido": true,
    "dataFim": "2026-01-31",
    "semPendencias": false,
    "temVistoriaSaida": false
  }
}
```

### Regras de encerramento

| Condição                               | Obrigatória |
| -------------------------------------- | ----------- |
| Vistoria de saída registrada           | Sim         |
| Parcelas `PENDENTE`/`ATRASADO` zeradas | Sim         |

***

## Encerrar contrato

Encerra o contrato e libera o imóvel para locação. Executa em transaction atômica.

```http theme={null}
PATCH /contratos/:id/encerrar
Cookie: imob_session=<session_cookie>
```

```json Resposta 200 theme={null}
{
  "message": "Contrato encerrado e imóvel liberado com sucesso.",
  "imovelLiberado": true
}
```

**Erros possíveis:**

```json 422 — Vistoria de saída pendente theme={null}
{
  "error": "Vistoria de saída obrigatória antes de encerrar o contrato.",
  "codigo": "VISTORIA_SAIDA_PENDENTE",
  "imovelId": "abc123"
}
```

```json 422 — Pendências financeiras theme={null}
{
  "error": "Existem 2 parcela(s) não quitada(s). Quite todas as pendências antes de encerrar.",
  "codigo": "PENDENCIAS_FINANCEIRAS",
  "pendencias": 2
}
```
