Motor de catálogo de conteúdo
O motor de catálogo é o núcleo das vitrines de jogos e das seleções promocionais no front-end: ele coleta e normaliza os metadados dos provedores (RGS), oferece busca, filtros e ranqueamento, aplica as regras de disponibilidade por jurisdição e por marca, mistura personalização e posições promocionais e entrega respostas rápidas pela API, com SLO previsível.
1) Objetivos e princípios
Leituras rápidas: p95 ≤ 100–150 ms por consulta ao catálogo ou à busca.
Precisão e atualidade: garantia de que os atributos principais estejam atualizados (disponibilidade, jackpots, status dos provedores).
Flexibilidade: coleções editoriais e espaços promocionais sem precisar de um novo release.
Conformidade: regras de geolocalização, idade e conteúdo, licenças, restrições de Jogo Responsável.
Multi-tenant/multirregião: isolamento das marcas e respeito à residência de dados.
Observabilidade: métricas de qualidade dos resultados, testes A/B, conversão em jogo/aposta.
2) Modelo de domínio (mínimo)
Entidades:- Game: jogo/produto do provedor.
- Provider: RGS/estúdio.
- Variant: variantes de um mesmo jogo (volatilidade, linhas, limites, servidor).
- Collection: seleção editorial ou automática (por exemplo, «Novidades», «Jackpots»).
- Placement: posição fixa/banner/card em uma página ou espaço.
- Capability/Feature: atributos do jogo (free spins, compra de bônus, jackpot).
- JurisdictionRule: regras de disponibilidade e restrições.
- Signals: sinais comportamentais e operacionais (popularidade, CTR, receita).
- Asset: mídia (ícones, pôsteres, vídeos de demonstração) com variantes para dispositivos e densidades de tela.
Chaves: `game_id` (interno e estável, diferente de provider_game_id), `tenant_id`, `region`, `locale`.
3) Ingestão e normalização
Pipeline:1. Source Adapters (coletores): integrações com RGS/estúdios (catálogos, funcionalidades, RTP, tags).
2. Sanitize & Map: mapeamento dos campos externos para um dicionário único (ACL), validação e deduplicação.
3. Enrich: traduções, categorias, tags semânticas, classificação etária.
4. Moderate: flags de conteúdo (NSFW/símbolos religiosos/temas sensíveis) por mercado.
5. Publish: eventos `GameUpserted/ProviderStatusChanged` → projeções do catálogo.
Idempotência: todas as mensagens levam `source_id`+`version_ts`; uma repetição é processada sem efeitos colaterais.
Evolução de esquema: `schema_version` nos adaptadores + migrações dos mapeadores.
4) Esquema normalizado (simplificado)
json
{
"game_id": "g_3f92",
"tenant_id": "brand_eu",
"provider": { "id": "pr_evolution", "name": "Evolution" },
"title": { "en": "Lightning Roulette", "de": "Lightning Roulette" },
"capabilities": ["live","roulette","multiplier","bonus"],
"rtp": 97. 3,
"volatility": "high",
"limits": { "min": 0. 1, "max": 1000. 0, "currency": "EUR" },
"jurisdiction": {
"allowed": ["MT","EE","DE"],
"blocked": ["NL","BE"],
"age_rating": 21
},
"assets": {
"tile": { "1x":"...", "2x":"..." },
"poster": { "web":"...", "mobile":"..." }
},
"tags": ["new","jackpot"],
"release_date": "2025-09-12",
"status": "active",
"variants": [{ "id":"v1","server":"eu-central-1","rtp":97. 3 }]
}
5) Busca, filtros e facetas
Índices: texto completo por nome/sinônimos, facetas por `provider`, `capabilities`, `volatility`, `rtp_bucket`, `tags`.
Filtros: jurisdição/região/idioma/dispositivo/idade, somente jogos ativos/certificados.
Sinônimos/stemming: mapa de termos usados pelos jogadores («livros», «frutas», «bolas»).
Erros de digitação: busca tolerante (edit distance ≤ 1–2), limitada pelo tamanho da palavra.
6) Ranqueamento: sinais e fórmula
Sinais (exemplo):- Freshness (tempo desde o lançamento).
- Popularity (inicializações por hora, jogadores únicos).
- Quality (CTR do catálogo para o jogo, retenção em 1/7 dias).
- Business (impulsos de marketing, acordos comerciais, espaços promocionais).
- Compliance (rebaixamento suave para conteúdo sensível, quando necessário).
- Player-fit (compatibilidade com o perfil/preferências do jogador).
score = w1freshness + w2popularity + w3ctr + w4player_fit + w5boost
Os pesos são controlados por configuração/experimentos; todos os sinais são normalizados em [0;1].
7) Personalização
Memória curta: últimas inicializações e gêneros; RYW — o jogador vê imediatamente suas ações recentes.
Memória longa: embeddings dos jogos e do perfil do jogador (gêneros, volatilidade, sessões).
Segurança: a personalização nunca viola as regras de jurisdição e de idade.
Fallback: com poucos sinais, ranqueamento neutro + coleções editoriais.
8) Coleções e posições promocionais
Coleções:- Automáticas: regra/consulta (por exemplo, `capabilities contains 'jackpot' AND release_date >= NOW()-30d`).
- Editoriais: lista manual com ordem e prazos.
- Posições: lugares fixos nas páginas (hero, row-1-slot-3), testes A/B, segmentação por público/jurisdição.
- Prazos e prioridades: `starts_at/ends_at`, prioridade em caso de conflito, pré-visualização antes da publicação.
9) Conformidade e política de disponibilidade
Geolocalização/jurisdição: listas de países/regiões permitidos e bloqueados, verificação de licenças/certificados.
Classificação etária: idade mínima, avisos, ocultação em mercados incompatíveis.
Temas/símbolos: flags de conteúdo sensível por país (religião, álcool etc.).
Jogo Responsável: ocultar ou rebaixar jogos para jogadores com limites/pausa ativa.
Auditoria: log imutável das mudanças de disponibilidade, com os motivos.
10) Multi-tenant e multirregião
Todos os dados são marcados com `tenant_id` e `region`.
Isolamento: quóruns/armazenamento por região; projeções entre regiões apenas com dados agregados.
Fairness: cotas de ingestão/publicação por tenant, para que uma marca «barulhenta» não atrase as demais.
11) Arquitetura geral
Núcleo de escrita do catálogo (CP): normalização + outbox transacional de eventos.
Projeções/Read Models (EC): índices de busca, coleções materializadas, contadores de popularidade.
- Edge/CDN para páginas/imagens «frias».
- Caches em memória para consultas frequentes (key = filtros+página+tenant+region).
- Feature flags: lançamento gradual de regras de ranqueamento/coleções sem novo release.
12) API (REST/GraphQL, exemplos)
REST
GET /v1/catalog? tenant=brand_eu®ion=EE&locale=ru
&filter=jackpot,true&sort=score_desc&page=1&size=24
→ 200 { items:[...], facets:{...}, as_of:"2025-10-31T12:10:02Z" }
GraphQL (trecho)
graphql query Catalog($tenant:String!,$region:String!,$q:String,$filters:Filters){
catalog(tenant:$tenant, region:$region, q:$q, filters:$filters){
items { gameId title provider { name } score badges assets { tile } }
facets { providers { key,count } capabilities { key,count } }
freshnessMs
}
}
Contratos:
- Sempre retorne `as_of/freshnessMs`, paginação e facetas.
- Para personalização, um marcador de sessão (RYW) sem dados pessoais.
13) Sinais e fluxo de dados
Popularidade: incrementos a cada inicialização de jogo → buckets por minuto → agregados nas projeções.
CTR/conversão: contadores de cliques/inicializações por posição/coleção.
Status operacionais: saúde dos provedores (RGS), jackpots/limites (stream de eventos).
Impulsos de marketing: coeficientes temporários para jogos/categorias/fornecedores.
14) Observabilidade e SLO
Métricas do catálogo:- `catalog_p95_ms`, `catalog_p99_ms`, `error_rate`.
- `index_freshness_ms` (atraso das projeções), `ingest_lag_ms`.
- `ctr`, `click-to-launch`, `collection_coverage` (% dos resultados vindos de coleções).
- `lift_ctr`, `lift_conversion`, proporção «explore vs exploit».
- % de regras de geolocalização/idade aplicadas corretamente, número de bloqueios por hora.
Alertas: aumento de `ingest_lag_ms`, queda de CTR nas coleções principais, degradação de um provedor (sinalizada nos resultados).
15) Desempenho e cache
Estratégia: consultas frequentes com cache de 30–120 s, com chave pelos filtros; blocos personalizados com TTL curto (10–30 s) ou sem cache.
Invalidação: pelos eventos `GameUpserted/AvailabilityChanged/PlacementUpdated`.
Paginação: cursores estáveis, para que os cards não «pulem» quando os sinais forem atualizados.
16) Mídia
Perfis de renderização: tamanhos/densidades para web/mobile/TV.
Otimização: WebP/AVIF, lazy-load, sprite/atlas para os cards.
Segurança de conteúdo: varredura, marcas-d'água, proibição de dados pessoais embutidos.
17) Testes
Testes de contrato/esquema para adaptadores e API.
Testes de relevância: conjuntos de consultas de referência → resultados/ordem esperados.
Personalização: AUC/NDCG offline + testes A/B online com métricas de proteção (tempo de jogo, depósitos, sinais de RG).
Caos: degradação de provedores, picos de ingestão, atrasos de indexação.
18) Runbooks
1. Atraso do índice > SLO: pausar coleções secundárias, aumentar a prioridade da ingestão, simplificar temporariamente o ranqueamento.
2. Provedor «vermelho»: rebaixar/ocultar seus jogos e destacar coleções alternativas.
3. Pico de erros na API: verificar o cache/back-end, ativar timeouts de proteção, reduzir o tamanho das páginas.
4. Disponibilidade incorreta: reverter a última regra, ativar a «lista de permissões» para os mercados críticos, auditar as mudanças.
5. Release de ranqueamento: rollout canário (5% → 25% → 50% → 100%), rollback pelo CTR/conversão.
19) Erros comuns
Misturar os esquemas externos dos provedores com o modelo interno (sem ACL).
Não informar `as_of/freshness` → discussões sobre catálogo «desatualizado».
Personalização que viola regras de jurisdição.
Uma única fórmula «mágica» de ranqueamento, sem decomposição dos sinais nem testes A/B.
Páginas grandes sem cache e sem cursores → picos no p99.
Escrita dupla no índice e no OLTP em vez de eventos + projeções.
20) Checklist antes da produção
- Dicionário de campos normalizado e ACL para todos os provedores.
- Ingestão idempotente, outbox/inbox, DLQ e reprocessamento.
- Projeções do catálogo e índices de busca com SLO de atualidade.
- Ranqueamento com pesos controláveis, decomposição dos sinais e testes A/B.
- Regras de conformidade (geolocalização/idade/temas) e auditoria de mudanças.
- Multi-tenant/multirregião: isolamento de dados, fairness, residência de dados.
- API com `as_of`, facetas e cursores; cache e invalidação por eventos.
- Métricas de p95/p99, ingestão/indexação, CTR/conversão; alertas.
- Runbooks de incidentes; releases canário e feature flags.
- Testes de relevância, contrato, caos e personalização.
Conclusão
O motor de catálogo é «buscador + sistema de regras + vitrine» sobre o conteúdo de jogos. Uma ACL sólida, dados normalizados, projeções para leituras rápidas, sinais de ranqueamento transparentes, personalização com métricas de proteção e conformidade rigorosa transformam o catálogo em uma alavanca de crescimento estável e mensurável, sem surpresas em produção e sem concessões perante os reguladores.