Expirar assinatura PRO quando a filiação CITRG deixa de ser válida

TLDR: Em todo sign-in de terapeuta (e tentativa de assinar o PRO), se a filiação CITRG estiver expirada ou ausente, expirar a assinatura PRO local e restaurar o plano de terapeuta regular — hoje o resultado da elegibilidade é calculado e descartado, então o acesso PRO nunca termina.

Contexto

Usuários mantêm o acesso ao TRG Club depois que a filiação CITRG expira. O fluxo de sign-in já consulta o CITRG em todo login (Subscriptions::Pro::AutoSubscribeJob → Creation::CreateFlow → ValidateEligibility lê valid_until_timestamp), mas quando o usuário já tem uma assinatura PRO ativa o flow para no ValidateExistingSubscription (“Você já possui um plano PRO ativo”) antes de reagir a pro_eligible == false. A assinatura PRO é criada com expires_at = nil, então permanece ativa para sempre.

Modelo de negócio: terapeuta regular = certificado Apolo válido (verificado no login); PRO = regular + filiação CITRG válida. Quando a filiação CITRG caduca, o usuário deve ser rebaixado de PRO para regular — não manter o PRO.

Objetivos

  • Rebaixar (expirar) a assinatura PRO no login/subscribe quando o CITRG indicar que a filiação não é mais válida
  • Restaurar a assinatura de terapeuta regular na mesma transação, já que o usuário ainda tem certificado Apolo válido (acabou de logar por ele)
  • Permitir a repromoção ao PRO depois que o usuário renovar a filiação CITRG — o ciclo completo precisa funcionar

Fora de escopo

  • Job recorrente para rebaixar usuários PRO que nunca mais fazem sign-in (os tokens se auto-renovam, então verificações só no login não cobrem usuários sempre online) — endereçado depois em downgrade_on_citrg_expiry_webhook
  • Expiração da janela de 12 meses da plataforma de aulas Apolo (Anjo/Tutelado) — bloqueado pela definição da fonte da verdade dessa janela

Mudanças

  • app/use_cases/subscriptions/pro/expire_when_ineligible.rb (novo): quando pro_eligible é false e o usuário tem uma assinatura PRO pending/active não expirada, expirá-la (status: :inactive, expires_at: Time.current) e reativar a assinatura de terapeuta regular (status: :active, expires_at: nil) numa única transação
  • app/use_cases/subscriptions/pro/creation/create_flow.rb: inserir ExpireWhenIneligible logo após ValidateEligibility
  • app/use_cases/subscriptions/pro/creation/create_subscription.rb: limpar expires_at ao (re)ativar uma assinatura PRO existente, para que uma filiação renovada repromova corretamente
  • Specs: spec unitário do novo use case; request spec cobrindo o cenário de rebaixamento ponta a ponta via POST /api/v1/subscriptions/pros, com a cassete VCR do CITRG já existente e uma data viajada para depois do valid_until (2026-01-31)

Como verificar

  • make test test=spec/use_cases/subscriptions/pro/expire_when_ineligible_spec.rb
  • make test test=spec/requests/api/v1/subscriptions/pros_create_spec.rb spec/requests/api/v1/subscriptions/pros_expire_when_ineligible_spec.rb
  • Manual: terapeuta com filiação expirada faz sign-in → user.active_pro? fica false e user.subscription é o plano de terapeuta regular; após renovar a filiação e logar de novo → o PRO volta a ficar ativo

Documentação