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

# Atividades, Arquivos e Histórico

> Tarefas, anexos e o log de eventos de cada negócio

## Atividades (todos)

Uma atividade é uma tarefa vinculada a um negócio: uma ligação, uma reunião, um follow-up.

### Tipos válidos

| `type`      | Uso                                           |
| ----------- | --------------------------------------------- |
| `Ligação`   | Contato por telefone                          |
| `Reunião`   | Encontro agendado                             |
| `Follow-up` | Retomada de contato                           |
| `Tarefa`    | Genérico — é o padrão quando `type` é omitido |

<Warning>
  Um `type` fora desta lista retorna **400**. Os valores são exatamente estes, acentuados.
</Warning>

### O objeto Atividade

<ResponseField name="id" type="string">
  UUID da atividade
</ResponseField>

<ResponseField name="deal_id" type="string">
  UUID do negócio
</ResponseField>

<ResponseField name="type" type="string">
  Tipo da atividade
</ResponseField>

<ResponseField name="text" type="string">
  Descrição da atividade
</ResponseField>

<ResponseField name="due_at" type="string">
  Prazo (ISO 8601), ou ausente
</ResponseField>

<ResponseField name="booking_id" type="string">
  UUID do agendamento no módulo Agendamentos, quando a atividade nasceu de uma reunião marcada
</ResponseField>

<ResponseField name="done" type="boolean">
  Se a atividade foi concluída
</ResponseField>

<ResponseField name="overdue" type="boolean">
  Calculado na leitura: `true` quando a atividade está pendente e `due_at` já passou
</ResponseField>

### Listar atividades

<Card>
  <strong>GET</strong> `/backend/pipeline/deals/{id}/todos`
</Card>

Requer `pipeline.view`.

### Criar atividade

<Card>
  <strong>POST</strong> `/backend/pipeline/deals/{id}/todos`
</Card>

Requer `pipeline.deals.edit`.

<ParamField body="text" type="string">
  Descrição da atividade. Quando omitida ou vazia, usa o próprio `type` como descrição.
</ParamField>

<ParamField body="type" type="string" default="Tarefa">
  Um dos tipos válidos acima
</ParamField>

<ParamField body="due_at" type="string">
  Prazo (ISO 8601)
</ParamField>

<ParamField body="booking_id" type="string">
  UUID de um agendamento já criado em Agendamentos, para vincular a atividade à reunião real
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.leavo.ai/backend/pipeline/deals/dd0e8400-e29b-41d4-a716-446655440000/todos" \
    -H "Authorization: Bearer sua_chave_aqui" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "Ligação",
      "text": "Retornar sobre a proposta",
      "due_at": "2026-07-25T14:00:00Z"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "id": "110e8400-e29b-41d4-a716-446655440000",
    "deal_id": "dd0e8400-e29b-41d4-a716-446655440000",
    "type": "Ligação",
    "text": "Retornar sobre a proposta",
    "due_at": "2026-07-25T14:00:00Z",
    "done": false,
    "overdue": false,
    "created_at": "2026-07-21T10:00:00Z"
  }
  ```
</ResponseExample>

### Atualizar atividade

<Card>
  <strong>PUT</strong> `/backend/pipeline/todos/{id}`
</Card>

Requer `pipeline.deals.edit`. Campos omitidos permanecem inalterados.

<ParamField body="text" type="string">
  Nova descrição. Se enviada, não pode ser vazia — nesse caso a resposta é **400**.
</ParamField>

<ParamField body="done" type="boolean">
  Marca ou desmarca como concluída
</ParamField>

<ParamField body="due_at" type="string">
  Novo prazo (ISO 8601)
</ParamField>

<Note>
  O `type` de uma atividade não pode ser alterado depois de criada.
</Note>

### Excluir atividade

<Card>
  <strong>DELETE</strong> `/backend/pipeline/todos/{id}`
</Card>

Requer `pipeline.deals.edit`. Retorna `{ "success": true }`.

***

## Arquivos

Os anexos seguem o padrão de **duas fases** já usado no restante da plataforma: primeiro o
arquivo é enviado para [Upload de Arquivos](/pt-BR/api-reference/uploads/upload), depois o
`upload_id` resultante é vinculado ao negócio.

<Steps>
  <Step title="Enviar o arquivo">
    `POST /backend/uploads` com o arquivo. O upload nasce com status `PENDING`.
  </Step>

  <Step title="Vincular ao negócio">
    `POST /backend/pipeline/deals/{id}/files` com o `upload_id`. O upload passa a `ASSOCIATED`.
  </Step>
</Steps>

### Listar arquivos

<Card>
  <strong>GET</strong> `/backend/pipeline/deals/{id}/files`
</Card>

Requer `pipeline.view`.

<ResponseExample>
  ```json 200 OK theme={null}
  [
    {
      "id": "220e8400-e29b-41d4-a716-446655440000",
      "upload_id": "330e8400-e29b-41d4-a716-446655440000",
      "filename": "proposta-comercial.pdf",
      "file_url": "https://storage.leavo.ai/...",
      "mime_type": "application/pdf",
      "size": 148392,
      "created_at": "2026-07-21T10:05:00Z"
    }
  ]
  ```
</ResponseExample>

### Anexar arquivo

<Card>
  <strong>POST</strong> `/backend/pipeline/deals/{id}/files`
</Card>

Requer `pipeline.deals.edit`.

<ParamField body="upload_id" type="string" required>
  UUID do upload retornado pela etapa anterior
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.leavo.ai/backend/pipeline/deals/dd0e8400-e29b-41d4-a716-446655440000/files" \
    -H "Authorization: Bearer sua_chave_aqui" \
    -H "Content-Type: application/json" \
    -d '{ "upload_id": "330e8400-e29b-41d4-a716-446655440000" }'
  ```
