feat: game lobby service

This commit is contained in:
Ilia Denisov
2026-04-25 23:20:55 +02:00
committed by GitHub
parent 32dc29359a
commit 48b0056b49
336 changed files with 57074 additions and 1418 deletions
+52 -10
View File
@@ -267,10 +267,11 @@ func (support commandSupport) loadActiveLimits(
// ApplySanctionService executes the explicit trusted sanction-apply command.
type ApplySanctionService struct {
support commandSupport
logger *slog.Logger
telemetry *telemetry.Runtime
publisher ports.SanctionChangedPublisher
support commandSupport
logger *slog.Logger
telemetry *telemetry.Runtime
publisher ports.SanctionChangedPublisher
lifecyclePublisher ports.UserLifecyclePublisher
}
// NewApplySanctionService constructs one sanction-apply use case.
@@ -282,11 +283,13 @@ func NewApplySanctionService(
clock ports.Clock,
idGenerator ports.IDGenerator,
) (*ApplySanctionService, error) {
return NewApplySanctionServiceWithObservability(accounts, sanctions, limits, lifecycle, clock, idGenerator, nil, nil, nil)
return NewApplySanctionServiceWithObservability(accounts, sanctions, limits, lifecycle, clock, idGenerator, nil, nil, nil, nil)
}
// NewApplySanctionServiceWithObservability constructs one sanction-apply use
// case with optional observability hooks.
// case with optional observability hooks. `lifecyclePublisher` is consulted
// when the newly applied sanction is `SanctionCodePermanentBlock`: one
// `user.lifecycle.permanent_blocked` event is emitted after the commit.
func NewApplySanctionServiceWithObservability(
accounts ports.UserAccountStore,
sanctions ports.SanctionStore,
@@ -297,6 +300,7 @@ func NewApplySanctionServiceWithObservability(
logger *slog.Logger,
telemetryRuntime *telemetry.Runtime,
publisher ports.SanctionChangedPublisher,
lifecyclePublisher ports.UserLifecyclePublisher,
) (*ApplySanctionService, error) {
support, err := newCommandSupport(accounts, sanctions, limits, lifecycle, clock, idGenerator)
if err != nil {
@@ -304,10 +308,11 @@ func NewApplySanctionServiceWithObservability(
}
return &ApplySanctionService{
support: support,
logger: logger,
telemetry: telemetryRuntime,
publisher: publisher,
support: support,
logger: logger,
telemetry: telemetryRuntime,
publisher: publisher,
lifecyclePublisher: lifecyclePublisher,
}, nil
}
@@ -389,6 +394,9 @@ func (service *ApplySanctionService) Execute(ctx context.Context, input ApplySan
ActiveSanctions: sanctionViews(active),
}
publishSanctionChanged(ctx, service.publisher, service.telemetry, service.logger, "apply_sanction", ports.SanctionChangedOperationApplied, record)
if record.SanctionCode == policy.SanctionCodePermanentBlock {
publishUserLifecyclePermanentBlocked(ctx, service.lifecyclePublisher, service.telemetry, service.logger, record)
}
return result, nil
}
@@ -1177,6 +1185,40 @@ func publishSanctionChanged(
}
}
func publishUserLifecyclePermanentBlocked(
ctx context.Context,
publisher ports.UserLifecyclePublisher,
telemetryRuntime *telemetry.Runtime,
logger *slog.Logger,
record policy.SanctionRecord,
) {
if publisher == nil {
return
}
event := ports.UserLifecycleEvent{
EventType: ports.UserLifecyclePermanentBlockedEventType,
UserID: record.UserID,
OccurredAt: record.AppliedAt.UTC(),
Source: adminInternalAPISource,
Actor: record.Actor,
ReasonCode: record.ReasonCode,
}
if err := publisher.PublishUserLifecycleEvent(ctx, event); err != nil {
if telemetryRuntime != nil {
telemetryRuntime.RecordEventPublicationFailure(ctx, string(ports.UserLifecyclePermanentBlockedEventType))
}
shared.LogEventPublicationFailure(logger, ctx, string(ports.UserLifecyclePermanentBlockedEventType), err,
"use_case", "apply_sanction",
"user_id", record.UserID.String(),
"source", adminInternalAPISource.String(),
"reason_code", record.ReasonCode.String(),
"actor_type", record.Actor.Type.String(),
"actor_id", record.Actor.ID.String(),
)
}
}
func publishLimitChanged(
ctx context.Context,
publisher ports.LimitChangedPublisher,