Pular para o conteúdo principal

Sports

Integracao de sportsbook multi-provider no template. Suporta First (iframe), Altenar (JS SDK) e Betby (JS SDK) via o pacote @cactus-agents/sports.

Visao geral

sports.config.ts (dados estaticos, fork-overridable)
|
+---------+-----------+
| |
v v
useSportsConfig() sportsConfig (import direto) <-- client / server
| |
v v
_layout.tsx loaders / API routes
|
v
SportsAltenar / SportsBetby / SportsIframeFirst

A selecao do provider e feita 100% por configuracao — sem mudancas de codigo para trocar entre providers.

:::info Regra arquitetural app/config contem somente dados estaticos de brand. Hooks, parsers e logica de negocio nao devem ficar em app/config. O hook useSportsConfig() vive em app/hooks/useSportsConfig.ts. :::

Configuracao

sports.config.ts (client)

Arquivo principal de configuracao (fork-overridable):

import type { SportsModuleConfig } from "@cactus-agents/sports";

export const sportsConfig: SportsModuleConfig = {
main: null, // provider principal (/sports) — null = desabilitado
test: null, // provider de teste (/sports-test) — null = desabilitado
first: {},
altenar: {
integration: "my-brand",
libraryUrl: "https://sb1client-altenar.biahosted.com/...",
},
betby: {
brandId: "my-brand-id",
theme: "default",
libraryUrl: "https://ui.betby.com/...",
},
};

O sportsConfig e importado diretamente tanto no client quanto no server — nao ha mais um wrapper sports.server.config.ts. API routes fazem import { sportsConfig } from "~/config/sports.config".

Overrides por brand

As configuracoes podem ser sobrescritas por brand em:

  • overrides/<brand-key>/app/config/sports/sports.ts

<brand-key> vem de ORIGIN_DOMAIN normalizado.

Hook — useSportsConfig()

Hook central consumido por rotas e componentes. Localizado em app/hooks/useSportsConfig.ts:

import { useSportsConfig } from "~/hooks/useSportsConfig";

const {
config, // SportsModuleConfig completo
activeProvider, // provider ativo para a rota atual
hasSports, // true se main != null
hasTestRoute, // true se test != null
isTestRoute, // true se pathname = /sports-test*
getConfigFor, // retorna sub-config de um provider
} = useSportsConfig();

O hook importa sportsConfig de ~/config/sports.config e combina com getActiveProvider() do SDK para resolver o provider ativo baseado na rota atual.

Componentes

SportsIframeFirst

Renderiza <iframe> do First com comunicacao postMessage. Sincroniza navegacao bidirecional entre o iframe e React Router via URLs semanticas.

SportsAltenar

Carrega o SDK Altenar dinamicamente, inicializa com AltenarWSDK.init(), e sincroniza navegacao via onRouteChangeDetailed. Busca token de auth via /api/sports/altenar-token.

SportsBetby

Carrega o SDK Betby (BTRenderer), autentica via /api/sports/betby-jwt. Recarrega a pagina em mudancas de auth (login/logout) para reinicializar o SDK.

Rotas

RotaDescricao
/sportsLayout + index. Renderiza o provider ativo.
/sports/*Catch-all. Deep links de esporte.
/sports-testProvider alternativo para testes.

O layout monta o componente do provider uma vez e mantem vivo em todas as sub-rotas. O conteudo interno e controlado pelo SDK do provider, nao por rotas React.

API Routes

RotaDescricao
api/sports/searchBusca esportiva
api/sports/launchLaunch First (autenticado)
api/sports/anonymous-launchLaunch First (anonimo)
api/sports/betby-jwtJWT para Betby
api/sports/altenar-tokenToken para Altenar

Define items de navegacao com paths por provider:

export const sportsMainItems: SportsSidebarItem[] = [
{ slug: "live", label: "Ao Vivo", firstPath: "...", betbyPath: "...", altenarPath: "..." },
{ slug: "upcoming", label: "Comeca em Breve", ... },
{ slug: "esports", label: "E-Sports", ... },
];

export const popularChampionships: SportsSidebarItem[] = [
{ slug: "brasileirao-a", label: "Brasileirao Serie A", flagCode: "BR", ... },
{ slug: "champions-league", label: "Champions League", flagCode: "EU", ... },
// ... 11 campeonatos
];

Cada item carrega firstPath, betbyPath e altenarPath. O path correto e resolvido em runtime via resolveMenuItemPath().

Configurando uma nova marca

  1. Criar overrides/<brand-key>/app/config/sports/sports.ts
  2. Definir main com first, altenar, betby ou null
  3. Opcionalmente definir test para habilitar /sports-test
  4. Configurar altenar ou betby dentro do arquivo quando necessario
  5. Customizar items do sidebar em sidebar-sports.config.ts se necessario