Split backend into tavolo-platform, tavolo-scopone and tavolo-app packages
Move the game-independent machinery (lobby, live-game store, websocket, deadline scheduler, match history, leaderboards) into a new tavolo-platform distribution behind a GameEngine contract, the scopone scientifico rules plus a platform adapter into tavolo-scopone, and keep only the composition root in tavolo-app. The three distributions share the tavolo namespace (PEP 420, kaya-style monorepo). Match history becomes fully generic: Match carries the engine's result JSON and MatchPlayer points/details instead of scopone-shaped team columns (migration 3 backfills existing rows). Lobby creation takes an opaque per-game options object and websocket actions dispatch to the session's engine. Tests: platform suite runs against a DummyEngine toy game, scopone keeps the rules tests plus new adapter tests, server/tests covers the wired stack end to end (194 tests, was 143).
This commit is contained in:
72 files changed
+4490
-2102
No files matched your search
@@ -0,0 +1,50 @@
|
||||
"""The :class:`PlatformMixin`: mounts the whole platform on a kaya app.
|
||||
|
||||
``Platform`` bundles the collaborators every platform endpoint needs —
|
||||
the game registry, the live-game store, the deadline scheduler and the
|
||||
OIDC mixin used for authentication — so route and websocket modules
|
||||
never reach for module-global state. :class:`PlatformMixin` is a plain
|
||||
:class:`~kaya.core.KayaMixin`: applying it registers the lobby, stats
|
||||
and health HTTP routes plus the live-play websocket endpoint, and the
|
||||
app stays a :class:`~kaya.core.KayaApp` (both ASGI and RSGI keep
|
||||
working).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from kaya.core import KayaApp, KayaMixin
|
||||
from kaya.oidc import OIDCMixin
|
||||
|
||||
from .deadlines import DeadlineScheduler
|
||||
from .registry import GameRegistry
|
||||
from .store import GameStore
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Platform:
|
||||
"""The collaborators shared by all platform endpoints."""
|
||||
|
||||
registry: GameRegistry
|
||||
game_store: GameStore
|
||||
scheduler: DeadlineScheduler
|
||||
oidc: OIDCMixin
|
||||
|
||||
|
||||
class PlatformMixin(KayaMixin):
|
||||
"""Register the game-independent routes and the websocket endpoint."""
|
||||
|
||||
def __init__(self, platform: Platform) -> None:
|
||||
self.platform = platform
|
||||
|
||||
def apply(self, app: KayaApp) -> None:
|
||||
# Imported here so module import order stays acyclic: the route
|
||||
# modules reference Platform only for typing.
|
||||
from . import ws
|
||||
from .routes import games, health, me, stats
|
||||
|
||||
health.register(app, self.platform)
|
||||
me.register(app, self.platform)
|
||||
games.register(app, self.platform)
|
||||
stats.register(app, self.platform)
|
||||
ws.register(app, self.platform)
|
||||
Reference in new issue
Block a user