Skip to content

feat(gaming): read-only game catalog port for plugins - #174

Merged
okapitula merged 3 commits into
devfrom
feat/add-game-catalog-reader
Sep 17, 2026
Merged

okapitula merged 3 commits into
devfrom
feat/add-game-catalog-reader

Conversation

@okapitula

Copy link
Copy Markdown
Collaborator

Summary

Adds GAME_CATALOG_READER, a read-only port owned and registered by the gaming module. Plugins outside casino/gaming can use it to read playable games, active categories and active providers without importing the gaming tables.

Why

Overlay lobby sections (defineLobbySection) need games, categories and providers. Until now the only way to get them was to import @openora/core/casino/schema/gaming and write their own Drizzle queries. That copied the playability rule into consumer code. One overlay checked only game.isActive, so games from a disabled provider still showed in its lobby sections. Each of those schema reads also blocks extracting gaming into its own service (ADR-0017).

The port applies core's own playableGameCondition() (game and provider both active), so consumers can't drift from core's visibility rule. It returns plain objects typed from the game.ts contract schemas, and every method answers a whole list of ids in one query:

  • getPlayableGames(ids), getActiveCategories(ids, { withGameCount? }), getActiveProviders(ids) and getCategoryIdsByGame(ids) return a Map in the order the ids were passed. Unknown, inactive, unplayable or malformed ids are left out rather than throwing.
  • listPlayableGamesInCategory(id, { limit }), listActiveCategoriesWithGameCount() and listActiveProviders() return ordered lists.
  • gameCount counts playable games only.

The gaming services now share their provider and category column sets and the countWhere helper through casino/shared/game-catalog.ts. The selected columns haven't changed.

Alternatives considered

  • Export GamingService, GameProviderService and GameCategoryService: module-structure rules forbid importing another module's service, and those services also carry audited admin writes. Their reads are paged or fetch a single row, so a lobby section would end up doing one query per game.
  • Expose playableGameCondition() on a public subpath: consumers would still query gaming's tables directly, which keeps the extraction blocker and the duplicated queries.

Risks

None.

Comment thread packages/core/src/casino/gaming/adapters/game-catalog-reader.service.ts Outdated
zaxovaiko
zaxovaiko previously approved these changes Sep 15, 2026

@zaxovaiko zaxovaiko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Adds GAME_CATALOG_READER, owned and bound by the gaming module, so plugins
outside casino/gaming can read playable games, active categories and active
providers without importing the gaming tables or re-implementing the
playability rule (game and provider both active).
@okapitula
okapitula merged commit 3e8e0a7 into dev Sep 17, 2026
3 of 4 checks passed
@okapitula
okapitula deleted the feat/add-game-catalog-reader branch September 17, 2026 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants