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

# API de contatos

> Referência interna para a API de contatos — CRUD, operações em massa, mesclagem de candidatos, linha do tempo e visualização 360 do cliente.

> **Documentação interna para desenvolvedores.** Esta página aborda os endpoints da API Contacts, operações em massa, detecção de mesclagem e o modelo de dados do cliente 360. Não se destina a usuários finais.

***

## Mapa de rotas

| Método   | Ponto final                      | Arquivo manipulador                  | Descrição                      |
| -------- | -------------------------------- | ------------------------------------ | ------------------------------ |
| `GET`    | `/api/contacts`                  | `contacts/route.ts`                  | Listar contatos com filtros    |
| `POST`   | `/api/contacts`                  | `contacts/route.ts`                  | Crie um contato                |
| `GET`    | `/api/contacts/[contactId]`      | `contacts/[contactId]/route.ts`      | Obter contato por ID           |
| `PATCH`  | `/api/contacts/[contactId]`      | `contacts/[contactId]/route.ts`      | Atualizar contato              |
| `DELETE` | `/api/contacts/[contactId]`      | `contacts/[contactId]/route.ts`      | Excluir contato                |
| `POST`   | `/api/contacts/bulk-delete`      | `contacts/bulk-delete/route.ts`      | Excluir vários contatos        |
| `GET`    | `/api/contacts/merge-candidates` | `contacts/merge-candidates/route.ts` | Encontre candidatos duplicados |

***

## Padrão de autenticação

```ts theme={null}
withPermissionRoute(req, {
  anyPermission: ['contacts.read'],  // for GET
  // or
  anyPermission: ['contacts.write'], // for mutations
  authMode: 'lightweight',           // for reads
}, handler)
```

Todas as consultas devem ter como escopo `req.session.organization.id`.

***

## Esquema de objeto de contato

```ts theme={null}
interface Contact {
  id: string;
  organizationId: string;
  name: string | null;
  email: string | null;
  phone: string | null;
  whatsappPhone: string | null;
  externalId: string | null;
  avatarUrl: string | null;
  metadata: Record<string, unknown>;
  tags: string[];
  createdAt: string;
  updatedAt: string;
}
```

***

## Listar contatos (filtros)

```ts theme={null}
// GET /api/contacts
// Query params:
// - search: string (name, email, phone, externalId)
// - page, limit: pagination
// - tag: string (filter by tag)
// - channel: string (contacts with conversations in this channel)
// - dateFrom, dateTo: ISO 8601
```

***

## Exclusão em massa

```ts theme={null}
// POST /api/contacts/bulk-delete
// Body: { contactIds: string[] }
// Deletes all contacts + cascades to conversations
// Max batch: 100 IDs per request (to prevent timeout)
```

***

## Mesclar Candidatos

O endpoint `merge-candidates` executa um algoritmo de correspondência difusa para identificar possíveis contatos duplicados:

```ts theme={null}
// GET /api/contacts/merge-candidates?contactId=xxx
// Returns contacts that match by email, phone, or name similarity
// Uses: Prisma + application-level fuzzy matching
```

**Estratégia de mesclagem:**

* O contato principal mantém seu ID
* As conversas do contato secundário são reatribuídas
* O contato secundário é excluído
* **Não desfazer** — avisar os usuários antes da mesclagem

***

## Visão 360 do cliente

A página de contato individual agrega dados de várias fontes:

| Fonte                            | Dados                                 |
| -------------------------------- | ------------------------------------- |
| `Contact` tabela                 | Perfil principal                      |
| `Conversation` tabela            | Todas as conversas                    |
| Tabela `Message` (via conversas) | Histórico de mensagens                |
| `metadata` JSON                  | Campos personalizados                 |
| Webhooks de integração           | CRM/dados externos (se sincronizados) |

***

## Índices Prisma usados

| Tabela    | Índice                       | Usado por                        |
| --------- | ---------------------------- | -------------------------------- |
| `Contact` | `organizationId`             | Todas as consultas da lista      |
| `Contact` | `organizationId, email`      | Mesclar detecção de candidato    |
| `Contact` | `organizationId, phone`      | Mesclar detecção de candidato    |
| `Contact` | `organizationId, externalId` | Sincronização de sistema externo |

***

## Problemas conhecidos/pegadinhas

* **Exclusão em cascata em massa:** A exclusão de contatos exclui suas conversas. Esta é uma operação destrutiva. Sempre confirme com o usuário antes de ligar.
* **Normalização do telefone:** Os números de telefone devem ser armazenados no formato E.164 (`+5511999990000`). Formatos inconsistentes fazem com que os candidatos à mesclagem percam duplicatas.
* **`externalId`** é usado para sincronização de CRM (por exemplo, HubSpot, Salesforce). Ao sincronizar de sistemas externos, sempre use `upsert` em `organizationId + externalId`.
* **Mesclar candidatos** usa correspondência em nível de aplicativo (não em nível de banco de dados). Para listas de contatos grandes (mais de 100 mil), isso pode ser lento. Considere adicionar um trabalho em segundo plano para organizações grandes.
