Quarto provider de sportsbook, e o primeiro renderizado in-app — 4c37f8967 integra o rogue: um sportsbook React nativo entregue pelo SDK @cactus-agents/sports-rogue, montado dentro da própria aplicação em Shadow DOM e consumindo a Rogue API da First. Diferente de First, Altenar e Betby, que são iframes, aqui o sportsbook é componente. O SportsRogue.tsx monta o SDK via createSportsbook, registra callbacks de auth / login / depósito / share, sincroniza histórico (pushState + popstate → instance.navigate), restaura share links via ?betslip= e aplica offsets de layout por useSdkChromeOffsets.
Rotas server-side e segredo que não chega ao browser — o commit adiciona rogue-anonymous e rogue-login (token) mais rogue-proxy/*, um proxy same-origin pro domínio do provider com streaming de SSE, resolvendo CORS sem expor nada ao client. A chave de API é server-to-server: entra via extraHeaders do api-client e é injetada nos endpoints de token a partir de secret, nunca chegando ao browser. O app/config/sports/provider.ts ganha FORCE_SPORTBOOK (resolveForceSportbook / applyForceSportbook) pra ativar o provider por ambiente sem mexer no main estático da marca. O módulo é autocontido: escudos e assets vêm do CDN default do SDK, sem plugin de cópia no host.
Suporte no core, sem vazar tipos do SDK — 170ca69 declara "rogue" como SportsProvider reconhecido em @cactus-agents/sports, adiciona RogueProviderConfig (tema / scheme / estilo de odds / cores, mais passthrough), roguePath opcional em SportsSidebarItemBase e o caso correspondente em resolveMenuItemPath. Em @cactus-agents/api-client entra extraHeaders opcional em CactusServerClientOptions, mesclado nas requisições de saída, permitindo injetar segredos server-to-server sem forkar o client. Tudo aditivo: comportamento default inalterado. A config do rogue usa superfície comum tipada mais passthrough justamente pra que o SDK siga como fonte de verdade dos próprios tipos.
@cactus-agents/sports-rogue não vive no front-cactus-core — vale registrar explicitamente: o pacote é uma dependência @cactus-agents/* real do front-web-base, mas não está em front-cactus-core/packages/; é publicado de outro lugar. Hoje o PROVIDERS do base declara quatro providers: ["first", "altenar", "betby", "rogue"].
Auth do SDK reconciliada depois do init — 503560f37. O SDK ficava preso em anônimo mesmo com o usuário logado: o efeito de isAuthenticated chamava instance.setAuthenticated() antes de a instância existir (durante o import dinâmico do SDK), virava no-op, e como isAuthenticated não mudava de novo nunca havia nova tentativa — só rogue-anonymous era chamado, nunca rogue-login. O fix guarda o isAuthenticated num ref e, depois do await instance.init(), chama setAuthenticated(isAuthRef.current) pra reconciliar qualquer flip ocorrido na janela de import/init.
Trem de bumps do SDK na mesma semana — fdada3743 (^0.4.0, criador de apostas), 570d71af2 (^0.5.0), a78417352 (^0.6.0), c95dc81f8 (^0.7.0) e 9721f814f (^0.8.0). O 0.3.0 trouxe auth lazy, dedup do token de SSE de 4+ chamadas pra 1 e retry na sidebar de esportes. O pacote segue evoluindo rápido — hoje o base está em ^0.29.2.
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.
Novo evento Mixpanel Deposit Requested (useAnalytics.trackDepositRequested) disparado quando /wallet/add-credit retorna 200 OK. Espelha o legado DefaultLayout.vue das brands 7k/cassino/vera (props Amount em unidades inteiras + DepositMethod). Continua complementar ao evento de funil já existente (pix_generated no GTM e PixGenerated no Facebook).
Bugfix crítico nos eventos S2S do AppsFlyer (sendRegister, sendFTD, sendRebill). Os três estavam dentro do guard if (!shouldLoadTrackers) return do useAnalytics, mas o gate é o inverso do gate do AppsFlyer (shouldLoadTrackers = !isAppMode && !isBot, useAppsFlyer.ready = enabled && isAppMode) — resultado: nenhuma das chamadas server-to-server disparava nem na web (gate externo bloqueia) nem dentro do APK (early return do gate externo cortava o caminho). Agora as três chamadas são disparadas antes do guard e o S2S funciona em produção. Coberto por useAppsFlyer.test.ts (202 linhas) e useAppMode.test.ts (72 linhas).
useAppMode agora reconhece ?is_twa=true além de ?app=true. Os APKs em produção da família 7k/cassino/vera (publicados antes do rename do query param) continuam injetando o legado em cada landing — sem isso isAppMode ficava false pra users do app e desativava todo o pipeline de tracking S2S silenciosamente.
Valor do deposit GTM corrigido pra unidades inteiras (amountCents / 100) ao invés de cents puros — paridade com o legado e com a expectativa dos dashboards de BI.
Banner de consentimento de cookies com Google Consent Mode v2 chega ao base. O CookieConsentBanner (fixado no canto inferior esquerdo, animado, z-60) e o painel CookieConsentDetails (abas Configurações/Sobre, toggles por categoria, tabela de cookies) injetam os defaults do GCM antes do GTM inicializar e gravam a preferência no cookie cactusCookiesConsent. Mapeamento de categorias: performance → analytics_storage, functionality → functionality_storage, demais → ad_storage + ad_user_data + ad_personalization. Bypass para bots via useIsBot(). Feature flag brand.features.cookieConsentPopup controla a exibição por marca, sem build-time config.
Paridade total com o legado Vue (base + 7k + cassino + vera): adicionado o sétimo sinal do GCM v2 (security_storage: granted) para auditorias Lighthouse/CMP enxergarem o contrato completo; COOKIE_TABLE expandida de 6 para 19 entradas cobrindo Cloudflare, GA4, Clarity, Meta Pixel, Kwai, Amplitude, Smartico e cookies de funcionalidade (current_lang, topbar_closed, install_app_popup_closed); migração transparente do formato legado (array JSON de strings) para o novo objeto, sem reprompt de usuários existentes.
UX e visual: o banner se posiciona acima do MobileBottomNav em mobile (h-14), some quando o drawer está aberto, fica print:hidden, e tem split 50/50 entre [Personalizar | Recusar] e [Aceitar todos]. Cores 100% via tokens de tema (bg-secondary, text-texts, bg-primary), eliminando bg-white/* e border-white/* hardcoded. O botão "Salvar" dentro do painel de detalhes se torna "Aceitar todos" quando só a categoria necessária está marcada — replica o saveButton() do legado.
Adicionado motor de validações no core SDK: stores Zustand, hooks e serviços para gerenciar fluxo de validação de jogadores por contexto (depósito, saque, casino, esportes)
Implementado ValidationBlockerOverlay: tela bloqueante com anti-tamper (MutationObserver + interval), bloqueio de ESC e carrossel de steps
Criado ValidationStepsModal: modal fechável para validações contextuais, com visual idêntico ao overlay porém com botão de fechar
Adicionados 10 componentes de step: Email, Telefone, Endereço, Documentos, Senha, Limites, KYC, Termos, GPS e Conta Bancária
Todos os modais tematizados com tokens auth.* do theme.config.ts
Gates de validação conectados nos módulos existentes: GameIframe (antes de abrir jogo), DepositModal, WithdrawModal, Sports layout, e seções da conta do usuário (endereço, documentos, limites, autoexclusão, timeout)
14 rotas de API criadas para todos os endpoints de validação
Utilitário buildValidationSnapshot adicionado
AuthInitializer conectado com sincronização de runtime
Pacote validations publicado no core com motor de regras, tipos TypeScript e testes unitários