Substituição integral do módulo pela v2 — a079bcfab troca app/components/album/** pela versão v2 do drop-in: subdiretório share/ novo (15 arquivos) com pipeline de compartilhamento social por figurinha, URL canônica, card de OG safe pra Satori e helpers de UTM; três componentes novos (CheckinSuccessModal, MissionTypeChoiceModal, PackSummaryPhase); StickerCard e StickerRevealStack extraídos como reusáveis; check-in consolidado em CheckInState com dois tipos de claim (diário e de conclusão); e a novidade estrutural — trilhas duplas (casinoMissions / sportbookMissions mais missionType, um gate bloqueante de escolha no primeiro acesso). O hook público passa a ser useAlbumProgress; useProgressSync, CheckInTier e AlbumBootstrap.checkInDays saem do contrato.
Handshake de auth próprio, server-side — 7644499ec. O BFF do álbum exige fluxo de auth distinto do JWT do cookie HttpOnly do host: POST {STICKER_API_URL}/auth/token com { encryptedUserId, brandId, campaign } devolvendo { accessToken, tokenType, expiresAtUtc }, e Authorization: Bearer em todas as demais chamadas. A versão anterior passava o JWT do cookie direto, o que não funcionava contra o BFF real. loadAlbumBootstrap agora faz o handshake antes do Promise.all de endpoints e retorna null quando ele falha — feature degradada em silêncio em vez de rota quebrada. 459b1b0d5 adiciona cache de token cross-request e fd8690a9b projeta o apiCampaign no servidor antes de mandar pro client.
Auditoria de porte com 53 achados — 3a2a0eab6 compara a v2 portada contra o harness do sticker-book, o Swagger oficial do BFF e os contratos consumidos pelo módulo: 19 críticos, 31 médios, 3 baixos. Os commits seguintes endereçam os 19 críticos — entre eles ff17d4230 (sincronizar state.checkIn a partir de data.checkIn após refetch), d78a718a9 (blindar loadAlbumPageData contra throws inesperados), def9b3f41 (gatear o polling de 60s em document.visibilityState), 9066c2284 (alinhar os handlers de rota ao Swagger) e 819b5dd03 (adapters de mutação, retry de 401, tipos de API compartilhados).
Kill-switch por marca e gating de acesso — 93b3d1312 cria albumConfig.enabled fail-closed: o código fica disponível pra todas as marcas mas só executa pra quem declara enabled: true explicitamente, com guard no loader de /vip/album que redireciona pra home antes de qualquer chamada ao BFF. Só o 7k liga. 72bf89007 adiciona modo preview, splash, gating de feature flag, entrada de sidebar e endurecimento de cache; b7157c1e6 esconde a entrada pra usuário deslogado; a13218eae faz o deslogado fechar pelo X e pelo backdrop em vez de abrir login.
Missões vindas do Smartico e do BFF, mescladas por id — dc868194f passa a carregar "Suas Missões" da seção ALBUM_FIGURINHAS do Smartico, 07672c7ae cai em todas as missões quando a seção não existe, 0d0fed93e mescla Smartico e BFF por id e 8dca06afd remove /users/me/missions (deprecado — o Smartico é autoritativo).
Renderização de flip-book e polimento visual — b64d23165 (capa centralizada, tag de faixa de páginas, backgroundImageUrl), 7b84ca712 (continuidade do flip: fatia da lombada, imagem de curl, lombada antecipando o BACK), 746803a4c (tap-to-flip nas bordas), bac022447 (thresholds assimétricos de commit FORWARD/BACK), 253ed4f2e (watermark central nos cards travados), b0a8d3c51 / bc9f28802 (dimensões, centralização e escalas proporcionais no mobile). d392f4072 fecha a semana com a LP de compartilhamento, download de composição e preview anônimo. Testes em c26c5af85, ad332e995 e 9340a8888 cobrem handshake, orquestração, os seis endpoints /api/album/* e os gates de degradação do loader.
Chaves album.* de i18n foram adicionadas como overrides do host em vez de irem pro core (e251c0d09), e 8d78a79d7 troca nomes de placeholder por versões neutras na config base.
Mixpanel removido de todas as marcas — retratação
cfd4d43a3 remove a integração Mixpanel por completo: script, hook, config, tipos, eventos e dependência. Foram deletados app/config/analytics/mixpanel.ts, app/types/mixpanel.ts, app/hooks/useMixpanel.ts e os três overrides por marca (7k, cassino, vera) que carregavam token e houseName. Os consumidores foram refatorados: useAnalytics perde o useMixpanel(), o useEffect de identify pós-auth e as funções que só existiam pra Mixpanel (trackLoginSubmitted, trackLoginFailed, trackDepositRequested); LoginModal e DepositModal perdem as chamadas correspondentes; AnalyticsLoaders deixa de montar o hook. trackRegistration e trackLogin seguem com os side-effects de GTM e AppsFlyer S2S, e fireDepositEvent de GTM/Pixel continua intacto.
Isso reverte o que este changelog já anunciou. As entradas de 23/04/2026 ("Mixpanel, Hotjar e Pendo integrados como infra genérica e config-driven", mais os eventos de auth Login Succeeded / Sign Up Succeeded e os exclusivos trackLoginSubmitted / trackLoginFailed), 24/04/2026 (consolidação do useMixpanel com paridade total ao legado, fila de identify, people.set, super-properties), 05/05/2026 (evento Deposit Requested) e 09/05/2026 (refactor do mixpanel.ts do override 7k pro pattern isDev()) descrevem um comportamento que não existe mais. Trate-as como registro histórico. O mesmo vale pra menção da entrada de 17/05, onde o Mixpanel aparece como um dos canais da matriz de destinos do registry de analytics recém-criado.
O que continua: tracking segue por GTM, Meta Pixel, Smartico, Hotjar, Pendo, AppsFlyer, Kwai, Taboola, cookie de audiência first-party e CAPI do BFF.
Sessão terminada pelo servidor: HTTP 440 e EM0030
Contrato de erro estendido pra 440 — core fa05bc7 faz o ApiClient.send disparar onUnauthorized em 401 ou 440, e o retry de refresh-token é deliberadamente pulado no 440: o BFF invalidou a sessão por conta própria (force-logout administrativo, motor antifraude, pausa regulatória), então repetir só produziria outro 440. Entra o código EM0030 no registry de erros, classificando o status 440 com a chave auth:session_error.session_terminated. DEFAULT_REFRESH_SKIP ganha /auth/logout-auto e /api/auth/logout-auto; o AuthService de accounts ganha logoutAuto(); a i18n ganha session_terminated e as chaves de menu/confirmação de logout nas sete locales.
Lado do base — 875a086bb adiciona a flag useAutoLogoutEndpoint em AuthFeatureFlags, que roteia o logout forçado pra /api/auth/logout-auto → POST /auth/logout-auto do BFF, de forma que o log de auditoria distinga logout iniciado pelo usuário de logout forçado. Default false, ligada só na vera-bet-br; o botão "Sair da conta" continua em /api/auth/logout independente da flag. O interceptor de api-fetch.client.ts reage a 401 ou 440, o deleteJwtCookie despacha entre as duas rotas conforme a flag, o guard de recursão cobre os dois paths, e useAuthInit passa a retornar null também no 440. Bumps: api-client0.16.0, accounts2.6.0, i18n0.90.0.
AUTH_SENSITIVE_STATUSES vira [401, 403, 440] em app/utils/proxy-error.server.ts — as ~60 rotas internas que passam o body do BFF intacto pro classifier agora preservam a reason real também no 440.
Status real do BFF preservado no /api/auth/profile — 64ac037d0. A rota devolvia 401 incondicionalmente sempre que a chamada subjacente falhava, porque getAuthForRequest engolia tudo num catch {} vazio e retornava null. Consequências reais: um 440 era reescrito como 401 e caía no EM0005 genérico em vez do EM0030 novo; e erros 5xx do BFF ou falhas de rede também eram mascarados como 401, forçando logout espúrio via handleUnauthorized (401 é auth-sensitive no interceptor do client).
Launchers no core — 74b2b66 adiciona @cactus-agents/kyc/unico com createUnicoLauncher() (carregador de script e estilos, wiring de clientBoxControl, launch type IFRAME) e @cactus-agents/kyc/sumsub com createSumsubLauncher() (builder do WebSDK com config de idioma/país/documento), ambos portados do stack Vue legado. KycStartResponse passa a declarar token e process_id opcionais, casando com o contrato do BFF pra operadores de SDK, e o helper novo inferKycIntegrationType() classifica a resposta de start em iframe / sdk / unknown. parseKycOperatorMessage ganha casos explícitos pra unico e sumsub para o fallback genérico do consumidor não casar com strings soltas. 39 testes novos; o pacote passa a buildar três entradas.
Integração no base — d5430061b porta a integração baseada em SDK por cima desses launchers: a store de KYC ganha integrationType, sdkToken e processId; o useKycFlow.start() classifica a resposta do BFF em iframe vs SDK e valida os requisitos por operador (Unico exige process_id), expondo finishAndPoll pros painéis de SDK; entram UnicoSdkPanel, SumsubSdkPanel e o dispatcher KycSdkWrapper; e o KycModal renderiza iframe ou wrapper conforme integrationType, preservando os estados de aprovação manual pendente, mobile e erro. Flag nova kyc.unicoEnv (default "prod") propagada pra todos os overrides, porque override é substituição de arquivo inteira. Os subpaths novos foram regenerados nos dois tsconfig. +15 testes.
5fad1ce56 passa a pré-validar a senha atual antes de iniciar o fluxo de KYC e 2286daf63 mostra mensagem localizada amigável quando o current_password não bate.
Fim do flood de 499 em /buscar.data e da corrida de digitação — 17ac07b81 resolve dois problemas de uma vez. O primeiro: 1,34 milhão de 499 do Cloudflare em 7 dias numa única marca, porque cada tecla atualizava o ?q= via setSearchParams, disparando revalidação dos loaders de root, _layout e da busca — cada revalidação emitia um /buscar.data?_routes=… que o React Router cancelava quando a tecla seguinte chegava. Agora o shouldRevalidate do root.tsx só re-roda quando chegam UTM/afiliado/clicked-id novos, e o do _layout.tsx honra formAction e revalidação explícita (modais de login/logout/registro/KYC) mais mudança de path, mas ignora mutação de query no mesmo pathname. O segundo: o bug da "letra que desaparece" ao digitar rápido (fortune virava forune), causado por um sync bidirecional em useSearchParamSync que sobrescrevia store.term com o valor velho da URL. A store ganha lastResolvedTerm como único sinal que espelha pra URL, setado só quando o doSearch resolve; buscas abortadas nunca tocam a URL, que passa a ser output-only durante a digitação.
Providers e categorias entram nos resultados — 8b8a70b88. Antes, digitar "evol" não encontrava o provider Evolution, porque /api/search/unified só devolve jogos e esportes. Agora o ResultsState filtra categorias e providers com o helper canônico foldForSearch de @cactus-agents/games — insensível a diacríticos, mesmo algoritmo do filterGames — em duas seções novas de até 8 chips cada. Ordem em /buscar: Cassino → Providers → Categorias → Esportes. No mesmo commit, resultados de esportes ficam capados em 12 visíveis com CTA "Ver todos" (antes renderizava o array inteiro, que podia passar de 90 eventos), e /buscar/all é dividido em /buscar/cassino e /buscar/esportes.
Fallback pro catálogo em memória quando o BFF devolve zero — 8e00f887c. Reportado na pb-bet: buscar "Fortune Tiger" dava "Nenhum jogo encontrado" enquanto o mesmo jogo era alcançável por link fixo na sidebar. Quando getListPage retorna total === 0, o fluxo cai em gamesCacheService.search(), que filtra o catálogo cacheado em memória com foldForSearch. Só roda em resposta vazia, então marcas com busca de BFF funcionando não pagam nada; erro no fallback é engolido e o resultado vazio do BFF prevalece.
e40221dc2 enxuga o loader de /buscar, restaura o título e deixa o botão de voltar mais esperto.
Camada de config opt-in — 932583090 cria os tipos SitemapConfig / SitemapGroupDef / SitemapPriorityRule / SitemapSource em app/types/sitemap.ts, o default { groups: [] } em app/config/seo/sitemap.ts, o resolver app/services/sitemap-config.server.ts com matching de glob por segmento e geração de XML, e a rota genérica /sitemap-{groupName}.xml. Rotas literais existentes vencem por especificidade do React Router. A vera-bet-br é a primeira a aderir, declarando 5 grupos extras (blog, promoções, VIP, cassino, esportes).
Segundo mecanismo: routeOverrides — 81a5a7cb1 adiciona SitemapConfig.routeOverrides e o applyRouteOverrides(urls), que percorre as URLs e aplica a primeira regra que casar, virando no-op quando o campo é ausente. Sete rotas compartilhadas de sitemap passam a envolver suas listas com ele. A cassino-bet-br adere com 24 grupos e ~80 regras de override.
As cinco rotas de grupo precisaram ser registradas explicitamente — 47a07d5da. A tentativa anterior usava uma rota só, route("sitemap-:groupName.xml", …), esperando capturar blog, promocoes, vip, cassino e esportes. O React Router 7 não aceita :param depois de -, só depois de / — a rota não casava com nada e o request caía no splat 404 do layout, renderizando página de erro com chrome da marca em vez de XML. O fix registra cinco declarações explícitas apontando pro mesmo handler, cada uma com id único, e o handler deduz o grupo pelo pathname do request em vez de params.groupName via resolveGroupSitemap() — mais robusto e independente da convenção de naming.
Dispositivos fracos: detecção de low-end e redução de custo de GPU
Infra de detecção — 39f97210d adiciona app/hooks/useIsLowEndDevice.ts com heurística Android-aware: em Android, navigator.deviceMemory <= 4 GB (o valor é quantizado em {0.25, 0.5, 1, 2, 4, 8}, então <= 4 pega exatamente os aparelhos de 4 GB físicos sem capturar 6/8 GB, que reportam 8); fora de Android, hardwareConcurrency <= 4 como rede de segurança pra iOS antigo; e universalmente saveData === true ou effectiveType em slow-2g / 2g / 3g. Override de DEV via ?lowend=1, SSR-safe (retorna false no servidor e no primeiro paint). app/context/device.tsx expõe useIsLowEnd() ao lado do useIsBot() existente, e app/types/feature-flags.ts ganha forceLowEndMode pra uma marca forçar o modo lite.
Reduções universais — pontos onde o ganho visual do backdrop-filter não paga o custo de GPU passam a ser opacos. dafa25ab0 reduz custo de GPU/CPU em Android low-end na vera e f72fc022e remove os blurs sempre-ligados do card de jogo de grid legado. 48075063c corrige um falso positivo no iOS e o gap de tamanho intrínseco do card de jogo.
Sportsbook: a saga do deep-link de regras de aposta
Cinco commits no dia 18 fecham o comportamento de "Regras de Apostas" no iframe: ea87e9a9e fixa o item na sidebar e faz a aba Cassino navegar, 061b200af injeta o hash de betting-rules já na URL de launch inicial, adfebffd8 mantém o hash grudado entre refetches da URL de launch, 2b5d24903 passa a usar o hash da URL do parent (à prova de StrictMode) e 0cb2a0144 pula o deep-link de boot quando o usuário já chega com o hash. 37064b875 gateia o item pelo provider principal da marca em vez da rota ativa, c8a9c39fc roteia o trigger pela navegação quando o usuário está fora de /sports, 68e39d509 mantém a seção de esportes aberta em rotas de cassino nas marcas que têm o recurso, e ec17a4ac2 / fdab46fec acertam a navegação e o drawer mobile ao trocar de aba.
Core adapta o builder de URL do First ao contrato v4 — a5f6715. O iframe atual (spbkv4) ignora em silêncio tanto o contrato de deep-link por hash (#Live, #Upcoming, #Early) quanto a API de postMessage({ eventType: "eventlistTab" }): a troca de aba passou a viver no path. buildFirstRedirectUrl foi reescrito pra emitir /spbkv4/live?selectedDefaultTab=Live, /spbkv4/az (lista A-Z, o análogo mais próximo da aba "Em Breve" — a v4 não expõe path dedicado pra upcoming/early no nível global) e /spbkv4 pra home, normalizando URLs /spbk legadas e removendo segmentos de aba pré-existentes. discoveryPathFromQueryParams e pathEntryFromRoute deixam de forçar Upcoming como fallback.
f7e5e6e43 corrige o slug do filtro de Crash Games (crash-games → jogos-crash) e 8167f99e7 restringe o fix às marcas BR.
Torneios e missões ordenados por relevância — 20fd05247. Torneios usam um sinal real de participantes (registration_count DESC com is_featured e start_time como desempate), aplicado incondicionalmente no TournamentsSection e como ordenação default de /vip/tournaments. Missões não têm contagem de participantes no tipo do Smartico, então o proxy de relevância é is_featured primeiro e position ASC (ordem do backoffice) depois. Helpers e testes em app/utils/gamification-sort.ts. 1571884d0 corrige a herança de tier em nomes de nível intermediários e 77477c1b2 atualiza o estado da missão ao vivo dentro do modal de detalhe.
Página de promoções com filtros no topo — 2c510e837 troca o layout de sidebar-à-direita (estilo blog) por um header estilo cassino: título à esquerda, ícone de funil e busca inline à direita no desktop, toggles no mobile, filtros abertos por padrão. Categorias viram chips horizontais em carrossel com "Todas" sempre fixa na primeira posição — sem reordenar a ativa, porque promoções têm poucas categorias e mover a ativa pro índice 0 só causaria salto visual. Grid expande pra 4 colunas em lg+. Componentes novos ficam escopados em content/ (ContentCategoryChips, ContentSearchForm com <Form method="get"> SSR-safe, ContentListPageTopFilters), e as duas props adicionadas aos componentes compartilhados preservam o comportamento do cassino por default.
userFullName propagado pro iframe de campanha — 572550931, imediatamente escopado só aos minigames diários por 0b65e36a5, estendido ao CampaignWidget flutuante por bb785175a e finalmente convertido em opt-in explícito includeUserFullName com trigger de visita gateado por auth em 6e9dc1f9d. Em paralelo, três fixes de sobreposição: 74d4660d0 põe o overlay do iframe no z-index máximo e suprime popups do Smartico, 36a0d20d5 restringe a supressão por strategy e ebeedfd1d dá paridade às marcas irmãs.
Regras de exibição das notificações apertadas — 4c778852b cria a flag app_installed (localStorage) marcada quando o usuário aceita o prompt de PWA, abre a loja ou clica no link externo, sondada passivamente por navigator.getInstalledRelatedApps no mount; e troca o closeStorage de download_app, referral, telegram e tournament pra "session", então o X reaparece na sessão seguinte em vez de sumir por 7 dias. e0fa1f95f faz o anúncio de check-in aparecer uma vez por dia em vez de uma vez por sessão, e 6214caa1a dá claim otimista com reconciliação em background e rollback.
/bff/transactions-new entrou e saiu na mesma semana — 0cfae0b97 opta a cassino pelo endpoint novo de histórico, 09bc29615 estende pra 7k e vera, 54b6e4587 adiciona logs dev-only no proxy pra diagnóstico de endpoint, 58fbc947b corrige o date_period pra snake_case no body — e dbfa8f038reverte tudo, mantendo o endpoint default. Vale como registro: o contrato novo não estava pronto.
Card de logout redesenhado com confirmação — 725a60737. O link "Sair" no rodapé do painel era visualmente apagado e confuso: replays do Pendo mostravam usuários tocando nele esperando fechar o painel, e logando de novo em seguida. Virou seção SESSÃO com card de borda vermelha no estilo do menu de conta, mais confirmação em duas etapas (Sim/Não na mesma altura de ~64px) protegendo contra toque acidental — o painel fica a um toque do avatar na topbar.
Versão 3.0 nos cabeçalhos de KYC e PLD-FTP — 46838bc6f alinha 7k, cassino e vera ao conteúdo curado publicado como 3.0, e fddb5becc adiciona override de updatedAt estático pra essas páginas, pinado em 10/12/2025.
0868acb96 passa a usar o list-referrals do BFF diretamente em vera, cassino e 7k, e c471e5ddf trata cancelamento do share-sheet como no-op em vez de disparar o fallback.
Pacote @cactus-agents/api-client bumpado pra 0.16.0 e depois 0.16.1: o primeiro traz EM0030 e o onUnauthorized em 440; o segundo (via base f99128e20) remove /payment-providers das DEFAULT_API_CACHE_RULES — estava com TTL de 12h e sobrevivia ao /api/cache/purge, porque o cache do SDK usa prefixo de KV próprio, fora do platform-cache.engine — e bumpa CACHE_KEY_PREFIX de :v1 pra :v2, invalidando todas as entradas cacheadas do SDK no próximo deploy.
Pacote @cactus-agents/accounts bumpado pra 2.6.0 (logoutAuto(), defaultFetchProfile() tratando 440 como 401).
Pacote @cactus-agents/kyc ganha os subpaths unico e sumsub (74b2b66).
Pacote @cactus-agents/i18n bumpado pra 0.90.0 (session_terminated, chaves de menu e confirmação de logout) e depois recebe 237b8c1 (copy de fallback de instalação manual do app em pt-br) e 69e1f9e — as chaves do redesenho de spotlight de torneios e missões nos namespaces tournaments, missions e missions_card, nas sete locales (pt-br, pt, en, en-ng, es, es-cl, fi-fi).
Pacote @cactus-agents/payments recebe dusupay e korapay (ae24037).
6fd3fe7 documenta a decisão de não cachear /payment-providers (dado mutável, risco de stale) e bumpa o CACHE_KEY_PREFIX de v1 pra v2.
7k-bet-br: semana inteira gasta no srcset do banner da home — 19668df4e corrige as larguras pra casar com o card de 460px, 2157b5d4d e 7eaa44da6 testam aspectRatio 460/187 e altura de 187px, f50f551b5 adiciona 920px pra Retina, 901b8b8ca corta pra [360, 460] sem overhead de Retina, e fac89ba31reverte tudo pro banner original de 460×167px. 4b6436a61 e a26660130 deixam a nota de que a mudança de srcset precisa de aprovação de review. Único override com o álbum ligado.
vera-bet-br: favicon descobrível na busca do Google (caf4d5dbf); redução de custo de GPU/CPU em Android fraco; sitemap com 5 grupos extras; única marca com useAutoLogoutEndpoint e /logout-auto ligados; links sociais do perfil do Xand Avião atualizados no 7k (bb4564a15).
cassino-bet-br e vera-bet-br: central de ajuda e FAQ ativadas via WordPress (751a1b355); redirects universais do 7k aplicados às duas (ab0b65866).
cassino-bet-br: sitemap com 24 grupos e ~80 regras de routeOverrides.
Todos os overrides: flag kyc.unicoEnv e useAutoLogoutEndpoint propagadas por causa do contrato de substituição de arquivo — omitir campo em override deixa a marca com undefined.
0a5eceebd resolve a imagem de post do WordPress via thumbnailUrl do schema Yoast em /promocoes (vera), 22139ab92 faz o modal de registro usar o padrão de bottom sheet removendo um disableSheetDrag hardcoded, e 85ada8a4c mostra confirmação de saída ao dispensar o modal de registro por swipe.
Dois agregadores nigerianos entram no SDK — core ae24037 adiciona os slugs dusupay e korapay em PaymentMethodSlug, com ícones SVG novos em packages/payments/icons/payments/ (copiados automaticamente pra public/icons/ do base pelo plugin copyPaymentIcons do Vite). Os dois são classificados como CHECKOUT_PAGE_METHODS — mesmo caminho de render de khipu e pixtopay-global: o BFF devolve a URL de checkout e o front embute como iframe via DepositResultCheckoutPage. Cobrem transferência bancária, USSD, mobile money e cartão na página hospedada do provider.
Instalação do app unificada num contrato explícito — 8b5e8fc27 aposenta o campo único vindo do BFF (brand.appearance.links.appDownload) e cria appInstallConfig (googlePlay + appleStore, overrideável por marca) consumido por todas as superfícies: sidebar, notificações de topbar e de baixo, pill e badge do rodapé, e a LP. O useAppInstall virou resolver esperto com união de ações (google_play / apple_store / pwa_prompt / ios_safari_tooltip / ios_other_tooltip / hidden), o novo app/hooks/useDeviceDetection.ts encapsula os helpers de @cactus-agents/utils, e uma store global (app/store/installTooltip.ts + InstallAppTooltipRoot montado uma vez no DefaultLayout) garante instância e posicionamento únicos do tooltip. Entra também a LP genérica /lp/download-app com hidratação skeleton-first, CTA dinâmico de um botão + dropdown, bloco único de instruções ciente do SO e JSON-LD HowTo + SoftwareApplication; /app-download redireciona pra ela. 98ac95633 completa com CTA sempre acionável e tooltip de fallback pra instalação manual. Suporte no core: ca99948 adiciona getUserAgentPlatform() (UA Client Hints com fallback pra UA-string e detecção de spoofing de iPadOS), isTouchPrimary() e o tipo unificado OsId, mais o namespace app_download_page.* de i18n nas sete locales.
bd342a91d (e o duplicado d976f0a7b) corrigem a unidade do parâmetro ?value= de depósito, que estava em centavos e devia estar em reais.
Middleware do Worker limpo de código brand-specific — be61e52d7 remove 136 linhas: o mapper de ~11 patterns de slug do Zendesk legado e o bloco de host que o chamava eram dead code, porque só dispararia se o host de atendimento fosse bindado ao Worker, o que o time de ops não vai fazer (a decisão é redirecionar o host preservando o path). Tudo migrado pro sistema existente de legacy-redirects, que é overrideável por marca, resolvido via routeHref() e neutro por design — o middleware compartilhado voltou a respeitar a regra de neutralidade. 465c02fa8 mantém o tratamento de artefatos /deploy-* legados na borda e 1e1c2e213 passa a usar env.ORIGIN_DOMAIN nos destinos dinâmicos de redirect em vez de host fixo.
Workflow de purge manual de cache — front-ops 7583319 adiciona um workflow_dispatch "Manual Cache Purge" que resolve a config do ambiente a partir de config/brands/web-base/environments/<env>/deploy.yml, escolhe o secret de purge correto automaticamente, suporta dry-run e imprime um resumo com host alvo, modo, status HTTP e body da resposta — qualquer dev autorizado purga sem precisar de FECA CLI configurada localmente. O mesmo commit adiciona brandConfig e paymentProviders aos segmentos de purge pós-deploy: o endpoint /api/cache/purge do worker da marca cascateia pro proxy do front-service-api (filtrado por originDomain), que limpa o cache de TTL 5min.
TTLs do front-service-api reduzidos — 379d10c: games/base, games/home, casino-games e getlegalterm de 12h pra 6h; bookmaker-settings pra 2h; bff/features e appearance pra 1h; payment-providers de 12h pra 5min, porque a ordenação no backoffice é mutável em tempo real. Ficam em 12h só os dados de fato estáticos (configurations/casino, country, crypto/all). O GLOBAL_VERSION e o prefixo de hash MD5 foram bumpados juntos pra invalidar o namespace inteiro (Cache API do CF + KV) no deploy, garantindo que nenhuma entrada de 12h do caminho antigo sobreviva à queda de TTL. 6e23708 passa a usar o env na chave de cache.
front-ops: auto-deploy desabilitado em betpontobet-bet-br, cassino-bet-br e prod-7k-bet-br (ebe683f) e em vera-bet-br (efab0ee); default branch do ng-7k-bet ajustada de novo (0f2040d).
ed87d5aa5 para de versionar um symlink de node_modules e 275cb3b32 evita que o Tailwind capture uma classe arbitrária inválida escrita dentro de um comentário.
3c857f650 sincroniza o documento de migração pro host com a versão mais recente do sticker-book, e 3a2a0eab6 versiona a auditoria de porte com os 53 achados.
7ff162824 documenta as envs STICKER_API_* e passa a avisar quando o fallback de DEV está em uso.
f99128e20 documenta em docs-internal que payment-providers é cacheado upstream no front-service-api com TTL de 5min e referencia as ferramentas de purge de emergência (feca purge e o workflow_dispatch novo).