</RequestExample>

Retorna **201 Created** com o arquivo.

### Remover arquivo

<Card>
  <strong>DELETE</strong> `/backend/pipeline/deal-files/{id}`
</Card>

Requer `pipeline.deals.edit`. O `{id}` é o **id do anexo** (`DealFile`), não o `upload_id`.

***

## Histórico (eventos)

Cada negócio mantém um log de eventos persistido — não derivado em tempo de leitura. É o que
alimenta a aba de histórico do negócio.

<Card>
  <strong>GET</strong> `/backend/pipeline/deals/{id}/events`
</Card>

Requer `pipeline.view`. Resposta paginada.

### Query Parameters

<ParamField query="page" type="integer" default="1">
  Página desejada
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Itens por página. Valores fora de 1–200 voltam ao padrão de 50.
</ParamField>

### Tipos de evento

| `event_type`       | Quando acontece               |
| ------------------ | ----------------------------- |
| `deal_created`     | Negócio criado                |
| `stage_moved`      | Movido para outra etapa       |
| `deal_won`         | Movido para a etapa de ganho  |
| `deal_lost`        | Movido para a etapa de perda  |
| `note_added`       | Observação alterada           |
| `todo_created`     | Atividade criada              |
| `todo_completed`   | Atividade concluída           |
| `owner_changed`    | Responsável alterado          |
| `tag_added`        | Tag adicionada                |
| `tag_removed`      | Tag removida                  |
| `file_attached`    | Arquivo anexado               |
| `file_removed`     | Arquivo removido              |
| `meeting_booked`   | Reunião agendada              |
| `products_updated` | Produtos do negócio alterados |

### Autor do evento (`actor_type`)

| Valor    | Significado                                                             |
| -------- | ----------------------------------------------------------------------- |
| `user`   | Uma pessoa autenticada                                                  |
| `ai`     | O assistente de IA                                                      |
| `system` | Ação automática — por exemplo, um negócio criado por webhook de entrada |

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": [
      {
        "id": "440e8400-e29b-41d4-a716-446655440000",
        "event_type": "deal_lost",
        "title": "Negócio marcado como perdido",
        "description": "Motivo: Fechou com concorrente",
        "actor_type": "user",
        "actor_name": "Ana Ribeiro",
        "metadata": {
          "from_stage_id": "cc0e8400-e29b-41d4-a716-446655440000",
          "to_stage_id": "cc3e8400-e29b-41d4-a716-446655440000"
        },
        "created_at": "2026-07-21T09:40:00Z"
      }
    ],
    "pagination": {
      "current_page": 1,
      "total_pages": 1,
      "total_count": 8,
      "has_next": false,
      "has_prev": false
    }
  }
  ```
</ResponseExample>
