Rebaixamento de PRO na expiração da filiação CITRG
TLDR: A assinatura PRO depende de uma filiação CITRG válida; o rebaixamento é sempre decidido pelo mesmo fluxo confiável, disparado por dois gatilhos — o login do terapeuta e o webhook diário de expiração da citrg-api.
Visão geral
A assinatura PRO de um terapeuta depende de uma filiação CITRG válida. O rebaixamento é sempre decidido pelo mesmo fluxo confiável:
Subscriptions::Pro::Creation::CreateFlow → ValidateEligibility (consulta ao CITRG por e-mail, em tempo real) → ExpireWhenIneligible (define a assinatura PRO como inactive e reativa regular-terapeuta).
A regra de negócio que esse fluxo aplica está em R-003; os critérios de elegibilidade, em R-004.
Fluxo
mermaid
graph TD
L["Sign-in do terapeuta"] --> AS["auto_subscribe_pro<br/>AutoSubscribeJob.perform_now"]
AS --> CF["Creation::CreateFlow"]
W["Cron diário da citrg-api"] --> WH["POST /citrg/memberships/expired<br/>MembershipExpirationsController"]
WH --> LOOK{"usuário encontrado<br/>pelo e-mail?"}
LOOK -->|não| OK200["200 + log — citrg não retenta"]
LOOK -->|sim| EWI
CF --> VE["ValidateEligibility<br/>consulta o CITRG"]
VE --> EWI["ExpireWhenIneligible<br/>PRO inactive + regular ativo"]
style W fill:#1f2937,color:#fff
style L fill:#1f2937,color:#fff
style EWI fill:#374151,color:#fff
Gatilhos
- Login (já existia): sign-in do terapeuta →
auto_subscribe_pro→Subscriptions::Pro::AutoSubscribeJob.perform_now. - Webhook de expiração do CITRG (fora do login): o cron diário de expiração da citrg-api envia
{ email, register_number }paraPOST /citrg/memberships/expired(CITRG::MembershipExpirationsController). O controller localiza o usuário pelo e-mail (normalizado) e rebaixa inline viaSubscriptions::Pro::ExpireWhenIneligible.call(user:, pro_eligible: false).
Contratos
| Aspecto | Definição |
|---|---|
| Transporte | POST JSON para /citrg/memberships/expired |
| Autenticação | Segredo compartilhado no header X-Security-Signature-Token |
| Corpo | { "email": "<e-mail do filiado>", "register_number": <bigint> } |
| Chave de correspondência | email (canônico para busca de filiação nos dois lados) |
| Resposta | 200 para conhecido, desconhecido e reentrega; 401 para token inválido |
Propriedades de segurança
- O webhook é tratado como autoritativo: a citrg-api só o envia após a própria guarda de renovação (filiados com renovação paga e
valid_untilposterior nunca são notificados), então o trg-club rebaixa direto, sem reconsultar o CITRG. Isso evita perder o evento quando o CITRG está momentaneamente indisponível no momento do processamento. Um filiado rebaixado por engano é restaurado no próximo login (auto_subscribe_prorecria a assinatura PRO para filiados elegíveis). - Idempotente: a reentrega do mesmo webhook é no-op depois que a assinatura PRO já está inativa.
- E-mails desconhecidos retornam
200(com log) para que a citrg não fique retentando filiados sem conta no trg-club. - Autenticação: segredo compartilhado no header
X-Security-Signature-Token. OCITRG_WEBHOOK_TOKENreaproveita o token de integração trg-club↔citrg já existente (envCITRG_MEMBERSHIP_TOKEN/ credencialcitrg.api_membership_token— o mesmo valor que a citrg-api valida comoapolo-access-token). Token em branco rejeita todas as requisições.
Referências
app/controllers/citrg/membership_expirations_controller.rbconfig/initializers/citrg.rb(CITRG_WEBHOOK_TOKEN)config/routes.rb(namespacecitrg)- Spec de origem: 20260709170553_downgrade_on_citrg_expiry_webhook