# ClientFlow Backend — versão de estabilização 2026-07-08

## Objetivo
Consolidar a última versão do backend antes de novas funcionalidades, corrigindo falhas P0/P1 encontradas na review: suíte de testes não-verde, bug em `list_tasks()`, divergências no workflow de oportunidades, linking ambíguo, `.env.example` ausente e problemas de coleção do pytest.

## Correções principais

### Testes e packaging
- Adicionado `pytest.ini` com `testpaths = tests`, `pythonpath = .` e `--import-mode=importlib`.
- Removido o teste duplicado de raiz `test_v4928_1_5_72_opportunity_consistency_static.py` para evitar `import file mismatch`.
- Adicionado `.env.example` com flags obrigatórias e opcionais documentadas.
- Consolidado teste estático contraditório de `workflow_guard`: a implementação mantém compatibilidade com schema sem coluna `completed_at` e continua a aceitar `completed_at` quando a evidência vem em payload/dict.
- Consolidado teste de materialização `PREPARE_ORDER` com a regra de arquitetura que remove esse código da triagem LLM em `action_catalog.py`.

### `task_service.py`
- Corrigido bug P0 em `list_tasks()`: `customer_column` agora é calculado antes do SQL através de `opportunity_customer_column()` e tem fallback seguro para `local_customer_id`.
- Removida duplicação acidental de coluna em `get_task_detail()`.

### Workflow de oportunidades
- `WAIT_PRODUCTION` volta a mostrar a label operacional “Aguardar produção”, mantendo alias/compatibilidade UI para “Aguardar WH/OUT”.
- Fluxo `after_delivery` com envio já criado e pagamento por confirmar passa a sugerir `FOLLOW_UP_PAYMENT`, em vez de voltar para `PREPARE_ORDER`.
- Mantida prioridade de fecho/entrega sobre estados de produção quando WH/OUT/picking já está concluído.
- Evidência de fatura enviada continua a considerar payload do documento e tasks `SEND_INVOICE` concluídas.

### UI/admin
- A página de oportunidades filtra tasks de pagamento/follow-up obsoletas quando o pagamento já está confirmado.
- O resumo operacional passa a usar `display_next_action_code` para evitar fallback para `last_action_code` antigo.
- Adicionada mensagem explícita quando o Jasmin existe mas não tem novos campos fiscais para importar.
- `admin_dashboard.py` ficou abaixo do limite legado de 1800 linhas sem alterar rotas principais.

### Segurança funcional / linking
- Ambiguidade de oportunidades por contacto Chatwoot passa a usar razão explícita `multiple_recent_open_opportunities_for_chatwoot_contact`.
- `action_catalog.py` mantém `PREPARE_ORDER` fora do catálogo de triagem LLM; o código interno é tratado dinamicamente para compatibilidade operacional.

### Outros ajustes
- Corrigidos warnings de `compileall` por escapes inválidos em SQL LIKE/ESCAPE.
- Adicionado marcador de identificação ao script `probe_jasmin_print_layout_catalog.py`.

## Validação local

Com variáveis de teste:

```bash
OPENROUTER_API_KEY=test \
DATABASE_URL=postgresql+psycopg://u:p@localhost:5432/db \
CLIENTFLOW_ADMIN_TOKEN=test \
PYTHONPATH=. \
pytest -q
```

Resultado:

```text
463 passed in 1.12s
```

Compilação:

```bash
python -m compileall -q app scripts tests
```

Resultado: sem erros e sem warnings reportados.

## Limitações
- Não foram executadas integrações reais com Postgres, Jasmin, Odoo, Packlink, Chatwoot ou OpenAI/OpenRouter.
- A validação foi feita por testes locais/estáticos/unitários e compilação Python.
- Antes de produção, correr migrações e smoke tests contra uma base staging.
