✅ Checklist: Reactivation Agent
Status: 🟢 Completo
Prioridade: 3 (Depende do Account State Agent)
Estimativa: 1-2 semanas
Progresso: 100% - ✅ Todas as fases concluídas!
📋 Resumo
| Item | Valor |
|---|---|
| Código | reactivation |
| Porta | 8022 |
| Database | csuite_context |
| Prefixo API | /v1/reactivation |
| Traefik Path | /reactivation/ |
| Depende de | Account State Agent, Pricing Agent, NBA Agent |
🎯 Objetivo
Estratégias controladas para recuperar contas em estado STALLED ou AT_RISK. Decide se vale tentar, qual estratégia usar, e mede resultados.
Frase-guia: Onboarding cria raiz. Gestão faz crescer. Reactivation decide se vale salvar ou deixar morrer.
⚠️ Regra de Elegibilidade (CRÍTICA)
Reactivation NÃO se aplica a contas que nunca atingiram
ACTIVE.
- ✅ Elegível: Conta que foi
ACTIVEe agora estáSTALLEDouAT_RISK- ❌ Não elegível: Conta que falhou no onboarding (nunca foi
ACTIVE)Razão: Failed onboarding ≠ stalled account. São problemas diferentes com soluções diferentes.
- Onboarding falho → revisar qualificação ou tentar novo onboarding
- Conta stalled → reativação com estratégia controladaIsso mantém o ROI de reativação alto e evita gastar recursos em contas que nunca provaram valor.
📊 Estratégias de Reativação
| Estratégia | Quando Usar | Custo |
|---|---|---|
INCENTIVE_DISCOUNT |
Cliente sensível a preço | Alto |
PRODUCT_MIX |
Cliente quer novidades | Médio |
PERSONAL_CONTACT |
Relacionamento forte | Baixo |
SPECIAL_CONDITION |
Cliente VIP | Alto |
WAIT |
Melhor não agir agora | Zero |
📊 Fluxo de Estados
STALLED/AT_RISK → [Create Attempt] → IN_PROGRESS → WON/LOST
↓
Se WON: ACTIVE
Se LOST: CHURN ou nova tentativa
✅ Fases de Implementação
Fase 1: Estrutura Base
- [x] Criar diretório
/c-suite/agents/reactivation/ - [x] Criar
requirements.txt
fastapi==0.104.1 uvicorn==0.24.0 mysql-connector-python==8.2.0 pydantic==2.5.2 python-dotenv==1.0.0 httpx==0.25.2 - [x] Criar
.env.example - [x] Criar
main.py(FastAPI app) - [x] Criar
app/__init__.py - [x] Criar
app/settings.py - [x] Criar
app/database.py
Fase 2: Schema SQL
- [x] Criar
sql/schema.sql - [x] Criar tabela
channel_reactivation_attempts - [x] Criar índices
- [ ] Executar no RDS DEV
- [x] Criar
sql/views.sql
Fase 3: Modelos Python
- [x] Criar
app/models.py - [x]
ReactivationStrategyEnum - [x]
AttemptStatusEnum - [x]
OutcomeTypeEnum - [x]
ReactivationAttempt - [x]
CreateAttemptRequest - [x]
RecordOutcomeRequest - [x]
CandidateAccount
Fase 4: Repository (Queries)
- [x] Criar
app/repository.py - [x]
create_attempt(account_id, strategy, params) - [x]
get_attempt(attempt_id) - [x]
get_attempts_by_account(account_id) - [x]
get_active_attempts() - [x]
update_attempt_status(attempt_id, status) - [x]
record_outcome(attempt_id, outcome) - [x]
get_metrics(period) - [x]
get_strategy_effectiveness()
Fase 5: Heuristics (Lógica de Decisão)
- [x] Criar
app/heuristics.py - [x]
select_strategy(account_data, history)- qual estratégia usar - [x]
calculate_max_discount(account_value, margin)- limite de incentivo - [x]
should_attempt(account, previous_attempts)- vale tentar? - [x]
suggest_products(account_data)- produtos para ofertar - [x]
evaluate_outcome(attempt, new_order)- funcionou? - [x]
calculate_attempt_cost(attempt)- custo da tentativa
Fase 6: Integrações Externas
- [x] Criar
app/state_client.py- Account State Agent - [x]
get_reactivation_candidates() - [x]
update_state_after_outcome(account_id, won) - [x] Criar
app/pricing_client.py- Pricing Agent - [x]
get_discount_limits(account_id) - [x] Criar
app/nba_client.py- NBA Agent - [x]
create_reactivation_action(account_id, strategy)
Fase 7: Routes/API
- [x] Criar
routes/__init__.py - [x] Criar
routes/core.py - [x]
GET /- info - [x]
GET /health- health check - [x] Criar
routes/reactivation.py - [x]
GET /v1/reactivation/candidates- listar candidatos - [x]
POST /v1/reactivation/create- criar tentativa - [x]
GET /v1/reactivation/attempt/{id}- consultar tentativa - [x]
POST /v1/reactivation/attempt/{id}/start- iniciar execução - [x]
POST /v1/reactivation/attempt/{id}/outcome- registrar resultado - [x]
GET /v1/reactivation/active- tentativas em andamento - [x]
GET /v1/reactivation/history/{account_id}- histórico - [x]
GET /v1/reactivation/metrics- KPIs - [x]
GET /v1/reactivation/strategy-effectiveness- eficácia por estratégia
Fase 8: Policies
- [x] Criar
policies/__init__.py - [x] Criar
policies/reactivation.py - [x] Máximo de tentativas por conta
- [x] Intervalo mínimo entre tentativas
- [x] Limites de desconto por estratégia
- [x] Regras de escalation
Fase 9: Docker
- [x] Criar
Dockerfile - [x] Criar
docker-stack.yml - [x] Criar
deploy.sh - [x] Build local e testar
Fase 10: Deploy DEV
- [ ] Adicionar ao
docker-stack-dev.ymlprincipal - [x] Configurar secrets
- [x] Deploy em DEV
- [x] Testar endpoints via curl
- [x] Verificar logs
Fase 11: Integração Seller Cockpit (Backend)
- [x] Criar
seller-cockpit/backend/src/services/reactivation.service.js - [x] Adicionar métodos:
- [x]
getCandidates() - [x]
createAttempt(accountId, strategy) - [x]
startAttempt(attemptId) - [x]
recordOutcome(attemptId, outcome) - [x] Atualizar
aggregator.service.js: - [x] Adicionar actionType
REACTIVATIONpara contas STALLED/AT_RISK - [x] Incluir estratégia sugerida na action
Fase 12: Integração Seller Cockpit (Frontend)
- [x] Criar componente
components/reactivation/ReactivationCard.jsx - [x] Criar componente
components/reactivation/StrategyBadge.jsx - [x] Adicionar tratamento para actionType
REACTIVATIONnoInboxPage.jsx - [x] Mostrar estratégia sugerida e limites no detalhe da ação
- [x] Botões de ação: "Iniciar Reativação", "Registrar Resultado"
Fase 13: Documentação
- [x] Criar
README.mdcompleto - [x] Documentar API endpoints
- [x] Documentar estratégias
- [ ] Atualizar
AGENTS_OVERVIEW.md
Fase 14: Testes
- [ ] Testar cada endpoint
- [ ] Testar seleção de estratégia
- [ ] Testar limites de desconto
- [ ] Testar registro de outcome
- [ ] Testar integração com Account State
- [ ] Testar visualização no Seller Cockpit
📁 Estrutura de Arquivos
reactivation/
├── .env.example
├── Dockerfile
├── README.md
├── deploy.sh
├── docker-stack.yml
├── main.py
├── requirements.txt
├── app/
│ ├── __init__.py
│ ├── database.py
│ ├── heuristics.py
│ ├── models.py
│ ├── nba_client.py
│ ├── pricing_client.py
│ ├── repository.py
│ ├── settings.py
│ └── state_client.py
├── policies/
│ ├── __init__.py
│ └── reactivation.py
├── routes/
│ ├── __init__.py
│ ├── core.py
│ └── reactivation.py
└── sql/
├── schema.sql
└── views.sql
🔌 API Endpoints
| Método | Endpoint | Descrição |
|---|---|---|
| GET | / |
Info do serviço |
| GET | /health |
Health check |
| GET | /v1/reactivation/candidates |
Candidatos à reativação |
| POST | /v1/reactivation/create |
Criar tentativa |
| GET | /v1/reactivation/attempt/{id} |
Consultar tentativa |
| POST | /v1/reactivation/attempt/{id}/start |
Iniciar execução |
| POST | /v1/reactivation/attempt/{id}/outcome |
Registrar resultado |
| GET | /v1/reactivation/active |
Tentativas em andamento |
| GET | /v1/reactivation/history/{account_id} |
Histórico de tentativas |
| GET | /v1/reactivation/metrics |
KPIs de reativação |
| GET | /v1/reactivation/strategy-effectiveness |
Eficácia por estratégia |
📊 Schema SQL Principal
CREATE TABLE IF NOT EXISTS channel_reactivation_attempts (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
org_id INT NOT NULL DEFAULT 1,
account_id VARCHAR(100) NOT NULL,
attempt_number INT NOT NULL DEFAULT 1,
-- Trigger Info
trigger_state ENUM('STALLED', 'AT_RISK') NOT NULL,
trigger_reason VARCHAR(255),
days_inactive INT,
risk_value DECIMAL(15,2), -- Valor em risco (receita anual)
-- Strategy
strategy ENUM('INCENTIVE_DISCOUNT', 'PRODUCT_MIX', 'PERSONAL_CONTACT', 'SPECIAL_CONDITION', 'WAIT') NOT NULL,
strategy_params JSON,
max_discount_allowed DECIMAL(5,2),
suggested_products JSON,
suggested_message TEXT,
-- Execution
status ENUM('PLANNED', 'IN_PROGRESS', 'WON', 'LOST', 'CANCELLED') NOT NULL DEFAULT 'PLANNED',
assigned_to VARCHAR(50), -- seller_id
started_at DATETIME,
completed_at DATETIME,
-- Contacts
contact_attempts INT DEFAULT 0,
last_contact_at DATETIME,
last_contact_channel VARCHAR(20),
-- Outcome
outcome_type ENUM('REACTIVATED', 'PARTIAL', 'NO_RESPONSE', 'DECLINED', 'CHURNED'),
outcome_notes TEXT,
next_order_at DATE,
next_order_value DECIMAL(15,2),
actual_discount_given DECIMAL(5,2),
-- Cost
attempt_cost DECIMAL(10,2) DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_account (account_id),
INDEX idx_status (status),
INDEX idx_strategy (strategy),
INDEX idx_outcome (outcome_type)
);
🎨 UI no Seller Cockpit
Inbox - Card de Reativação
┌─────────────────────────────────────────────────────┐
│ 🔴 REATIVAÇÃO Urgente │
├─────────────────────────────────────────────────────┤
│ Atacadão Norte │
│ 🟠 AT_RISK • Inativo há 45 dias │
│ R$ 320.000/ano em risco │
│ │
│ 📋 Estratégia sugerida: INCENTIVE_DISCOUNT │
│ ┌─────────────────────────────────────────────────┐ │
│ │ • Desconto máximo: 5% │ │
│ │ • Produtos: Linha Premium │ │
│ │ • Canal: WhatsApp + Ligação │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Tentativa: 1 de 3 │
│ │
│ [🚀 Iniciar] [💬 WhatsApp] [📞 Ligar] [❌ Descartar] │
└─────────────────────────────────────────────────────┘
📊 KPIs a Monitorar
| KPI | Descrição | Meta |
|---|---|---|
| Taxa de Reativação | % de contas reativadas | > 40% |
| Margem Pós-Reativação | Margem após retorno | > 15% |
| Tempo até Nova Compra | Dias até pedido | < 15 dias |
| Custo por Tentativa | Custo médio | < R$ 50 |
| Reincidência | % que volta a ficar inativo | < 20% |
✅ Critérios de Conclusão
- [ ] Candidatos sendo identificados automaticamente
- [ ] Estratégias sendo selecionadas corretamente
- [ ] Limites de desconto sendo respeitados
- [ ] Outcomes sendo registrados
- [ ] Account State atualizando após outcome
- [ ] Card de reativação visível no Inbox
- [ ] Métricas calculadas
- [ ] README completo
- [ ] Deploy em DEV funcionando
Atualizado: 2026-01-24