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
+7 -82
View File
@@ -3,7 +3,6 @@ package ports
import (
"context"
"fmt"
"time"
"galaxy/user/internal/domain/account"
"galaxy/user/internal/domain/common"
@@ -14,9 +13,6 @@ import (
type CreateAccountInput struct {
// Account stores the durable user-account state.
Account account.UserAccount
// Reservation stores the canonical race-name reservation linked to Account.
Reservation account.RaceNameReservation
}
// Validate reports whether CreateAccountInput is structurally complete.
@@ -24,61 +20,6 @@ func (input CreateAccountInput) Validate() error {
if err := input.Account.Validate(); err != nil {
return fmt.Errorf("create account input account: %w", err)
}
if err := input.Reservation.Validate(); err != nil {
return fmt.Errorf("create account input reservation: %w", err)
}
if input.Account.UserID != input.Reservation.UserID {
return fmt.Errorf("create account input reservation user id must match account user id")
}
if input.Account.RaceName != input.Reservation.RaceName {
return fmt.Errorf("create account input reservation race name must match account race name")
}
return nil
}
// RenameRaceNameInput stores the atomic state required to replace one stored
// race name and its canonical reservation.
type RenameRaceNameInput struct {
// UserID identifies the account that must be updated.
UserID common.UserID
// CurrentCanonicalKey stores the currently owned canonical reservation key.
CurrentCanonicalKey account.RaceNameCanonicalKey
// NewRaceName stores the replacement exact stored race name.
NewRaceName common.RaceName
// NewReservation stores the replacement canonical reservation.
NewReservation account.RaceNameReservation
// UpdatedAt stores the account mutation timestamp.
UpdatedAt time.Time
}
// Validate reports whether RenameRaceNameInput is structurally complete.
func (input RenameRaceNameInput) Validate() error {
if err := input.UserID.Validate(); err != nil {
return fmt.Errorf("rename race name input user id: %w", err)
}
if err := input.CurrentCanonicalKey.Validate(); err != nil {
return fmt.Errorf("rename race name input current canonical key: %w", err)
}
if err := input.NewRaceName.Validate(); err != nil {
return fmt.Errorf("rename race name input race name: %w", err)
}
if err := input.NewReservation.Validate(); err != nil {
return fmt.Errorf("rename race name input reservation: %w", err)
}
if err := common.ValidateTimestamp("rename race name input updated at", input.UpdatedAt); err != nil {
return err
}
if input.NewReservation.UserID != input.UserID {
return fmt.Errorf("rename race name input reservation user id must match user id")
}
if input.NewReservation.RaceName != input.NewRaceName {
return fmt.Errorf("rename race name input reservation race name must match new race name")
}
return nil
}
@@ -87,7 +28,7 @@ func (input RenameRaceNameInput) Validate() error {
// exact lookup mappings.
type UserAccountStore interface {
// Create stores one new account record. Implementations must wrap
// ErrConflict when the user id, e-mail, or exact race-name lookup already
// ErrConflict when the user id, e-mail, or exact user-name lookup already
// exists.
Create(ctx context.Context, input CreateAccountInput) error
@@ -98,33 +39,17 @@ type UserAccountStore interface {
// address.
GetByEmail(ctx context.Context, email common.Email) (account.UserAccount, error)
// GetByRaceName returns the stored account identified by the exact stored
// race name.
GetByRaceName(ctx context.Context, raceName common.RaceName) (account.UserAccount, error)
// GetByUserName returns the stored account identified by the exact stored
// user name.
GetByUserName(ctx context.Context, userName common.UserName) (account.UserAccount, error)
// ExistsByUserID reports whether userID currently identifies a stored
// account.
ExistsByUserID(ctx context.Context, userID common.UserID) (bool, error)
// RenameRaceName replaces the stored race name of userID and swaps the
// exact race-name lookup atomically. Implementations must wrap ErrConflict
// when newRaceName is already owned by another account.
RenameRaceName(ctx context.Context, input RenameRaceNameInput) error
// Update replaces the stored account state for record.UserID.
//
// Implementations must wrap ErrConflict when the replacement record
// attempts to mutate `user_name` or `email`.
Update(ctx context.Context, record account.UserAccount) error
}
// RaceNameReservationStore persists source-of-truth race-name reservations.
type RaceNameReservationStore interface {
// Create stores one new race-name reservation keyed by its canonical
// uniqueness key. Implementations must wrap ErrConflict when the canonical
// key is already reserved.
Create(ctx context.Context, record account.RaceNameReservation) error
// GetByCanonicalKey returns the stored reservation identified by key.
GetByCanonicalKey(ctx context.Context, key account.RaceNameCanonicalKey) (account.RaceNameReservation, error)
// DeleteByCanonicalKey removes the reservation identified by key.
DeleteByCanonicalKey(ctx context.Context, key account.RaceNameCanonicalKey) error
}