Resumão
- Caso 598931185 (GONCALVES BOSON ARRUDA): trial venceu 19/05 e o cron já cobrou via PLG. R$ 293,55 pro-rata foram somados na receita de junho/2026 (aberta) e R$ 700 nas seis receitas seguintes (jul–dez), inclusive já atualizadas no Asaas. Pra dar +30d de trial, precisa reverter receitas + Asaas + aditivo. Passo a passo abaixo.
- Rollout 30d pra base toda: universo bruto é 33.159 escritórios não-bloqueados que ainda não foram tocados pelo piloto. Pra ser cirúrgico, precisa do mesmo filtro que o JV usou no piloto (planilha externa) — ou destila pelo banco com critérios adicionais. Queries prontas abaixo.
- Documentação: existe runbook + memory + Confluence. Tem tudo, só não está centralizado num lugar só. Mapa abaixo.
1 Renovar trial de 598931185 sem deixar resquício
Estado atual no banco
- Escritório
- 598931185 — GONCALVES BOSON ARRUDA ADVOGADOS
- id_aditivo
- 35
- Tier
- enterprise (R$ 700/mês · 600.000 reqs)
- Coorte
- A (trial 7d)
- status_api
- ativo (passou de
em_periodo_testeem 19/05 17:09) - data_inicio_trial
- 2026-05-12 16:38:12
- data_fim_trial
- 2026-05-19 16:38:12
- data_proxima_cobranca
- 2026-06-19 17:09:23
- id_pagador_vinculado
- 680529204
Sim, já gerou cobrança
Quando o cron cron_trial_para_ativo.php rodou em 19/05 17:09, ele executou processar_contratacao_plg. O PLG somou o valor da API nas faturas em aberto do pagador e atualizou cada cobrança correspondente no Asaas. Reflexo em tb_receitas (id_pagador=680529204):
| id_receita | Vencimento | Valor antes | Valor depois | Δ (API) | Asaas | Status |
|---|---|---|---|---|---|---|
| 4477164 | 2026-06-10 | 7.720,05 | 8.013,60 | +293,55 (pro-rata) | pay_ecr891eqggo78ron | A aberta |
| 4477165 | 2026-07-10 | 7.720,05 | 8.420,05 | +700,00 | pay_v5b3jk9yfzzfbkkh | A aberta |
| 4477166 | 2026-08-10 | 7.720,05 | 8.420,05 | +700,00 | pay_pqisixssgisfk11t | A aberta |
| 4477167 | 2026-09-10 | 7.720,05 | 8.420,05 | +700,00 | (ver tb_receitas) | A aberta |
| 4477168 | 2026-10-10 | 7.720,05 | 8.420,05 | +700,00 | (ver tb_receitas) | A aberta |
| 4477169 | 2026-11-10 | 7.720,05 | 8.420,05 | +700,00 | (ver tb_receitas) | A aberta |
| 4477170 | 2026-12-10 | 7.720,05 | 8.420,05 | +700,00 | (ver tb_receitas) | A aberta |
| Total adicionado da API | +4.493,55 | |||||
Além disso, foram criadas 7 linhas em tb_aditivos_pagamentos (id 592–598) com id_receita = NULL — essa tabela é apenas rastreio do PLG, não é a cobrança em si. A cobrança real vive em tb_receitas + Asaas.
Por que sumiu de junho R$ 293,55? O PLG aplicou pro-rata de 13 dias (19–31/05) na próxima fatura em aberto, que era a de junho (vencimento 10/06). Não criou uma fatura nova de maio.
Passos pra estender +30d sem deixar resquício
Reverter cobrança no Asaas (7 PUTs)
Pra cada uma das 7 receitas afetadas, fazer PUT na cobrança Asaas via API do Asaas pra restaurar o valor original (subtrair o delta da API). Use a função send_asaas_payment_update_put($data, $id_pagamento_asaas, $token_master) com ['value' => valor_original]:
// Pseudo-código (deve rodar via script PHP no monolito, em produção, master token)
$reversoes = [
['id_receita' => 4477164, 'asaas' => 'pay_ecr891eqggo78ron', 'novo_valor' => 7720.05], // jun
['id_receita' => 4477165, 'asaas' => 'pay_v5b3jk9yfzzfbkkh', 'novo_valor' => 7720.05], // jul
['id_receita' => 4477166, 'asaas' => 'pay_pqisixssgisfk11t', 'novo_valor' => 7720.05], // ago
// ... seguir pra 4477167, 4477168, 4477169, 4477170
];
foreach ($reversoes as $r) {
send_asaas_payment_update_put(['value' => $r['novo_valor']], $r['asaas'], get_master_token());
}
Os pay_* faltando pra setembro–dezembro estão em tb_receitas.id_pagamento_asaas. Vide query #2 abaixo.
Reverter as 7 receitas no banco
USE advogados_iturn;
START TRANSACTION;
-- 1ª receita (junho): subtrair pro-rata
UPDATE tb_receitas
SET valor = valor - 293.55,
valor_total = valor_total - 293.55,
observacao = CONCAT(observacao, CHAR(10), '[REVERSAO ', NOW(), '] -R$ 293,55 - API EasyJur (extensao de trial)')
WHERE id = 4477164;
-- Outras 6 (jul–dez): subtrair mensalidade
UPDATE tb_receitas
SET valor = valor - 700.00,
valor_total = valor_total - 700.00,
observacao = CONCAT(observacao, CHAR(10), '[REVERSAO ', NOW(), '] -R$ 700,00 - API EasyJur (extensao de trial)')
WHERE id IN (4477165, 4477166, 4477167, 4477168, 4477169, 4477170);
-- Confirmar valores voltaram a R$ 7.720,05 nas 7
SELECT id, data_vencimento, valor, valor_total
FROM tb_receitas
WHERE id BETWEEN 4477164 AND 4477170
ORDER BY id;
-- Se ok:
COMMIT;
-- Se errado:
-- ROLLBACK;
Limpar o rastreio em tb_aditivos_pagamentos
USE advogados_iturn; -- Confirmar que são exatamente as 7 que entraram em 19/05 e ainda não viraram receita SELECT id, mes_competencia, valor, tipo, id_receita FROM tb_aditivos_pagamentos WHERE id_aditivo = 35 AND id_receita IS NULL; -- Esperado: 7 linhas (ids 592 a 598) -- Deletar DELETE FROM tb_aditivos_pagamentos WHERE id_aditivo = 35 AND id_receita IS NULL;
id_receita IS NULL é a salvaguarda — garante que não vai apagar algo que já virou fatura paga (caso futuro do mesmo aditivo). Hoje, todas as 7 são NULL, então o DELETE pega exatamente o que entrou no cron.
Voltar o aditivo pra trial + estender 30 dias
USE advogados_iturn;
START TRANSACTION;
UPDATE tb_aditivos_api_easyjur
SET status_api = 'em_periodo_teste',
data_fim_trial = DATE_ADD(NOW(), INTERVAL 30 DAY),
data_proxima_cobranca = DATE_ADD(NOW(), INTERVAL 31 DAY),
data_cancelamento = NULL,
coorte = 'C', -- opcional: marcar como 30d
updated_at = NOW()
WHERE id_empresa = 598931185;
-- Validar
SELECT id, id_empresa, tier, coorte, status_api,
data_inicio_trial, data_fim_trial, data_proxima_cobranca, data_cancelamento
FROM tb_aditivos_api_easyjur
WHERE id_empresa = 598931185;
-- Se ok:
COMMIT;
Mudar a coorte pra C é opcional — só ajuda a refletir "trial 30d" em relatórios e no comportamento esperado quando vencer (cobrança automática igual A/B/C). Se preferir manter coorte A no histórico, só não inclua a linha coorte = 'C'.
Sanity check final
-- Confirmar estado do aditivo SELECT id, status_api, data_fim_trial, data_proxima_cobranca FROM tb_aditivos_api_easyjur WHERE id_empresa = 598931185; -- Esperado: status_api='em_periodo_teste', data_fim_trial = hoje+30d -- Confirmar receitas restauradas SELECT id, data_vencimento, valor, valor_total FROM tb_receitas WHERE id BETWEEN 4477164 AND 4477170 ORDER BY id; -- Esperado: todas com valor=7720.05 e valor_total=7720.05 -- Confirmar tb_aditivos_pagamentos limpa SELECT COUNT(*) FROM tb_aditivos_pagamentos WHERE id_aditivo = 35; -- Esperado: 0
Queries de apoio
Query 1 — Diagnóstico de qualquer escritório (estado completo do aditivo):
SELECT a.id, a.id_empresa, ea.nome, a.tier, a.coorte, a.status_api,
p.preco_centavos/100 AS preco_mes,
a.data_inicio_trial, a.data_fim_trial,
a.data_proxima_cobranca, a.data_cancelamento,
a.updated_at,
(SELECT COUNT(*) FROM tb_aditivos_pagamentos
WHERE id_aditivo = a.id) AS rastreios_pagamento,
ea.id_pagador_vinculado
FROM tb_aditivos_api_easyjur a
LEFT JOIN tb_api_pacotes p ON p.id = a.id_pacote
LEFT JOIN tb_escritorio_advogados ea ON ea.id = a.id_empresa
WHERE a.id_empresa = 598931185; -- trocar pelo id alvo
Query 2 — Receitas afetadas pelo PLG (todas as 7 do exemplo):
SELECT id, id_pagador, valor, valor_total, status,
data_cadastro, data_vencimento, id_pagamento_asaas,
LEFT(observacao, 300) AS observacao
FROM tb_receitas
WHERE id_pagador = 680529204
AND observacao LIKE '%API EasyJur%'
AND status = 'A' -- aberta (não pode reverter receita paga sem chargeback)
ORDER BY data_vencimento;
Query 3 — Rastreio em tb_aditivos_pagamentos (espelho do PLG):
SELECT id, id_aditivo, produto, id_empresa, mes_competencia, valor, tipo, id_receita, created_at FROM tb_aditivos_pagamentos WHERE id_empresa = 598931185 ORDER BY mes_competencia;
status='A'), a reversão é segura e o cliente não fica sabendo.
status='P') quando você for executar, pare e chame o financeiro: reverter receita paga vira estorno no Asaas + nota de crédito, fora do escopo deste runbook.
2 Rollout 30d pra base toda — mapeamento dos não-elegíveis
Universo bruto hoje
| Grupo | Qtd | Observação |
|---|---|---|
| Escritórios totais | 35.463 | Tudo em tb_escritorio_advogados |
| — Bloqueados | 1.952 | bloqueado=1 · não devem entrar no rollout |
| — NULL | 29 | Inconsistência histórica |
| Não bloqueados | 33.511 | COALESCE(bloqueado,0)=0 |
| — Já elegíveis (piloto) | 359 | Em tb_aditivos_api_easyjur_elegiveis |
| — Já com aditivo | 117 | Em tb_aditivos_api_easyjur (trial/ativo/cancelado) |
| Candidatos brutos ao rollout | 33.159 | Não bloqueados ∩ sem elegibilidade ∩ sem aditivo |
Sim, precisa de uma planilha
33 mil escritórios é o universo bruto, mas nem todos têm plano ativo, alguns são contas trial vazias, outros são clientes históricos sem atividade. O piloto original (359) já passou por um filtro externo pelo time do JV/Hideo (planilha c350.xlsx) usando critérios que o banco não tem em coluna única:
- Cliente ativo com plano pago (≠ Trial, ≠ juris_ai, ≠ legal_crm)
- Login ≥ 20 nos últimos 30d (proxy de "usa o sistema")
- Health ≠ Crítico (puxado do CustomerX)
- Pagamento mensal (cartão e à vista anual ficaram de fora em 28/04 e voltaram como Grupo D)
Pro rollout 30d, recomendação prática:
- Pedir ao Hideo/JV uma planilha equivalente à
c350.xlsxcom os critérios desta nova fase. Mesma estrutura:id_empresa,nome,tier_sugerido. - Aplicar o seed usando o mesmo padrão do D-day original: cria registros em
tb_aditivos_api_easyjur_elegiveiscomstatus_aceite='pending'ecoorte='C'(30d). O modal aparece pro admin do escritório no próximo login. - Não usar caminho B direto (ativação sem modal) pro rollout em massa — isso bypassa o aceite formal e pode gerar dor de cabeça com financeiro/jurídico se cliente reclamar.
Query — universo candidato (com nome e plano)
SELECT
e.id AS id_empresa,
e.nome,
e.cnpj,
e.tipo_perfil,
e.juris_ai,
e.tamanho_escritorio,
e.data_cadastro,
e.data_expiracao
FROM tb_escritorio_advogados e
WHERE COALESCE(e.bloqueado, 0) = 0
AND e.id NOT IN (SELECT id_empresa FROM tb_aditivos_api_easyjur_elegiveis)
AND e.id NOT IN (SELECT id_empresa FROM tb_aditivos_api_easyjur)
AND (e.data_expiracao IS NULL OR e.data_expiracao > NOW()) -- sem plano vencido
ORDER BY e.data_cadastro DESC;
Quando a planilha chegar — template de seed
Assumindo que o Hideo/JV mande um CSV com colunas id_empresa, tier_sugerido, o seed segue o padrão do D-day:
-- Pra cada linha da planilha, rodar (com cuidado: validar nº de linhas afetadas)
INSERT INTO tb_aditivos_api_easyjur_elegiveis
(id_empresa, id_pacote_sugerido, tier_sugerido, coorte,
status_aceite, created_at, updated_at)
SELECT
@id_empresa,
(SELECT id FROM tb_api_pacotes WHERE slug = @tier_sugerido AND ativo = 1),
@tier_sugerido,
'C', -- 30 dias
'pending',
NOW(), NOW()
ON DUPLICATE KEY UPDATE
id_pacote_sugerido = VALUES(id_pacote_sugerido),
tier_sugerido = VALUES(tier_sugerido),
coorte = VALUES(coorte),
status_aceite = 'pending',
updated_at = NOW();
Quando o admin do escritório fizer login no SGR, o modal de aceite aparece (mesmo fluxo do piloto). Aceitou → cria tb_aditivos_api_easyjur com status_api='em_periodo_teste', trial de 30 dias, cobrança automática após vencer. Igual coorte C do piloto.
Script Python pra gerar o seed (opcional)
O piloto usou ~/claude/api-launch-v1/scripts/gen_d_day_seed_sql.py (lê XLSX e cospe SQL idempotente). Pra reutilizar, basta trocar o input pelo CSV/XLSX novo e ajustar a coorte default pra 'C'.
3 Documentação da API EasyJur
Existe sim — está distribuída, mapa abaixo
1. Confluence — visão de produto e modelo de cobrança
Lançamento da API V1 — Discovery, Plano de Execução e Preparação Organizacional Decisão dos 7 tiers fixos, cronograma, A/B test de coortes (7d/14d/30d), FAQ comercial, concessões pré-aprovadas, perfil de cada coorte. Leitura obrigatória.2. Runbooks operacionais
Runbook — Ativar Trial via Banco Caminho B (direto via SQL, sem modal) e caminho A (gera modal de aceite). Cobre clientes novos; não cobre reverter de "ativo" pra "trial" — pra isso, ver Dúvida 1 acima. Este documento (Dúvida 1) Passo a passo pra estender trial após o aditivo já ter virado ativo — não documentado em outro lugar até hoje. Salvar este link.3. Schema do banco (3 tabelas centrais)
| Tabela | O que guarda | Quem escreve |
|---|---|---|
tb_api_pacotes |
Catálogo dos 7 tiers (slug, créditos/mês, preço) | Read-only no dia-a-dia · só admin via migration |
tb_aditivos_api_easyjur_elegiveis |
Quem está elegível pra ativar API + status do aceite (pending/acknowledged/declined). Aqui mora a coorte sugerida. | Seed do D-day (massa) · clique do admin no modal (aceitar_api.php) |
tb_aditivos_api_easyjur |
Aditivo de fato (1 linha por escritório). Tem o status_api (em_periodo_teste/ativo/cancelado), o tier contratado, datas de trial/cobrança |
aceitar_api.php ao virar trial · cron_trial_para_ativo.php ao virar ativo · scripts manuais (este runbook) |
tb_aditivos_pagamentos |
Rastreio dos pagamentos planejados (1 linha por mês de competência). Não é a cobrança em si — é só log do que o PLG agendou. | processar_contratacao_plg ao registrar contratação |
tb_receitas |
Cobrança real (= fatura). Quando o PLG cobra, ele SOMA o valor da API numa receita em aberto existente. | Sistema financeiro completo · PLG soma valor |
4. Código no monolito
| Arquivo | O que faz |
|---|---|
sgr/advogados/scripts/minha_assinatura/api_easyjur/api/contratar.php | Endpoint que o admin chama ao clicar "Aceitar" no modal |
sgr/advogados/scripts/minha_assinatura/api_easyjur/helpers/cron_trial.php | Lógica do cron diário que vira trial → ativo (ou cancela pra coorte D) |
sgr/rotinas/api_easyjur/cron_trial_para_ativo.php | Entrypoint do cron (chamado via systemd timer) |
sgr/advogados/scripts/minha_assinatura/api_easyjur/utils/pagamentos.php | Função registrar_pagamentos_aditivo() que insere as linhas em tb_aditivos_pagamentos |
sgr/advogados/scripts/minha_assinatura/api_easyjur/api/subir_tier.php | Endpoint pra cliente mudar de tier durante trial/ativo |
sgr/advogados/scripts/minha_assinatura/utils/functions.php | processar_contratacao_plg() — o motor da cobrança PLG (linha 119+) |
5. Código no Turin (API que valida e contabiliza chamadas)
| Arquivo | O que faz |
|---|---|
turin/services/aditivo_service.py | Validação do aditivo (status, quota) na hora de cada chamada |
turin/services/quota_service.py | track_request() · indexa cada chamada no ES + agrega contador mensal |
turin/repositories/aditivo_repo.py | Acesso ao banco · lê de tb_aditivos_api_easyjur |
6. Logs e métricas
- Elasticsearch índice
api_easyjur_requests— toda chamada autenticada à API (track_request) - Elasticsearch índice
easyjur-logs-plg— eventos PLG (contratação, atualização Asaas, etc) - Kibana dashboard exportado em
~/claude/api-launch-v1/kibana-dashboard-api-easyjur.ndjson - Receita estipulada: relatorios.easyjur.ygarasab.com/receita-estipulada.html · atualizado periodicamente · todas as queries SQL prontas
Resumo do fluxo end-to-end (mapa mental)
D-day (seed) → tb_aditivos_api_easyjur_elegiveis (status_aceite='pending')
│
Admin clica "Aceitar" │
no modal SGR │
▼
aceitar_api.php → tb_aditivos_api_easyjur (status_api='em_periodo_teste')
│
Trial roda N dias │
(coorte A=7d, B=14d, C=30d, D=7d sem cobrança)
▼
cron_trial_para_ativo → Coorte D: status_api='cancelado' (fim)
→ Coorte A/B/C: processar_contratacao_plg
│
├─ Soma valor na tb_receitas (fatura aberta) → Asaas PUT
├─ INSERT em tb_aditivos_pagamentos (rastreio)
└─ UPDATE tb_aditivos_api_easyjur SET status_api='ativo'
Cliente faz chamada → Turin valida aditivo em tb_aditivos_api_easyjur
→ quota_service.track_request() indexa no ES
→ 429 se estourou quota