Simplificar campos do admin de Trial

TLDR: remove “Permite renovação?” e “Acesso a biblioteca de áudios?” da tela do admin de Trial, e trava “Limite de áudios” para ser sempre igual a “Duração (dias)”, exibido como campo desabilitado.

Contexto

Esses três campos existem no admin de Trial (apps/trials/admin.py) mas não serão usados por enquanto: allow_renewal, access_library_audios e audio_limit como valor independente. A regra de negócio atual é que o limite de áudios do trial deve sempre coincidir com a duração em dias do trial, e não deve ser configurado manualmente.

Objetivos

  • Remover “Permite renovação?” (allow_renewal) da tela do admin de Trial (fieldsets, list_display, list_filter).
  • Remover “Acesso a biblioteca de áudios?” (access_library_audios) da tela do admin de Trial (fieldsets).
  • Fazer audio_limit sempre valer o mesmo que duration_days, sincronizado a cada save do modelo (não só via admin), e exibido no admin como campo desabilitado (somente leitura).

Fora de escopo

  • Remover as colunas allow_renewal e access_library_audios do modelo/banco — permanecem no modelo e no banco, só saem da UI do admin.
  • Migration de backfill para audio_limit de trials já existentes — a sincronização passa a valer só para trials salvos a partir desta mudança.
  • Mudanças em apps/common/management/commands/seed.py — os seeds continuam passando allow_renewal explicitamente (campo continua existindo no modelo) e não precisam declarar audio_limit/access_library_audios, que serão sobrescritos no save().
  • Mudanças na API pública (UserTrialStateSerializer) — ela já lê trial.access_library_audios e trial.audio_limit, que continuarão existindo e agora sempre coerentes.

Mudanças

apps/trials/models/trial.py - Sobrescrever save() em Trial para, antes de persistir: self.audio_limit = self.duration_days e self.access_library_audios = True. Isso garante o invariante em qualquer caminho de escrita (admin, seed, shell), não só no admin.

apps/trials/admin.py (TrialAdmin) - list_display: remover "allow_renewal". - list_filter: remover "allow_renewal". - Fieldset “Informações”: remover "allow_renewal" da tupla de fields. - Fieldset “Permissões”: remover "access_library_audios" da tupla de fields, mantendo "features" e "audio_limit".

apps/trials/forms.py (TrialAdminForm) - Meta.exclude = ("allow_renewal", "access_library_audios") no lugar de fields = "__all__" (mantém features declarado explicitamente, que continua incluído independente do exclude). - Declarar audio_limit explicitamente no form com disabled=True (renderiza disabled no HTML; Django ignora o valor postado e usa o initial na validação). - Em __init__, setar self.fields["audio_limit"].initial = self.instance.duration_days quando a instância já tiver duration_days (edição), para a tela mostrar o valor correto mesmo antes de salvar.

Como verificar

  • Abrir dash.*/admin/trials/trial/ e confirmar que a coluna e o filtro “Permite renovação?” não aparecem mais na listagem.
  • Abrir o formulário de criação/edição de um Trial e confirmar que:
    • “Permite renovação?” e “Acesso a biblioteca de áudios?” não aparecem mais na tela.
    • “Limite de áudios” aparece desabilitado (não editável) mostrando o mesmo valor de “Duração (dias)”.
  • Salvar um Trial com duration_days=14 e, via shell (make shell), confirmar trial.audio_limit == 14 e trial.access_library_audios is True.
  • Editar duration_days de um trial existente e salvar; confirmar que audio_limit é recalculado para o novo valor.
  • Rodar python manage.py test apps.trials / tests/trials e garantir que os testes existentes (tests/trials/test_admin.py) continuam passando.
  • Adicionar teste cobrindo: Trial.save() sincroniza audio_limit com duration_days e força access_library_audios=True; TrialAdminForm não expõe allow_renewal/access_library_audios e expõe audio_limit como disabled.

Documentação

Atualizar .project/docs/rules/trials/ com uma nova regra descrevendo que audio_limit do Trial é sempre sincronizado com duration_days e não é configurável manualmente, e registrar a entrada em .project/docs/RULES.md.