feat: game lobby service
This commit is contained in:
@@ -30,6 +30,14 @@ const (
|
||||
// SanctionCodeProfileUpdateBlock denies self-service profile/settings
|
||||
// mutations.
|
||||
SanctionCodeProfileUpdateBlock SanctionCode = "profile_update_block"
|
||||
|
||||
// SanctionCodePermanentBlock marks the account as permanently disabled.
|
||||
// It is a terminal sanction: every `can_*` eligibility marker collapses to
|
||||
// false while it is active, self-service reads and writes are rejected
|
||||
// with 409 conflict, and Game Lobby performs Race Name Directory cascade
|
||||
// release when it observes the corresponding `user:lifecycle_events`
|
||||
// event.
|
||||
SanctionCodePermanentBlock SanctionCode = "permanent_block"
|
||||
)
|
||||
|
||||
// IsKnown reports whether SanctionCode belongs to the frozen v1 catalog.
|
||||
@@ -39,7 +47,8 @@ func (code SanctionCode) IsKnown() bool {
|
||||
SanctionCodePrivateGameCreateBlock,
|
||||
SanctionCodePrivateGameManageBlock,
|
||||
SanctionCodeGameJoinBlock,
|
||||
SanctionCodeProfileUpdateBlock:
|
||||
SanctionCodeProfileUpdateBlock,
|
||||
SanctionCodePermanentBlock:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -63,6 +72,12 @@ const (
|
||||
// LimitCodeMaxActiveGameMemberships limits how many active public-game
|
||||
// memberships the user may hold at once.
|
||||
LimitCodeMaxActiveGameMemberships LimitCode = "max_active_game_memberships"
|
||||
|
||||
// LimitCodeMaxRegisteredRaceNames overrides the tariff default quota for
|
||||
// permanent race-name registrations in the Game Lobby Race Name Directory.
|
||||
// The value `0` denotes an unlimited quota and is the canonical marker used
|
||||
// by the `paid_lifetime` tariff default.
|
||||
LimitCodeMaxRegisteredRaceNames LimitCode = "max_registered_race_names"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -91,7 +106,8 @@ func (code LimitCode) IsSupported() bool {
|
||||
switch code {
|
||||
case LimitCodeMaxOwnedPrivateGames,
|
||||
LimitCodeMaxPendingPublicApplications,
|
||||
LimitCodeMaxActiveGameMemberships:
|
||||
LimitCodeMaxActiveGameMemberships,
|
||||
LimitCodeMaxRegisteredRaceNames:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -127,6 +127,50 @@ func TestActiveSanctionsAt(t *testing.T) {
|
||||
require.Equal(t, SanctionCodeProfileUpdateBlock, active[0].SanctionCode)
|
||||
}
|
||||
|
||||
func TestSanctionCodeCatalog(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.True(t, SanctionCodeLoginBlock.IsKnown())
|
||||
require.True(t, SanctionCodePrivateGameCreateBlock.IsKnown())
|
||||
require.True(t, SanctionCodePrivateGameManageBlock.IsKnown())
|
||||
require.True(t, SanctionCodeGameJoinBlock.IsKnown())
|
||||
require.True(t, SanctionCodeProfileUpdateBlock.IsKnown())
|
||||
require.True(t, SanctionCodePermanentBlock.IsKnown())
|
||||
require.False(t, SanctionCode("unknown_code").IsKnown())
|
||||
}
|
||||
|
||||
func TestActiveSanctionsAtPermanentBlockCoexistsWithOtherCodes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
now := time.Unix(1_775_240_000, 0).UTC()
|
||||
records := []SanctionRecord{
|
||||
{
|
||||
RecordID: SanctionRecordID("sanction-1"),
|
||||
UserID: common.UserID("user-123"),
|
||||
SanctionCode: SanctionCodePermanentBlock,
|
||||
Scope: common.Scope("platform"),
|
||||
ReasonCode: common.ReasonCode("terminal_policy_violation"),
|
||||
Actor: common.ActorRef{Type: common.ActorType("admin"), ID: common.ActorID("admin-1")},
|
||||
AppliedAt: now.Add(-time.Hour),
|
||||
},
|
||||
{
|
||||
RecordID: SanctionRecordID("sanction-2"),
|
||||
UserID: common.UserID("user-123"),
|
||||
SanctionCode: SanctionCodeLoginBlock,
|
||||
Scope: common.Scope("auth"),
|
||||
ReasonCode: common.ReasonCode("policy"),
|
||||
Actor: common.ActorRef{Type: common.ActorType("admin")},
|
||||
AppliedAt: now.Add(-2 * time.Hour),
|
||||
},
|
||||
}
|
||||
|
||||
active, err := ActiveSanctionsAt(records, now)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, active, 2)
|
||||
require.Equal(t, SanctionCodeLoginBlock, active[0].SanctionCode)
|
||||
require.Equal(t, SanctionCodePermanentBlock, active[1].SanctionCode)
|
||||
}
|
||||
|
||||
func TestActiveSanctionsAtDuplicateActiveCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user