# v4928.1.5.91 — Company contact cross-conversation linking

## Problema corrigido

Em clientes B2B é comum a encomenda chegar por um contacto/departamento e o pagamento por outro:

- `geral@empresa.pt` ou `compras@empresa.pt` pede orçamento/encomenda;
- `financeiro@empresa.pt` ou `contabilidade@empresa.pt` envia comprovativo/pagamento.

Antes desta versão, uma nova conversa Chatwoot podia criar uma segunda oportunidade mesmo quando o assunto continha uma referência documental já ligada a uma oportunidade existente, por exemplo `Orçamento 2026/193` versus `ORC.ORC2026.193`.

## Correções

- Antes de criar uma nova oportunidade, o motor extrai e normaliza referências documentais no assunto/corpo/nota da task:
  - `Orçamento 2026/193` → `ORC.ORC2026.193`;
  - `ORC 2026/193` → `ORC.ORC2026.193`;
  - `Fatura 2026/131` → `FA.FA2026.131`.
- Se o documento já estiver em `commercial_documents` ou `reconciliation_items` e estiver ligado a uma oportunidade aberta, a nova task/conversa é ligada automaticamente a essa oportunidade.
- O domínio empresarial passa a ser evidência de empresa, não prova cega de oportunidade:
  - domínio único + tarefa financeira/processo → pode associar automaticamente;
  - múltiplas oportunidades no mesmo domínio → envia para associação manual;
  - domínios públicos/ISP (`gmail.com`, `sapo.pt`, `hotmail.com`, etc.) continuam excluídos.
- A task ambígua passa a guardar candidatos em metadata para o operador escolher.
- A página da task ganha painel “Associar a oportunidade existente”, com botão para ligar a task/conversa à oportunidade certa.
- Novo script de reparação:
  - `scripts/repair_cross_conversation_company_links.py`
  - dry-run por defeito;
  - move apenas matches fortes por referência documental com `--apply`;
  - casos só por domínio/múltiplos candidatos ficam para revisão manual.

## Ficheiros alterados

- `app/company_opportunity_linking.py`
- `app/opportunity_service.py`
- `app/admin_ui/pages/tasks.py`
- `scripts/repair_cross_conversation_company_links.py`
- `tests/test_v4928_1_5_91_company_contact_cross_conversation_static.py`
