Serviços de infraestrutura (Workers auxiliares)
Além dos brand workers (front-web-*), a plataforma opera três Workers Cloudflare
auxiliares, cada um no seu próprio repositório. Nenhum deles é deployado pelo
reusable front-ops/deploy.yml — cada um tem o próprio workflow e os próprios
wrangler.*.toml por conta.
| Repo | Papel | Tags no feca.yaml |
|---|---|---|
front-service-api | Proxy do BFF com cache de duas camadas, chamado pelo brand worker via Service Binding | ops, service, api |
front-service-api-dev-proxy | Proxy de dev: remapeia o domínio e autentica por desenvolvedor | ops, service, api, dev |
front-service-api-warmup | Serve respostas do BFF pré-geradas por cron (cobertura hoje: 2 sites) | ops, service, api |
Nenhum dos três é clonado pelo setup default. Para trabalhar neles:
feca clone --tag service
front-service-api — proxy do BFF
O brand worker chama env.API_SERVICE.fetch() passando a URL completa do BFF.
O proxy valida o hostname contra uma whitelist de sufixos, tenta servir do cache de
duas camadas (CF Cache API → KV API_CACHE_KV) e, em miss, vai no BFF.
Configs por conta
Três arquivos wrangler, todos com name = "front-service-api" e
main = "src/index.ts":
| Arquivo | Conta | Binding KV | Extra |
|---|---|---|---|
wrangler.toml | default (== CT) | API_CACHE_KV | — |
wrangler.ct.toml | Cactus | API_CACHE_KV | conteúdo idêntico ao wrangler.toml |
wrangler.bt.toml | Bluetec | API_CACHE_KV (namespace próprio) | binding mTLS CF_WORKER_CERT |
Nenhum deles declara account_id nem [[routes]] — a conta é escolhida no deploy
pelo env CLOUDFLARE_ACCOUNT_ID (o workflow mapeia a matriz ct/bt para
FRONT_CT_CF_ACCOUNT_ID / FRONT_BT_CF_ACCOUNT_ID e passa
--config wrangler.<conta>.toml).
Todos usam keep_vars = true e têm [observability] ligado.
:::danger Não é "Smart Placement"
mode = "smart" não aparece em nenhum arquivo deste repo. O que existe, nos
três tomls, é um pin de região explícito:
[placement]
region = "aws:eu-central-1"
Os próprios comentários dos tomls dizem isso e alertam que placement não se
aplica a invocações por Service Binding (que rodam co-locadas com o chamador) —
logo o pin provavelmente é inerte no caminho real de tráfego, e confirmar exige ler
cf.colo nos logs de invocação.
O README.md e o header de src/index.ts do repo ainda chamam isso de "Smart
Placement". Os tomls são a declaração autoritativa; o README está desatualizado
nesse ponto.
:::
Env e bindings consumidos
| Identificador | Papel |
|---|---|
API_CACHE_KV | KV — camada 2 do cache |
SERVICE_API_CACHE_POLICY_JSON | Política de cache injetada no deploy (a partir de front-ops/config/cache/service-api-defaults.yml). TTLs são clampados por um teto de 3600s |
CACHE_GENERATION | Token de generation. Vazio → cai no fallback in-source |
BUILD_KEY | Compõe o nome do namespace na CF Cache API. Default "default" |
CACHE_PURGE_SECRET | Auth do endpoint de purge. Ausente → 500 |
CF_WORKER_KEY_PROXY | Forwardado ao BFF como header cf-worker-key-proxy |
CF_WORKER_CERT | Binding mTLS, só na BT. Quando presente, o request vai por ele e ganha o header cf-worker-cert-signed: 1 |
API_UPSTREAM_URL | Declarado e setado como "", mas a lógica de rewrite que o usava está comentada — efetivamente morto |
O header origin-domain do request de entrada é o que segrega o cache por marca.
Chave de cache e generation
A generation é literalmente o prefixo do hash. O namespace da CF Cache API é
<BUILD_KEY>-<generation>, e a chave é uma URL sintética
https://<domain>/__cache__/<origin-domain>/<hash>, onde o hash é md5 de
domain | cacheName | origin-domain | method | url.
Trocar a generation torna toda entry anterior inalcançável. Ver playbook 11.
Endpoint de purge
Um só:
POST /__cache_purge__
X-Cache-Secret: <CACHE_PURGE_SECRET>
O match acontece antes da whitelist de domínio, para funcionar com o hostname sintético que o brand worker usa. Sem o secret configurado → 500; secret errado → 401.
Body aceita all, originDomain, tags, glob, segments.
:::caution tags sem originDomain escala para purge-all
Um body só com tags (sem originDomain e sem all) é tratado como purge total.
tags/glob são informacionais neste worker — ele reporta os paths pretendidos
como ignorados. A granularidade real por tag existe no brand worker, não aqui.
:::
Deploy
pnpm deploy:ct # --config wrangler.ct.toml
pnpm deploy:bt # --config wrangler.bt.toml
pnpm deploy # sem --config → usa wrangler.toml (equivalente a CT)
pnpm deploy:no-policy # wrangler deploy puro, sem injetar a policy
pnpm tail # logs
Os scripts deploy* (exceto deploy:no-policy) geram a policy com
scripts/build-cache-policy.mjs e a passam via
--var SERVICE_API_CACHE_POLICY_JSON:"$POLICY".
:::caution Os npm scripts não passam --keep-vars
O CI e o fallback manual do README usam --keep-vars; os scripts do
package.json, não. Rodar pnpm deploy:ct direto pode limpar vars setadas no
dashboard. Prefira o workflow.
:::
O bump-cache-generation.yml do front-ops consegue disparar o deploy deste
worker em CT e BT (input redeploy_service_api, default true).
front-service-api-dev-proxy — proxy de dev
Permite rodar o front-web-base local contra o BFF de produção: reescreve o
sufixo do hostname de dev para o de produção e autentica cada request por
desenvolvedor. Não tem cache.
Configs por conta
| Arquivo | Conta | Route | PROXY_FROM → PROXY_TO |
|---|---|---|---|
wrangler.toml / wrangler.ct.toml | Cactus | *.cac-dev.com/* (zona cac-dev.com) | .cac-dev.com → .bs2bet.com |
wrangler.bt.toml | Bluetec | *.bet-dev.com/* (zona bet-dev.com) | .bet-dev.com → .bluetecconnect.com |
Worker name em todos: front-service-api-dev-proxy. É o único dos três
serviços que declara [[routes]] — logo o pin de região aws:eu-central-1 de fato
se aplica aqui.
Remap de domínio
Não existe arquivo de mapeamento. O mapa é um par de sufixos por config, no
bloco [vars] do wrangler:
[vars]
PROXY_FROM = ".cac-dev.com"
PROXY_TO = ".bs2bet.com"
O worker rejeita (400) o que não começa com /v2/ e o que não contém
PROXY_FROM; depois troca o sufixo no hostname e força https sem porta.
Auth por desenvolvedor
Três headers obrigatórios (faltando qualquer um → 401 Missing auth headers):
| Header | Papel |
|---|---|
dev-user | id do desenvolvedor |
dev-user-token-checksum | MD5(MAIN_TOKEN + "|" + USER_TOKEN_UUID_<USERID>) — o separador é um pipe literal |
cf-worker-key | presença é checada; o valor não é comparado |
A lista de credenciais não está no repo. Cada desenvolvedor é uma secret do
próprio Worker, resolvida dinamicamente por nome: o id é normalizado para
maiúsculas sem caracteres especiais e o worker lê
USER_TOKEN_UUID_<USERID_NORMALIZADO>. Checksum divergente → 401
Invalid user token checksum; usuário desconhecido → 401 Invalid user token.
O provisionamento e a revogação desses tokens é feito pelo fecadm
(fecadm access create|list|revoke <user>) — o CI nunca toca nas
USER_TOKEN_UUID_*. Ver fecadm.
Quando há worker key, o proxy adiciona ao request upstream:
cf-worker-key-user, cf-worker-key-origin e cf-worker-key-proxy.
Deploy
O package.json tem só dev, deploy (wrangler deploy, sem --config) e
tail. Para uma conta específica, o caminho é o CI (matriz CT/BT) ou wrangler
direto:
pnpm exec wrangler deploy --config wrangler.ct.toml --keep-vars
:::caution Metadados errados neste repo
O package.json deste repo declara "name": "front-service-api" e uma
description copiada do proxy de produção ("…Used as a Service Binding by
front-web-base"), o que é falso aqui — este worker é invocado por rotas HTTP. O
header de src/index.ts também é uma cópia stale e descreve cache em KV e
whitelist de domínios, que não existem neste worker. Ignore os metadados; confie
no código e nos tomls.
:::
front-service-api-warmup — respostas pré-geradas
Worker que serve respostas do BFF pré-geradas e gzipadas, por uma busca em três
camadas: módulos .json.gz embutidos no bundle → KV WARMUP_KV → proxy pro
origin. A chave é derivada do header origin-domain (obrigatório — sem ele o
worker responde erro).
Os caches em si são regenerados por crons de GitHub Actions no próprio repo,
que commitam o resultado numa branch warmup.
:::danger Cobertura real: 2 sites
warmup.config.ts declara exatamente dois sites ativos, ambos org: "cactus":
id | originDomain | baseUrl |
|---|---|---|
casateste | casateste.com | https://casateste.com |
rico | rico.bet.br | https://rico.bet.br |
Um terceiro bloco, 7k-bet-br, está comentado — e, como está escrito, não
compilaria se descomentado (falta org e originDomain, ambos obrigatórios no
tipo, e as rotas usam um esquema de path antigo).
Consequências práticas:
- Nenhuma env de produção real do
front-web-baseé coberta por este worker hoje.rico.bet.brnão é nem um environment declarado nofront-ops. - Nenhum site ativo é
org: "blue", entãowrangler.blue.tomlnão tem site alimentando cache. Se isso é intencional, não foi possível verificar.
Se você está diagnosticando staleness numa marca, não assuma que este worker
está no caminho. A lista viva é warmup.config.ts.
:::
Grupos de rotas
Quatro grupos (brand-configs, games-info, bricks-data, sitemap), os dois
sites ativos compartilham o mesmo conjunto default:
| Grupo | Modo | Concorrência | Rotas ativas | Cron (GH Actions) |
|---|---|---|---|---|
brand-configs | parallel | 10 | 8 (/v2/appearance, /v2/bff/features, /v2/bookmaker-settings (POST), /v2/configurations/casino, /v2/country, /v2/crypto/all, /v2/getlegalterm, /v2/payment-providers) | */5 * * * * |
games-info | sequential | — | 2 (/v2/bff/games/base, /v2/casino-games) | */15 * * * * |
bricks-data | parallel | 5 | zero — todas comentadas | */10 * * * * |
sitemap | — | — | descoberta a partir de /sitemap.xml | */30 * * * * |
bricks-data está configurado e agendado mas não aquece nada hoje.
:::info Os crons não estão no worker
src/index.ts exporta apenas fetch — não há handler scheduled, e nenhum
wrangler.*.toml declara [triggers]/crons. Os agendamentos são workflows do
GitHub Actions no repo (generate-brand-configs.yml, generate-games-info.yml,
generate-bricks-data.yml, generate-sitemap.yml, mais merge-warmup.yml que
mergeia a branch warmup na main). generate-all.yml é manual.
:::
Configs wrangler
Quatro arquivos, todos com name = "front-service-api-warmup":
| Arquivo | Corresponde a | Nota |
|---|---|---|
wrangler.base.toml | — | Base compartilhada. O header diz explicitamente para não deployar com ele |
wrangler.toml | — | Dev local (pnpm dev); o id de KV é um placeholder |
wrangler.cactus.toml | org: "cactus" | ORIGIN_URL de produção Cactus |
wrangler.blue.toml | org: "blue" | ORIGIN_URL de produção Blue |
Nenhum declara account_id, [[routes]], placement ou cron — a conta vem do CI.
pnpm deploy:cactus # wrangler deploy -c wrangler.cactus.toml
pnpm deploy:blue # wrangler deploy -c wrangler.blue.toml
pnpm generate # regenera caches localmente
pnpm validate
Não existe script deploy simples neste repo.
:::caution Possível typo de hostname
wrangler.blue.toml declara ORIGIN_URL com o host
prd-front-warmup.bluetecconect.com (bluetecconect, um n no meio),
enquanto o domínio Blue no resto da frota é bluetecconnect.com (dois n). Se é
typo vivo ou um hostname genuinamente distinto não foi possível verificar a
partir dos repos. Vale confirmar com quem opera a conta Blue.
:::
Onde este bloco NÃO aparece
Estes três Workers não são gateados por deploy_protection, não aparecem no
dropdown do manual-cache-purge.yml, e não têm environment em
front-ops/config/brands/. A relação com o front-ops é indireta:
front-service-apiconsomeconfig/cache/service-api-defaults.ymle o token deconfig/cache/generation.yml;- o
bump-cache-generation.ymlpode disparar o deploy dele; - o
purge-monitor.ymlusaFRONT_{XX}_CF_WORKER_KEY_PROXY, que é a mesma classe de credencial que ofront-service-apiforwarda.