Pular para o conteúdo principal

12 publicações com a etiqueta "cache"

Ver todas as etiquetas

Changelog - 26/07/2026

Documento SSR auth-agnóstico — useAuthGate e o expurgo de dado de usuário dos loaders

  • Janela desta entrada — cobre 20/07 a 26/07 (171 commits em main-7k, a semana mais movimentada do trimestre). Foi também a semana em que main-fix e main-7k foram cruzadas nos dois sentidos (PR #1770 e PR #1773), então muitos assuntos aparecem duas vezes no histórico com SHAs diferentes — cada item abaixo cita um SHA só.
  • O documento SSR deixa de saber quem é o usuário (PR #1808, branch feat/user-data-out-of-ssr) — 6b1f32a90 remove auth e smarticoHash do loader de routes/_layout, e cb1b41c26 introduz o gate canônico app/hooks/useAuthGate.ts, client-side e sem snapshot SSR: o SSR sempre pinta convidado, o cookie is_authenticated serve como sinal otimista pós-mount e a store reativa assume depois da hidratação. Regra que nasce daqui: visibilidade e comportamento de UI nunca devem ser decididos com useRouteLoaderData("routes/_layout"), porque aquele é um snapshot SSR que não atualiza quando o login/logout acontece por modal.
  • Loaders per-user desmontados um por umd006a45fc (wallet, fetch 100% client-side), 62fd7b064 (rewards e income-report), 7de40d656 (página de favoritos), f17975eff (favoritos e recentes da home), 5683cdb3c (a página de jogo passa a serializar só a contagem pública de voteState; o userVote vira client-side), e23934b23 (bootstrap do álbum via /api/album/bootstrap). 28366ffca é a reescrita larga do caminho de dado de usuário no SSR.
  • Guardrail em teste, não em revisão282070eca cria o leak-canary: loaders públicos não podem serializar dado de usuário, e o teste falha se voltarem a fazê-lo. e06e384a0 fecha um furo do próprio guardrail (o canary passou a resolver todos os campos-promise do _layout, não só os síncronos). f8d6acf53 testa o useAuthGate contra a store real e f4d4eb059 deduplica React e Zustand no vitest.config — a resolução source-direct estava trazendo uma segunda cópia de React pela via de alias.
  • Reconciliação do Smartico7c5659fba mantém o smarticoHash correto em login e logout dentro da sessão SPA agora que o doc é auth-agnóstico, e 338c824b0 adiciona guard de corrida no fetch dele (além de corrigir comentários que descreviam o gate SSR antigo).

Changelog - 19/07/2026

Refino de UX da família 7k — ondas 4 a 7 e paridade cl/ng/fi

  • Janela desta entrada — cobre 13/07 a 19/07 (151 commits em main-7k, a branch de entrega viva do front-web-base; a main está parada desde 25/06 e não representa o que está em produção). Entradas semanais, não diárias.
  • Ondas 4, 5 e 7 fecham a série de refino visual do 7k-bet-br2de6e2187 (onda 4: modais de depósito, PIX compacto, "já paguei", valores sugeridos), 927f6b2e6 (onda 5: sidebar/nav, gamificação, home cassino, busca mobile) e 352b5beeb (onda 7: corrige hydration mismatch dos links de share, que piscava no F5). As ondas 1 a 3 caíram na semana anterior.
  • Paridade da família imediatamente depois32245acd0 replica as ondas 1 a 4 em cl-bet7k-com, ng-7k-bet e fi-7k-bet; fd3e7ad1c replica a onda 5 (sidebar/nav). O padrão do trimestre: o 7k-bet-br é a brand de referência e as três irmãs recebem o mesmo pacote em commit separado.
  • Barra mobile redesenhada com FAB central da marca (PR #1597) — b5a8d4f99 cria a variante mobile-nav-fab-logo: o item "Menu" vira um FAB circular com a logo da brand e o menu mobile passa a subir como bottom sheet em vez de drawer lateral, degradando pra tiles planos quando o special fab-center está ausente. af7e9bd23 (PR #1594) reordena os tiles pra Menu · Cassino · Buscar · Torneios · Esportes, com a busca no centro pelo alcance do polegar.
  • Tom global dos textos escurecido um pontoe45e597c4 troca #e6e6e6 por #e0e0e0 nos theme/colors.ts das 4 brands da família, cobrindo texts, links, titles e todos os sub-tokens; 4fb6b3eb5 já havia escurecido o fundo dos títulos de seção.

Changelog - 12/07/2026

Semana de 06/07 a 12/07, na branch main-7k do front-web-base. É a semana em que o programa de performance/streaming da plataforma sai do papel: 93 commits filtrados, a maioria concentrada num único eixo.

Semana 06–12/07 — streaming SSR e clientLoader em toda a aplicação

  • App-shell streaming SSR, começando pela home (90d1dcfb4): o entry.server passa a transmitir o stream no shell-ready via TransformStream — head processado no primeiro flush (tailwind inline, strip de modulepreload com keep-list derivada do manifest, strip de preloads de imagem não-LCP) e body em passthrough com tail-carry. Antes o stream era bufferizado até o fim pra rodar regex no HTML completo, ou seja, o primeiro byte esperava todo o conteúdo. Junto vem o piloto de deferred data na home: catalog, gameStatsCache, topWins e lastWins saem do caminho crítico e streamam via Suspense/<Await> no documento SSR e via turbo-stream nas navegações .data, com SectionSkeleton no lugar. Continuam awaited homeRows, brand, auth e a page description (meta/SEO/LCP). Cada perna deferida ganhou .catch(() => vazio), então rejeição degrada pra row vazia em vez de 500 na home inteira. streamTimeout de 10s com abort combinado.
  • Estendido pra game page, hubs e navegação (85a108c2d): o loader da página de jogo cai de 3 gates sequenciais pra 2 awaits (game e brand, o mínimo pro meta/SEO), deferindo stats, winners, related, providers, voteState e as seções showcase. O getStatsRaw, um endpoint do BFF não cacheado que só alimentava o DevPanel, foi movido pro gate de dev — produção deixa de pagar por ele. Nos hubs de cassino e ao-vivo, gameStatsCache e os wins passam a deferidos no caminho de rows. E em _layout.shouldRevalidate, troca de pathname deixa de revalidar o layout, o que remove a chamada de auth por usuário — transatlântica — do caminho crítico de toda navegação SPA logada; login e logout seguem revalidando via revalidate() explícito. Skeletons CLS-zero novos: WinsCombinedSkeleton (o fallback anterior causava ~137px de shift no desktop), WinsMarqueeRowSkeleton, PaidTodaySkeleton, ListWinsSkeleton e GameRowSkeleton derivado do gameCardConfig, com widths corretos por breakpoint e por brand.
  • clientLoader deixa a navegação game → game instantânea (1812d8b07): a navegação SPA pra /cassino/jogar/:provider/:game esperava o .data inicial, que aguarda o getDetail (round-trip de 0,5-1,5s em cache miss), travando a troca de rota inteira. O clientLoader devolve o loaderData na hora — serverLoader() disparado sem await, cada campo encadeado como promise — então a URL troca instantaneamente e o conteúdo preenche por streaming. game, frontDescription, seo e faqEntry foram combinados num único boundary de AwaitValue cujo fallback reserva a geometria exata do conteúdo real, e slug/showcase ficam síncronos porque são deriváveis de params/featuresConfig sem round-trip. 5c24a1354 acrescenta o skeleton pixel-perfect e o seed otimista do card clicado.
  • Padrão propagado pro resto das rotasb3e8c151d (hubs cassino e ao-vivo), bb0b2c012 (categorias e provedores), f241a9145 (home, incluindo seed otimista a partir do homeRows já cacheado na store e o bundle de favoritos/recentes virando um único favoritesBundle streamado), 761088aa6 (VIP e gamificação) e e6fe562f1 (conteúdo WP, legal e busca, com legalTerms deferido). cc237adfc centraliza o preview de dev-skeleton num módulo único e removível; 49ef0d808 e d8401122b corrigem imports .server que vazaram pro caminho client.
  • Dois defeitos reais achados e corrigidos no próprio programa. 885f0e92c: o encoder de single-fetch do React Router corre toda promise deferida contra o streamTimeout, e perna pendente virava frame E:["Unexpected Server Error"] dentro de um body 200, por fora do .catch do loader; pior, errorElement={null} é falsy, então o <Await> re-lançava pro ErrorBoundary da rota em vez de suprimir (a tela renderizava e depois virava erro); e o worker cacheava o .data 200 com o frame de erro embutido por 60s, servindo o mesmo erro em HITs subsequentes. Fix: errorElement truthy (fragment vazio) em AwaitValue/AwaitWins e na home. afc20a73d, resultado de revisão adversarial: o buildSpaShell bufferizava o stream inteiro pro usuário logado (TTFB = render completo, ~11s no pior caso) e devolvia um shell morto; Set-Cookie de tracking bloqueava o cache compartilhado pra todo visitante anônimo frio; o cache autenticado não tinha guard contra payload envenenado ou documento truncado; e a home resuspendia pra skeleton genérico em todo login/logout. O buildSpaShell foi removido e o autenticado em rota pública passa a receber a mesma stream real do anônimo.
  • Navegação e stats estáveis na página de jogo (dfad863b1): getStats e getVoteCount ganham timeout fail-fast de 1200ms, com a promise original registrada no waitUntil — assim o warming completa em background mesmo em cold-miss, o que o timeout sozinho mataria. As duas ondas sequenciais de Promise.all do loader foram fundidas, removendo um round-trip serial.

Changelog - 05/07/2026

Semana de 29/06 a 05/07, na branch main-7k do front-web-base. Semana mais leve em volume (47 commits filtrados), mas com duas decisões estruturais de tracking.

Semana 29/06–05/07 — anaLayer: uma segunda camada de tagueamento GA4, paralela à existente

  • Fundação da camada (1fceb0672): implementa o tagueamento GA4 do guia Ana Gaming num container GTM secundário próprio, com dataLayer isolado chamado anaLayer, rodando em paralelo e independente da stack de analytics atual (dataLayer/registry + Meta, Kwai e os demais). A config é brand-gated com default null, então a invariante é que nenhuma brand dispara sem container declarado. Inclui registry tipado dos 32 eventos, helper pushAnaLayerEvent, campos padrão (user_id, user_id_hash como SHA-256 do CPF, platform, profile_type, event_timestamp), event_id determinístico, AnaLayerProvider/useAnaLayer e um AnaLayerInitializer espelhando o Consent Mode v2 do initGTM. 21 testes.
  • Wiring de 22 eventos no mesmo commit — page_view, login, sign_up, modal_viewed, begin_checkout, add_payment_info, deposit_pix_generated/copied, purchase, deposit_pix_expired, withdrawal_started/requested, kyc_started/completed, form_error, view_item_list, select_item, view_promotion/select_promotion, select_content e search — disparados em paralelo aos eventos legados, lendo IDs reais das APIs. Bloqueados de propósito, com scaffold e TODO: game_opened e game_session_ended (aguardando game_session_id no StartGameResponse do core), além de refund, o ciclo de saque pós-requested, aprovação/rejeição de KYC e cashback, que são observados no backend e ficam registry-only. Nada é disparado com dado sintético.
  • Alvo trocado de 7k pra vera e depois configurado por brandfba166367 reaponta a camada pra vera em vez do 7k; b621f558e faz o useAnaLayer degradar pra no-op fora do provider; e 4bf4ebabd adiciona a flag enabled à AnaLayerConfig, criando o estado "configurado mas desabilitado": o gate passa a exigir enabled === true e containerId. Resultado no fim da semana: vera-bet-br é a única com enabled: true; 7k-bet-br e cassino-bet-br ficam com container declarado e enabled: false. Os IDs de container vivem só nos overrides de cada brand.

Changelog - 28/06/2026

Semana de 22/06 a 28/06, na branch main-7k do front-web-base.

  • O baseline de boot do Google Consent Mode v2 foi invertido pra granted (16bf59fee). Isto reverte o comportamento descrito no changelog de 23/04/2026. A política antiga emitia gtag('consent','default', { ...tudo denied, wait_for_update: 500 }) e só depois, se houvesse cookie salvo, aplicava um update. A nova emite gtag('consent','default', { ...tudo granted }) sempre, sem wait_for_update. O único caminho que ainda rebaixa sinais é cookieConsentCosmeticOnly === false e cookie salvo indicando rejeição total, caso em que o initGTM dispara um update imediato pra denied. Matriz implementada: cosmético truegranted (qualquer cookie ignorado); cosmético false sem cookie ou com aceite → granted; cosmético false com rejeição total → default granted + update imediato pra denied. Arquivos: app/utils/metrics/consent.ts (injectConsentDefaults com opts.applyDenied) e app/utils/metrics/gtm.ts (decide applyDenied = !cosmetic && userRejectedAll), com 4 casos de teste. A justificativa registrada no commit é paridade com o app Nuxt legado, que nunca gateava tracking, e a eliminação da janela cega de 500ms do wait_for_update, apontada como causa suspeita da queda de performance em Google Ads e Meta Ads após a migração.
  • cookieConsentCosmeticOnly passa a ter default true no base (be0518d91). Antes o default global era false, então brand que não declarasse a flag honrava a rejeição do usuário. As 7 brands que já declaravam true seguem idênticas; as 8 que herdavam false (casateste-com, donald-bet-br, pb-bet, ph-state77-com, pt-state77-com, rj-bet, state77-com, x2b-bet) passaram a declarar false explicitamente no próprio override — comportamento preservado bit a bit, com o ganho de que cada override é agora a fonte autoritativa da política de consent daquela brand, sem depender do default do base.
  • Nota de revisão pendente: as duas mudanças acima descrevem o que o código faz hoje. A política resultante — consent concedido por padrão, tratamento cosmético como default e ausência de botão de rejeição total no banner — ainda depende de confirmação do responsável por LGPD antes de ser publicada como política oficial. Registrado aqui como fato técnico, não como posição de conformidade.
  • Eco do gtag duplicando eventos do dataLayer corrigido em ea9b09a68.

Changelog - 21/06/2026

Semana de 15/06 a 21/06. Daqui pra frente o changelog é semanal (arquivos YYYY-MM-DD-weekly.md, datados no último dia coberto). A fonte de verdade do front-web-base é a branch main-7k — a main está defasada e não reflete o que foi pra produção.

Semana 15–21/06 — cache overhaul: CACHE_GENERATION como token único de rotação

  • front-ops/config/cache/generation.yml vira a fonte operacional de verdade (ops f00c642): o arquivo carrega current: apcsrasj-v3, é lido no deploy e injetado como --var CACHE_GENERATION no wrangler deploy. Bumpar pelo workflow novo bump-cache-generation flipa de uma vez a namespace do Cache API do platform-cache, o cacheKeyPrefix do api-client e o GLOBAL_VERSION do front-service-api; sem o arquivo, o deploy cai no default in-source (fail-open). É separado do BUILD_ID, que já rotaciona a cada deploy — o CACHE_GENERATION é o "nuke from orbit" que o padrão legado de pasta-nova-por-deploy fornecia. cache-status.yml complementa como leitura read-only.
  • Base conectado à máquina nova (b445a6b5a): binding declarado no worker-configuration.d.ts; app/services/platform-cache.server.ts mantém um storesByGeneration chaveado pelo token, então o cache de isolate rotaciona atomicamente; app/services/api.server.ts deriva cacheKeyPrefix como api-cache-<gen> e liga delegateCaching: true nas rotas já cacheadas na camada platform-cache, eliminando o drift de TTL duplo que causou o postmortem de /payment-providers em 05/2026. app/routes/api/cache/purge.ts passa a delegar ao createPurgeHandler do core (mesmo contrato de tag/glob/scope/dry_run, com extractApiError no lugar de [object Object]) e nasce app/routes/api/cache/inspect.ts, endpoint GET que lista recursos, tags e namespace corrente e, com ?include=state, sonda o Cache API.
  • TTLs apertados e falhas de fallback visíveis (239651ff4): KV_SSR_TTL cai de 12h pra 1h (o valor antigo era resquício da premissa "rebuild a cada 12h"), entra MAX_API_CACHE_TTL = 3600 com clamp em getApiCacheRule, e erros de fallback de asset em KV e R2 passam a ser logados — antes eram engolidos em silêncio, deixando problema de permissão ou bucket invisível no Logpush. public/_headers reduz /icons/* de 1 ano pra 30 dias.
  • Defaults e purge seletivo no front-ops (b36e445): brandConfig sai de 3600s e homeRows de 7200s, ambos pra 60s + SWR 300s, então mudança de backoffice reflete em menos de 60s; toda resource ganha tags pra o purge mirar fatias em vez de derrubar tudo; staleIfErrorSeconds capado em 6h. manual-cache-purge.yml sobe pra v3 com tags (CSV), glob, scope e dry_run. 8645ac2 cria config/cache/service-api-defaults.yml com 19 regras consumidas no deploy do service-api — base e service-api passam a compartilhar a mesma taxonomia de tags.
  • skip_post_deploy_purge por environment (ops 2d83a4c, aplicado em 0d4437e e 64f130f): workers atrás de Cloudflare Access devolvem 404 no purge pós-deploy porque o curl segue o redirect de login sem service token. Até os service tokens entrarem no workflow, o environment pode sair do purge por segmento — a rotação do CACHE_GENERATION já torna as entradas anteriores inalcançáveis — e um step de notice registra o skip no run summary.
  • front-service-api com política externalizada (f80791d): DEFAULT_GLOBAL_VERSION = apcsrasj-v3, getGlobalVersion(env) lendo CACHE_GENERATIONBUILD_KEY → default, política vinda de env.SERVICE_API_CACHE_POLICY_JSON (era hardcoded) e /v2/cache/purge com o mesmo contrato do base. scripts/build-cache-policy.mjs resolve o YAML por --file, FRONT_OPS_PATH ou irmão ../front-ops. 27 testes novos, com 8d9fe4f documentando o fluxo no README.

Changelog - 10/05/2026

Remarketing first-party (rmkvera)

  • Sistema de remarketing first-party com UUID v4 estável + audience tags do funil, brand-aware via feature flag (app/config/features/remarketing.ts). Vera ativa com cookie rmkvera (365 dias sliding TTL, Domain=.vera.bet.br, SameSite=None, Secure); demais brands fazem opt-in declarando seu próprio cookieName no override.
  • Cookie rmkvera_aud armazena tags do funil em JSON (90 dias sliding TTL, cap de 40 tags com eviction de oldest, set-once semantics) — pra ser usado como external_id em Meta CAPI, Google Enhanced Conversions e TikTok Events API. Funciona mesmo sem cookies de terceiros (iOS 14+, ITP, Brave).
  • Tags emitidas automaticamente em três eixos: path-based via useLocation brand-aware no Route Registry (viewed_casino, viewed_live_casino, viewed_game_detail, viewed_sports, viewed_promotions), modal-based via Zustand (clicked_register, registered, abandoned_register, viewed_deposit_modal, abandoned_deposit) e FTD-based em useAnalytics.trackDepositConfirmed (ftd_completed, multi_deposit).
  • Captura server-side no root loader (captureRemarketingIdFromRequest) — sobrevive a redirects via Set-Cookie na própria response do 302 (mesmo padrão do tracking de UTMs). Client-side RemarketingCapture faz refresh de TTL, publica em window.__rmk e dispara rmk_ready + rmk_audience_tag no dataLayer.
  • Regras duras: nome do cookie rejeita termos internos da plataforma (cactus, bluetec) em runtime, bot traffic é skipado no server, validador strict UUID v4 RFC 4122 contra cookies adulterados. 39 unit tests + 16 server-side tests cobrindo capture, Set-Cookie, regenerate em tamper, eviction.

Changelog - 29/04/2026

Dia pesado: 25 PRs no front-web-base cobrindo um empurrão grande de performance (CSS, ícones, modal), refatoração do header secundário com gating de rota, novas features de cassino e pagamentos, e ajustes finos de SEO/mobile/auth. Plus 4 mudanças de CI/CD em front-ops pra suportar o novo modelo de cache por device/country/buildId.

Performance — empurrão grande

  • Drop important: true do Tailwind (tailwind.config.js). Removido globalmente — precedência CSS volta ao normal (inline style vence class). Resultado: CSS −23,5KB raw (−14,4%). Componentes que usavam o pattern condicional bgStyle ? "" : "bg-..." (omitir classe quando havia inline style) foram simplificados — agora basta sempre emitir a classe que o style inline sobrescreve quando presente. Atualizados: GameCardStacked, GameStats, GameWinners, MainLeaguesSquare, SidebarButtonsGradient, SidebarButtonsGrid.
  • Migração react-modal-sheetvaul (app/components/base/Modal.tsx). Modal chunk caiu de ~158KB pra ~65KB raw — −93KB (−59%). Mesma API externa, drop-in pelos consumers. (PR #405 fez ajustes finos depois pra resolver bugs de input-focus em mobile e espaço fantasma no footer.)
  • Remoção do @tailwindcss/typography. Plugin não justificava o custo — uso restrito a 4 lugares (FaqSingleContent, WpPostContent, page.$slug, vip/levels) substituído por classes utilitárias inline. package.json enxuga uma dep + 22 linhas de pnpm-lock.yaml.
  • Ícones direct-imports + lazy MainLeagues (app/widgets/home-leagues/). Drop do registry intermediário — agora cada componente faz import Icon from "~icons/<set>/<name>" direto. MainLeaguesSquare virou lazy chunk separado. 25 arquivos tocados, −564 linhas vs +454. Atualiza configs de home-leagues em 7 brands (7k-bet-br, cassino-bet-br, fi-7k-bet, ng-7k-bet, pb-bet, vera-bet-br, state77-com, x2b-bet).
  • CI Lighthouse manual (.github/workflows/lighthouse.yml). Workflow caller dispatchável via workflow_dispatch pra rodar Lighthouse on-demand contra preview/prod sem precisar de schedule fixo. Útil pra validar PRs pesados de UI antes de mergear.

Changelog - 12/04/2026

Semana 06–12/04 — Onboarding de depósito: banner de bônus, auto-abertura e prefill

  • FirstDepositBonusBanner entra no DepositModal (94fe5c7b7), visível enquanto o formulário de depósito está ativo, para expor a oferta de primeiro depósito no exato momento da decisão. 62ff8e4a1 ajusta a margem e renomeia o maxLabel não consumido para _maxLabel, mantendo o Biome quieto sem apagar o campo.
  • O modal de depósito volta a abrir sozinho para quem tem saldo baixo (bf390c85e), replicando o useOpenModalAfterTime do front Vue/Nuxt legado: abre após login ou registro quando o saldo é ≤ R$ 0,99, pula contas restritas (autoexclusão, somente-saque), respeita cooldown de 12 h gravado em localStorage, espera 1 s para que modais de validação e bloqueio tenham prioridade, e limpa a chave no logout.
  • ?value= na URL pré-preenche o valor do depósito (c34c93d93), fechando o ciclo de campanhas que mandam o usuário direto para um valor sugerido. O namespace de i18n de pagamentos ganha as mensagens de bônus de primeiro depósito nos três idiomas (core f31c309).

Changelog - 05/04/2026

Semana 03–05/04 — Rede 7k chega à Nigéria e à Finlândia

  • Duas marcas novas nascem no mesmo dia: ng-7k-bet (7c7bcbe0a) e fi-7k-bet (e83078a76) ganham árvore de override completa em overrides/<brand>/app/config/ — tema, features.config.ts, menu.config.ts, sidebar.config.ts, linhas de home/cassino e itens de navegação. O acabamento veio na sequência: 224653ac7 fecha o branding da ng-7k-bet, 750fd7f5c ajusta features e cores da fi-7k-bet, e 0359f4e2e / f6b0ce82c trocam favicon e ícones PWA de cada uma. Como overrides/* é ignorado por padrão no .gitignore, cada marca só passa a ser versionada quando entra na lista de exceções (!overrides/<brand>/) — é esse commit que "cria" a marca aos olhos do git.
  • Manifest PWA passa a sair do tema (1dff5bffc): theme.config.ts ganha um bloco manifest com theme-color e background-color, e a rota app/routes/manifest[.]json.ts lê dali em vez de ter os valores fixos — o mesmo bloco foi propagado para todos os overrides.
  • Licenciamento por jurisdição: 24d0b6ebf padroniza o texto de licença entre as configs, 7f46e5604 troca o texto da ng-7k-bet para inglês e 9a9a38be0 ajusta o textLicense do licenses.config.ts dessa mesma marca. Marca nova em jurisdição nova não reaproveita o rodapé regulatório brasileiro.
  • Suporte de país no core: @cactus-agents/country-config ganha suporte ao documento NIN e a localização da Nigéria (8a5d11d) — é dessa config que o registro tira qual documento pedir e como validá-lo.