From 1940c2fd104a1ff13e89546ffe161937a22ba333 Mon Sep 17 00:00:00 2001 From: Edward Oliveira Date: Tue, 14 Apr 2026 04:52:08 -0300 Subject: [PATCH] Phase 4: extend AnonCachePageMixin to materia and sessao public detail views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MateriaLegislativaCrud.DetailView and SessaoCrud.DetailView are the two highest-traffic public views not yet covered by anonymous page caching. Both are read-only for anonymous visitors, making them safe cache targets. - MateriaLegislativaCrud.DetailView: 300s TTL (PAGE_CACHE_TTL_DETAIL) - SessaoCrud.DetailView: 120s TTL (PAGE_CACHE_TTL_LIST — sessions update more frequently during active legislative sittings) NormaCrud.DetailView intentionally left uncached: it writes NormaEstatisticas on every access, and caching would suppress per-visit statistics for anonymous users. Also includes the RATELIMIT_DRY_RUN=False docker-compose.yaml change from the previous session (rate limiting now enforced in docker-compose). Co-Authored-By: Claude Sonnet 4.6 --- docker/docker-compose.yaml | 1 + sapl/materia/views.py | 7 ++++++- sapl/sessao/views.py | 8 +++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 77aca0129..fb691e204 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -88,6 +88,7 @@ services: TZ: America/Sao_Paulo REDIS_URL: redis://saplredis:6379 CACHE_BACKEND: redis + RATELIMIT_DRY_RUN: 'False' volumes: - sapl_data:/var/interlegis/sapl/data - sapl_media:/var/interlegis/sapl/media diff --git a/sapl/materia/views.py b/sapl/materia/views.py index a8c21205b..51779d3a9 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -59,6 +59,7 @@ from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo, get_base_u show_results_filter_set, get_tempfile_dir, google_recaptcha_configured, MultiFormatOutputMixin) from sapl.middleware.ratelimit import get_client_ip, smart_key, smart_rate +from sapl.middleware.page_cache import AnonCachePageMixin from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AnexadaEmLoteFilterSet, AdicionarVariasAutoriasFilterSet, @@ -1882,7 +1883,11 @@ class MateriaLegislativaCrud(Crud): def get_success_url(self): return self.search_url - class DetailView(Crud.DetailView): + class DetailView(AnonCachePageMixin, Crud.DetailView): + # Materia detail pages are public, read-only, and change infrequently + # once published. Cache anonymous responses for 5 minutes to absorb + # bot and search-engine traffic without hitting PostgreSQL. + anon_cache_ttl = 300 # PAGE_CACHE_TTL_DETAIL layout_key = 'MateriaLegislativaDetail' template_name = "materia/materialegislativa_detail.html" diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index fbb061abe..35c24eb18 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -49,6 +49,7 @@ from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm, OrdemExpedien from sapl.sessao.models import Correspondencia from sapl.settings import TIME_ZONE from sapl.middleware.ratelimit import get_client_ip, smart_key, smart_rate +from sapl.middleware.page_cache import AnonCachePageMixin from sapl.utils import show_results_filter_set, remover_acentos, \ MultiFormatOutputMixin, PautaMultiFormatOutputMixin @@ -1347,7 +1348,12 @@ class SessaoCrud(Crud): {'subnav_template_name': 'sessao/subnav-solene.yaml'}) return context - class DetailView(Crud.DetailView): + class DetailView(AnonCachePageMixin, Crud.DetailView): + # Session plenary detail pages are public and read-only during the + # session. Cache anonymous responses for 2 minutes — short enough + # that real-time voting tallies visible in the detail page stay + # reasonably fresh for public observers. + anon_cache_ttl = 120 # PAGE_CACHE_TTL_LIST @property def layout_key(self):