feat: game lobby service
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
package ports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrUserServiceUnavailable is returned by UserService implementations when
|
||||
// the upstream User Service is unreachable, returns an unexpected status,
|
||||
// or violates the contract in a way that callers must surface as
|
||||
// service_unavailable. Service-layer code wraps it with the
|
||||
// shared.ErrServiceUnavailable sentinel before bubbling up to transport.
|
||||
var ErrUserServiceUnavailable = errors.New("user service unavailable")
|
||||
|
||||
// Eligibility stores the lobby-relevant subset of the User Service
|
||||
// eligibility snapshot. only consumes Exists and CanJoinGame; the
|
||||
// remaining fields are pre-plumbed for (race name registration)
|
||||
// so that adding consumers later does not churn the port surface.
|
||||
type Eligibility struct {
|
||||
// Exists reports whether userID currently identifies a stored user.
|
||||
// false maps to subject_not_found at the service layer.
|
||||
Exists bool
|
||||
|
||||
// CanLogin reports whether the user may currently log in.
|
||||
CanLogin bool
|
||||
|
||||
// CanCreatePrivateGame reports whether the user may currently create
|
||||
// a private game.
|
||||
CanCreatePrivateGame bool
|
||||
|
||||
// CanManagePrivateGame reports whether the user may currently manage
|
||||
// a private game they own.
|
||||
CanManagePrivateGame bool
|
||||
|
||||
// CanJoinGame reports whether the user may currently join a game
|
||||
// (submit application or redeem invite). false surfaces as
|
||||
// eligibility_denied for the
|
||||
CanJoinGame bool
|
||||
|
||||
// CanUpdateProfile reports whether the user may currently update
|
||||
// self-service profile and settings fields.
|
||||
CanUpdateProfile bool
|
||||
|
||||
// PermanentBlocked reports whether the user carries an active
|
||||
// permanent_block sanction. rejects the
|
||||
// `lobby.race_name.register` call with `shared.ErrForbidden` ⇒
|
||||
// HTTP `403 forbidden`; the dedicated `race_name_permanent_blocked`
|
||||
// envelope code is reserved for the cascade flows. Stage
|
||||
// 11 currently surfaces it indirectly through CanJoinGame=false
|
||||
// (collapses every can_* marker to false on
|
||||
// permanent_block).
|
||||
PermanentBlocked bool
|
||||
|
||||
// MaxRegisteredRaceNames stores the snapshot value for the
|
||||
// max_registered_race_names limit. A value of 0 denotes unlimited
|
||||
// per the lifetime tariff. The race-name registration service
|
||||
// enforces the quota; this port only carries the value through.
|
||||
MaxRegisteredRaceNames int
|
||||
}
|
||||
|
||||
// UserService is the synchronous lobby-facing User Service eligibility
|
||||
// reader. The application flow consumes it via a single
|
||||
// GetEligibility call before accepting an applicant.
|
||||
type UserService interface {
|
||||
// GetEligibility returns the lobby-relevant eligibility snapshot for
|
||||
// userID. It returns Eligibility{Exists:false} for unknown users
|
||||
// without an error so callers can distinguish missing users from
|
||||
// transport failures. Transport, decode, and unexpected status code
|
||||
// failures wrap ErrUserServiceUnavailable.
|
||||
GetEligibility(ctx context.Context, userID string) (Eligibility, error)
|
||||
}
|
||||
Reference in New Issue
Block a user