Cache operations (playbooks)
Esta página é o manual de operações pro cache da plataforma. Cada seção é um playbook independente — entrar, fazer, sair.
Para entender por que o sistema é assim, veja Cache architecture. Para a visão de "como funciona, sem detalhes técnicos", veja Cache strategy.
Pré-requisitos
- Acesso ao repositório
cactus-agents/front-opsno GitHub - Permissão pra rodar Actions workflows
- Em casos críticos: acesso ao Cloudflare Dashboard (CT e/ou BT)
Todos os exemplos abaixo assumem vera-bet-br como brand/environment. Substitua pelo seu caso.
Playbook 1 — Invalidar config de brand (banners, payment-providers)
Quando usar: mudança no backoffice (banner novo, ordem de payment-providers, feature flag) que não está aparecendo após 1-2min.
Tempo: ~30s.
Passos:
- GitHub →
cactus-agents/front-ops→ Actions → Manual Cache Purge → Run workflow - Inputs:
- environment:
vera-bet-br(ou prod-7k-bet-br, etc) - tags:
brand - scope:
all(purga platform-cache + service-api)
- environment:
- Run
- Aguarda ~30s. O step summary mostra resposta de cada camada.
- Valida visitando o site em janela anônima (pra contornar browser cache).
O que acontece por trás:
- Brand worker
engine.purgeByTag("brand")invalidabrandConfig(e qualquer outro resource com tagbrand) - Cascade pro service-api purga entradas com tag
brand(/v2/bff/features,/v2/appearance,/v2/bookmaker-settings,/v2/configurations/casino,/v2/country) - Próxima request → BFF → dado fresco
Por que isso é suficiente:
- TTL do brandConfig é 60s; este purge é só pra forçar antes do TTL natural expirar
- Não precisa zone purge nem CF Cache Reserve
Playbook 2 — Invalidar catálogo de jogos
Quando usar: jogo novo adicionado, jogo removido, mudança de ordem em categorias.
Tempo: ~30s.
Passos:
- Actions → Manual Cache Purge → Run workflow
- Inputs:
- environment:
vera-bet-br - glob:
games:*(cobregames:list,games:detail,games:wins,games:stats,games:high-payers,games:category,games:provider,games:base,games:listPage,games:all) - scope:
all
- environment:
- Run.
Variante (mais cirúrgica):
Pra atingir só home + casino (não detalhe de jogo):
- tags:
rows - scope:
all
Pra atingir só a estatística "pagou hoje":
- tags:
stats - scope:
all
Playbook 3 — "O site inteiro tá com dados velhos, quero zerar tudo"
Quando usar: ultima opção. Postmortem em andamento, problema generalizado, ou após uma mudança grande no BFF.
Tempo: ~1-2min (incluindo zone purge).
Passos:
- Actions → Manual Cache Purge → Run workflow
- Inputs:
- environment:
vera-bet-br - (deixa tags/glob/segments vazios) = purgeAll
- scope:
all
- environment:
- Run.
O que acontece:
- platform-cache
engine.purgeAll()no brand worker - service-api purga TODAS as entries com
originDomain: vera.bet.br({ all: false, originDomain: "vera.bet.br" }) - CF zone
purge_everything(apaga TODO o cache de zone — assets, HTMLs, .data)
Cuidado: zone purge_everything tem custo CF e é nuclear. Use só quando realmente necessário.
Playbook 4 — Invalidar só uma camada (debug)
Quando usar: investigando se um problema específico está em uma camada ou outra.
Inputs:
- scope: platform-cache — só invalida no brand worker (memory + CF Cache API + KV snapshot do platform-cache)
- scope: service-api — só invalida no proxy worker (KV API_CACHE_KV + CF Cache API do service-api)
- scope: zone — só CF zone purge (edge cache do SSR HTML)
Use cases típicos:
- "Dados que vêm da home tão velhos, mas detalhe tá certo" →
scope: platform-cache, tags: rows - "Pagamentos errados no checkout" →
scope: service-api, tags: payments - "Página /alguma-coisa tá com HTML antigo mesmo após /api/cache/purge" →
scope: zone
Playbook 5 — Diagnosticar staleness
Quando usar: "tá dando velho mas eu não sei onde", antes de chutar um purge.
Tempo: ~10s.
Passos:
- Actions → Cache Status → Run workflow
- Inputs:
- environment:
vera-bet-br - include_state:
true(probe live state)
- environment:
- Run.
- Abrir o step summary. Vai mostrar uma tabela com:
- Qual resource está warm em CF Cache API
- Quantos segundos de age (desde a última população)
- Quantos segundos fresh sobram antes de virar stale
- Quais tags cada resource tem
Interpretação:
Primary hit ❌em vários resources → cache está cold, próxima request vai pagar custo de BFFAge > TTLmasFresh? ⚠️→ resource está stale, SWR vai revalidar na próxima request- Resource esperado não aparece → não está declarado na policy (BYPASS silencioso). Veja Playbook 7.
Playbook 6 — Inspeção direta via curl
Pra automação, scripts, ou quando o GitHub Actions tá fora:
# Variáveis (substituir)
TARGET=vera.bet.br
SECRET=$FRONT_CT_CACHE_PURGE_SECRET
WORKER_KEY=$FRONT_CT_CF_WORKER_KEY
# 1) Inspecionar policy declarada
curl -s "https://$TARGET/api/dev/cache-policy" \
-H "X-Cache-Secret: $SECRET" | jq .
# 2) Inspecionar estado live (com TTLs restantes)
curl -s "https://$TARGET/api/cache/inspect?include=state" \
-H "X-Cache-Secret: $SECRET" | jq .
# 3) Inspecionar só uma tag
curl -s "https://$TARGET/api/cache/inspect?tag=brand&include=state" \
-H "X-Cache-Secret: $SECRET" | jq .
# 4) Purge por tags
curl -s -X POST "https://$TARGET/api/cache/purge" \
-H "X-Cache-Secret: $SECRET" \
-H "cf-worker-key: $WORKER_KEY" \
-H "Content-Type: application/json" \
-d '{"tags": ["brand", "catalog"]}' | jq .
# 5) Purge tudo da brand (incluindo service-api)
curl -s -X POST "https://$TARGET/api/cache/purge" \
-H "X-Cache-Secret: $SECRET" \
-H "cf-worker-key: $WORKER_KEY" \
-H "Content-Type: application/json" \
-d '{}' | jq .
Playbook 7 — Adicionar resource novo ao platform-cache
Quando usar: novo serviço/módulo precisa cachear dados do BFF de forma agregada.
Tempo: ~15min, incluindo PR review.
Passos:
-
Define o resource no
front-ops/config/cache/defaults.yml:myNewResource:enabled: truettlSeconds: 600 # 10minstaleWhileRevalidateSeconds: 300staleIfErrorSeconds: 86400fallbackEnabled: false # ou true se for hotstorage:primary: cache_apisnapshot: none # ou kvkeyPrefix: myNewResourcetags: ["catalog", "my-domain"] -
Wire-up no service do brand worker:
// app/services/my-new.cache.server.tsexport async function getMyData(deps: Deps) {const result = await engine.fetch("myNewResource",() => fetchFromBff(deps),{ waitUntil: deps.ctx?.waitUntil },);return result.data;} -
(Opcional) Adicione ao service-api se o BFF path precisar de cache no proxy também:
Em
front-ops/config/cache/service-api-defaults.yml:/v2/my/bff/path:ttl: 1800methods: ["GET"]tags: ["catalog", "my-domain"] -
PR em
front-opscom as duas mudanças. -
Deploy explícito do brand worker. Um push no
front-opsnão redeploya o brand worker automaticamente — o worker lêPLATFORM_CACHE_POLICY_JSONem deploy-time. Pra ativar o novo resource, rode o workflowdeploy.ymlmanualmente (ou aguarde o próximo deploy de código do brand worker). -
Valida rodando
Cache Statusworkflow — o novo resource deve aparecer na tabela.
Atenção:
- Resource user-scoped? Use
fetchWithKey(resource, userId, fetcher)e adicionetags: ["user-scoped"]pra documentar. Nunca usefetch()sem suffix em resource per-user. - KV ON (
fallbackEnabled: true+snapshot: kv) é caro (KV writes custam $). Use só pra resources hot ou pra cross-DC warm-up crítico.
Playbook 8 — Deploy não invalidou cache esperado
Sintoma: após deploy, mudança no código não aparece no site. (Normalmente o deploy.yml dispara post-deploy purge automático.)
Diagnóstico:
- Verifica o run do deploy.yml. Procura por:
- Step "Purge platform cache after deploy" — status 200?
- Step "Purge SSR cache (CF zone)" — status 200?
- Step "Warm up cache" — todos 200/304?
- Se algum step falhou: re-roda
manual-cache-purge.ymlcomscope: all.
Causas comuns:
FRONT_<X>_CACHE_PURGE_SECRETmismatch entre worker e workflow → 401 no stepcf_zoneerrado emdeploy.yml→ zone purge skip (warning)- Token CF sem permissão "Cache Purge:Purge" → 403
Veja config/brands/README.md no front-ops pro checklist completo de tokens CF.
Playbook 9 — Resource em BYPASS silencioso
Sintoma: dev adicionou engine.fetch("foo", ...) mas o resource não está cacheando.
Diagnóstico:
- Roda
cache-status.ymlna env. - Procura
foona tabela. - Se não aparece, é BYPASS — não está na policy.
- Logs do worker (
wrangler tail) deveriam mostrar uma vez:[platform-cache] resource "foo" has no policy entry — running in BYPASS mode
Solução: PR no front-ops/config/cache/defaults.yml (Playbook 7).
Playbook 10 — Forçar invalidação direta no Cloudflare (último recurso)
Quando usar: workflows do GH down, ou cache.purge endpoint do brand worker quebrado.
Tempo: ~2min.
Passos:
- Cloudflare Dashboard → Zone (ex: vera.bet.br) → Caching → Configuration
- Purge by URL se sabe exatamente o que zerar, ou
- Purge Everything se é nuclear.
OU via API:
# Zone ID (lookup)
curl -s -X GET \
"https://api.cloudflare.com/client/v4/zones?name=vera.bet.br&account.id=$ACCOUNT_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[0].id'
# Purge everything
curl -s -X POST \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"purge_everything": true}'
Atenção: isso afeta SÓ o CF zone cache (SSR HTML em edge). Não toca platform-cache nem service-api. Pra purgar app-level use o manual-cache-purge.yml.
Playbook 11 — Reset completo de cache-key prefix (escalada)
Cenário extremo: uma mudança de schema do BFF causou que payloads cacheados em KV/CF Cache estão com formato incompatível com a nova versão do código.
Como funciona:
Cada camada tem um prefix versionado. Bumpar o prefix significa todos os caches dessa camada ficam órfãos instantaneamente.
| Camada | Onde bumpar | Versão atual |
|---|---|---|
| platform-cache CF Cache API namespace | core/packages/platform-cache/src/generation.ts (single source of truth) | platform-cache-apcsrasj-v3 |
| api-client cache key | core/packages/api-client/src/cache.ts (DEFAULT_CACHE_KEY_PREFIX) | api-cache-apcsrasj-v3 |
| service-api proxy | front-service-api/src/index.ts (CACHE_GENERATION env / fallback) | apcsrasj-v3 |
Nota: um bump de
CACHE_GENERATIONorphana (não deleta) as entries KV antigas. Elas TTL-evict dentro da janela do ceiling (≤1h). Para wipe instantâneo, seria necessário um POST{ all: true }adicional ao service-api — isso é follow-up futuro. Veja Invariante 9.
Passos:
- PR bumpando o prefix (
v1→v2,v3→v4, etc) no arquivo acima. - Para core packages: tem que publicar versão nova no GH Packages.
- Para brand worker: redeploy automático puxa o package novo + invalida tudo no novo namespace.
- Para service-api: redeploy via
pnpm deploy:ct/:bt. - Aviso pré-deploy ao time: vai ter cold-start massivo. Considere fazer em horário de baixo tráfego.
Quando NÃO fazer: se um purge normal funcionaria. Bump de prefix é última opção.
Sumário rápido — escolha o playbook certo
| Situação | Playbook |
|---|---|
| Backoffice mudou e não reflete | 1 |
| Jogo novo não aparece | 2 |
| "Tá tudo errado, zera tudo" | 3 |
| Debug — quero saber em qual camada está o problema | 4, 5 |
| Inspeção rápida via curl | 6 |
| Adicionar resource novo | 7 |
| Deploy não invalidou esperado | 8 |
engine.fetch("foo") não cacheia | 9 |
| Workflow GH fora, preciso resolver via CF direto | 10 |
| Mudança de schema do BFF quebrou caches existentes | 11 |