API EasyJur — Respostas pro Escudeiro

Gerado em 2026-05-20 · dados de produção (read-only)

Resumão

  1. 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.
  2. 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.
  3. 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

Preciso renovar o período de teste por mais 30 dias de um escritório (598931185) que finalizou o período ontem. No status, consta como 'ativo', aí não sei se já teve cobrança atribuída (porque se teve, teríamos que cancelar/etc), ou como certificar que se eu alterar só o status e o data_fim, não vai ter resquício em outro canto. Porque parece que já gerou cobranças pra ele.

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_teste em 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
44771642026-06-107.720,058.013,60+293,55 (pro-rata)pay_ecr891eqggo78ronA aberta
44771652026-07-107.720,058.420,05+700,00pay_v5b3jk9yfzzfbkkhA aberta
44771662026-08-107.720,058.420,05+700,00pay_pqisixssgisfk11tA aberta
44771672026-09-107.720,058.420,05+700,00(ver tb_receitas)A aberta
44771682026-10-107.720,058.420,05+700,00(ver tb_receitas)A aberta
44771692026-11-107.720,058.420,05+700,00(ver tb_receitas)A aberta
44771702026-12-107.720,058.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

Ordem importa: reverter o Asaas antes de mexer no banco. Se reverter o banco primeiro e o PUT no Asaas falhar, o cliente recebe boleto com valor errado e o sistema não sabe disso.
1

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.

2

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;
3

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;
Filtro 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.
4

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'.

5

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;
Resumo: não dá pra "só mudar status e data_fim". A cobrança PLG é fan-out (banco + Asaas), tem que reverter os dois lados. Como nada foi pago ainda (todas em status='A'), a reversão é segura e o cliente não fica sabendo.
Se alguma receita já estiver paga (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

Durante a semana que vem, iremos disponibilizar para todos os clientes esse trial da API, com um período de 30 dias. Aí nesse caso, vai ser necessário estruturar algum script ou planilha com o mapeamento dos que não foram ativados ainda pra isso?

Universo bruto hoje

GrupoQtdObservação
Escritórios totais35.463Tudo em tb_escritorio_advogados
— Bloqueados1.952bloqueado=1 · não devem entrar no rollout
— NULL29Inconsistência histórica
Não bloqueados33.511COALESCE(bloqueado,0)=0
— Já elegíveis (piloto)359Em tb_aditivos_api_easyjur_elegiveis
— Já com aditivo117Em tb_aditivos_api_easyjur (trial/ativo/cancelado)
Candidatos brutos ao rollout33.159Nã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:

Pro rollout 30d, recomendação prática:

  1. Pedir ao Hideo/JV uma planilha equivalente à c350.xlsx com os critérios desta nova fase. Mesma estrutura: id_empresa, nome, tier_sugerido.
  2. Aplicar o seed usando o mesmo padrão do D-day original: cria registros em tb_aditivos_api_easyjur_elegiveis com status_aceite='pending' e coorte='C' (30d). O modal aparece pro admin do escritório no próximo login.
  3. 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.

Lembrete: coorte D (cartão/avista, sem cobrança automática) teve retenção de 16% no piloto (16/19 cancelaram). Se o rollout pegar esse perfil de cliente, esperar conversão muito menor que coortes A/B/C.

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 alguma documentação que documente como tá estruturada a API em geral (ou onde/como) os dados estão estruturados? Pra caso seja necessário fazer renovação de trial, etc.

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 page 1668186114 · autor JV · v2.0 · canônico 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 https://relatorios.easyjur.ygarasab.com/api-launch-v1/runbook-ativacao-trial.html 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) ~/claude/turin-avancado/site/respostas-escudeiro.html 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)

TabelaO que guardaQuem 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

ArquivoO que faz
sgr/advogados/scripts/minha_assinatura/api_easyjur/api/contratar.phpEndpoint que o admin chama ao clicar "Aceitar" no modal
sgr/advogados/scripts/minha_assinatura/api_easyjur/helpers/cron_trial.phpLógica do cron diário que vira trial → ativo (ou cancela pra coorte D)
sgr/rotinas/api_easyjur/cron_trial_para_ativo.phpEntrypoint do cron (chamado via systemd timer)
sgr/advogados/scripts/minha_assinatura/api_easyjur/utils/pagamentos.phpFunção registrar_pagamentos_aditivo() que insere as linhas em tb_aditivos_pagamentos
sgr/advogados/scripts/minha_assinatura/api_easyjur/api/subir_tier.phpEndpoint pra cliente mudar de tier durante trial/ativo
sgr/advogados/scripts/minha_assinatura/utils/functions.phpprocessar_contratacao_plg() — o motor da cobrança PLG (linha 119+)

5. Código no Turin (API que valida e contabiliza chamadas)

ArquivoO que faz
turin/services/aditivo_service.pyValidação do aditivo (status, quota) na hora de cada chamada
turin/services/quota_service.pytrack_request() · indexa cada chamada no ES + agrega contador mensal
turin/repositories/aditivo_repo.pyAcesso ao banco · lê de tb_aditivos_api_easyjur

6. Logs e métricas

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