# Conversations

**Conversation Engine V1** — Sprint 003 (R0.5) ✅

Namespace: `ImovelZapAi\Conversations\`

## Domínio

Quem fala, a sessão e cada mensagem — canal-agnóstico (WhatsApp na V1).

| Entidade | Tabela | Nota |
|----------|--------|------|
| **Contact** | `contacts` | Identidade mínima (telefone/wa_id). **Não é Lead.** |
| **Conversation** | `conversations` | Sessão tenant + contact + estado do fluxo |
| **Message** | `messages` | Inbound/outbound, status de entrega |
| **TenantMessagingConfig** | `tenant_messaging_configs` | Provedor (`evolution` \| `meta_cloud`), credenciais, instância |

## Fluxo de descoberta (V1)

```text
Inbound webhook
  → ProcessInboundMessageJob
  → HandleConversationMessageAction
  → ConversationIntentExtractor (heurística PT-BR)
  → ProcessPropertySearchAction | PresentCatalogPropertyAction | …
  → SendOutboundMessageAction (adapter por tenant)
```

### Estados

`open` · `collecting_search` · `awaiting_catalog_confirmation` · `browsing` · `viewing_detail` · `closed`

### Palavras-chave (Baileys)

| Palavra | Intent |
|---------|--------|
| `SIM` | ConfirmCatalog |
| `MAIS` | ShowNextCatalogProperty |
| `VISITAR` | RegisterVisitInterest |

Botões interativos: apenas com `CONVERSATION_USE_INTERACTIVE_BUTTONS=true` e provider `meta_cloud`.

## Actions principais

| Action | Responsabilidade |
|--------|------------------|
| `HandleConversationMessageAction` | Orquestra intents |
| `ProcessPropertySearchAction` | Coleta critérios + dispara catálogo |
| `SendPropertyCatalogAction` | Resumo + confirmação; relaxamento de filtros |
| `PresentCatalogPropertyAction` | 1 imóvel por vez (foto + texto) |
| `PresentPropertyDetailAction` | Ficha detalhada |
| `HandlePropertyVisitInterestAction` | Interesse em visita |

## Services

| Service | Responsabilidade |
|---------|------------------|
| `ConversationIntentExtractor` | Classifica mensagem → intent |
| `PropertySearchCriteriaExtractor` | Extrai filtros de busca PT-BR |
| `ConversationSearchQuestioner` | Perguntas incrementais (local) |
| `ConversationSearchMemory` | `context.search` na conversa |
| `PropertyCatalogFormatter` | Mensagens de catálogo |
| `ConversationResponseDelay` | Delay humanizado |
| `PropertyMediaUrlResolver` | Mídia outbound (base64 padrão) |

## Provedores WhatsApp

| Fase | Adapter | Onboarding |
|------|---------|------------|
| **MVP** | `EvolutionMessagingAdapter` | QR Code na UI `/whatsapp` |
| **Enterprise** | `MetaCloudMessagingAdapter` | Credenciais Meta por tenant |

Porta: `MessagingAdapterInterface` · resolução: `MessagingAdapterResolver`

## Webhooks

- Evolution: `POST /api/webhooks/evolution`
- Meta: `GET/POST /api/webhooks/whatsapp`

## Config

`backend/config/conversations.php` — catálogo, delay, mídia, keywords.

## Testes

```bash
docker compose exec -w /var/www/html/backend php php artisan test --filter=Conversation
```

## Documentação

- [`docs/sprints/SPRINT_003_CONVERSATIONS.md`](../../docs/sprints/SPRINT_003_CONVERSATIONS.md)
- [`docs/sprints/SPRINT_004_QUALIFICATION.md`](../../docs/sprints/SPRINT_004_QUALIFICATION.md)
- [`docs/blueprints/WHATSAPP_BLUEPRINT.md`](../../docs/blueprints/WHATSAPP_BLUEPRINT.md)
- [`docs/PRODUCT_MODEL.md`](../../docs/PRODUCT_MODEL.md)
