120 lines
5.9 KiB
Go
120 lines
5.9 KiB
Go
// Package handlers serves the trusted internal REST surface of Game
|
|
// Master frozen by `gamemaster/api/internal-openapi.yaml`. The package
|
|
// owns one HandlerFunc per OpenAPI operation; route registration goes
|
|
// through Register so the listener (`internal/api/internalhttp`) keeps
|
|
// its lifecycle code separate from the per-operation logic. Handlers
|
|
// delegate every business decision to the `internal/service/*`
|
|
// packages and never decode engine-owned hot-path payloads.
|
|
//
|
|
// The pattern mirrors `rtmanager/internal/api/internalhttp/handlers`
|
|
// so a reader familiar with one service can find their way around the
|
|
// other.
|
|
package handlers
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
)
|
|
|
|
// Route paths frozen by `gamemaster/api/internal-openapi.yaml`. The
|
|
// values match the operation IDs asserted in
|
|
// `gamemaster/contract_openapi_test.go`; renaming any of them is a
|
|
// contract change.
|
|
const (
|
|
registerRuntimePath = "/api/v1/internal/games/{game_id}/register-runtime"
|
|
banishRacePath = "/api/v1/internal/games/{game_id}/race/{race_name}/banish"
|
|
invalidateMembershipsPath = "/api/v1/internal/games/{game_id}/memberships/invalidate"
|
|
gameLivenessPath = "/api/v1/internal/games/{game_id}/liveness"
|
|
listRuntimesPath = "/api/v1/internal/runtimes"
|
|
getRuntimePath = "/api/v1/internal/runtimes/{game_id}"
|
|
forceNextTurnPath = "/api/v1/internal/runtimes/{game_id}/force-next-turn"
|
|
stopRuntimePath = "/api/v1/internal/runtimes/{game_id}/stop"
|
|
patchRuntimePath = "/api/v1/internal/runtimes/{game_id}/patch"
|
|
listEngineVersionsPath = "/api/v1/internal/engine-versions"
|
|
createEngineVersionPath = "/api/v1/internal/engine-versions"
|
|
engineVersionItemPath = "/api/v1/internal/engine-versions/{version}"
|
|
resolveEngineVersionImageRefPath = "/api/v1/internal/engine-versions/{version}/image-ref"
|
|
executeCommandsPath = "/api/v1/internal/games/{game_id}/commands"
|
|
putOrdersPath = "/api/v1/internal/games/{game_id}/orders"
|
|
getReportPath = "/api/v1/internal/games/{game_id}/reports/{turn}"
|
|
)
|
|
|
|
// Dependencies bundles the collaborators required to serve the
|
|
// gateway-, Lobby-, and Admin-facing internal REST surface. Any port
|
|
// may be nil; in that case the routes that depend on it return
|
|
// `500 internal_error` with the message «service is not wired». This
|
|
// mirrors the rtmanager handlers' guard so partially-wired listener
|
|
// tests do not crash on routes they do not exercise.
|
|
type Dependencies struct {
|
|
// Logger receives structured per-handler logs. nil falls back to
|
|
// slog.Default.
|
|
Logger *slog.Logger
|
|
|
|
// RuntimeRecords backs the read-only list/get runtime endpoints.
|
|
// Reads do not produce operation_log rows, mirroring
|
|
// `rtmanager/docs/services.md` §18.
|
|
RuntimeRecords RuntimeRecordsReader
|
|
|
|
// RegisterRuntime is the orchestrator for the
|
|
// `internalRegisterRuntime` operation.
|
|
RegisterRuntime RegisterRuntimeService
|
|
|
|
// ForceNextTurn drives the synchronous force-next-turn flow.
|
|
ForceNextTurn ForceNextTurnService
|
|
|
|
// StopRuntime drives the admin stop flow.
|
|
StopRuntime StopRuntimeService
|
|
|
|
// PatchRuntime drives the admin patch flow.
|
|
PatchRuntime PatchRuntimeService
|
|
|
|
// BanishRace drives the engine race-banish flow.
|
|
BanishRace BanishRaceService
|
|
|
|
// InvalidateMemberships purges the in-process membership cache for a
|
|
// game id; backed by `service/membership.Cache.Invalidate`.
|
|
InvalidateMemberships MembershipInvalidator
|
|
|
|
// GameLiveness returns the current runtime status without
|
|
// contacting the engine.
|
|
GameLiveness LivenessService
|
|
|
|
// EngineVersions exposes the multi-method engine-version registry
|
|
// service (List/Get/ResolveImageRef/Create/Update/Deprecate).
|
|
EngineVersions EngineVersionService
|
|
|
|
// CommandExecute forwards a player command batch to the engine.
|
|
CommandExecute CommandExecuteService
|
|
|
|
// PutOrders forwards a player order batch to the engine.
|
|
PutOrders OrderPutService
|
|
|
|
// GetReport reads a per-player turn report from the engine.
|
|
GetReport ReportGetService
|
|
}
|
|
|
|
// Register attaches every internal REST route to mux. The function is
|
|
// idempotent against the listener-level probes (`/healthz`,
|
|
// `/readyz`); the probe routes are owned by the listener and remain
|
|
// disjoint from the paths registered here.
|
|
func Register(mux *http.ServeMux, deps Dependencies) {
|
|
mux.HandleFunc(http.MethodPost+" "+registerRuntimePath, newRegisterRuntimeHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+getRuntimePath, newGetRuntimeHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+listRuntimesPath, newListRuntimesHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+forceNextTurnPath, newForceNextTurnHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+stopRuntimePath, newStopRuntimeHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+patchRuntimePath, newPatchRuntimeHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+banishRacePath, newBanishRaceHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+invalidateMembershipsPath, newInvalidateMembershipsHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+gameLivenessPath, newGameLivenessHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+listEngineVersionsPath, newListEngineVersionsHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+createEngineVersionPath, newCreateEngineVersionHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+engineVersionItemPath, newGetEngineVersionHandler(deps))
|
|
mux.HandleFunc(http.MethodPatch+" "+engineVersionItemPath, newUpdateEngineVersionHandler(deps))
|
|
mux.HandleFunc(http.MethodDelete+" "+engineVersionItemPath, newDeprecateEngineVersionHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+resolveEngineVersionImageRefPath, newResolveEngineVersionImageRefHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+executeCommandsPath, newExecuteCommandsHandler(deps))
|
|
mux.HandleFunc(http.MethodPost+" "+putOrdersPath, newPutOrdersHandler(deps))
|
|
mux.HandleFunc(http.MethodGet+" "+getReportPath, newGetReportHandler(deps))
|
|
}
|