102 lines
3.3 KiB
Go
102 lines
3.3 KiB
Go
// Package account defines the logical user-account entities owned directly by
|
|
// User Service.
|
|
package account
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"galaxy/user/internal/domain/common"
|
|
)
|
|
|
|
// UserAccount stores the current editable account state of one regular user.
|
|
type UserAccount struct {
|
|
// UserID identifies the durable regular-user account.
|
|
UserID common.UserID
|
|
|
|
// Email stores the normalized login/contact address of the account.
|
|
Email common.Email
|
|
|
|
// UserName stores the immutable auto-generated `player-<suffix>` handle.
|
|
UserName common.UserName
|
|
|
|
// DisplayName stores the optional mutable free-text user-facing label.
|
|
DisplayName common.DisplayName
|
|
|
|
// PreferredLanguage stores the current declared language tag.
|
|
PreferredLanguage common.LanguageTag
|
|
|
|
// TimeZone stores the current declared time-zone name.
|
|
TimeZone common.TimeZoneName
|
|
|
|
// DeclaredCountry stores the latest effective declared-country value. The
|
|
// zero value means the geo workflow has not synchronized any country yet.
|
|
DeclaredCountry common.CountryCode
|
|
|
|
// CreatedAt stores the account creation timestamp.
|
|
CreatedAt time.Time
|
|
|
|
// UpdatedAt stores the last account mutation timestamp.
|
|
UpdatedAt time.Time
|
|
|
|
// DeletedAt stores the soft-delete timestamp set by the `DeleteUser`
|
|
// command. A nil value means the account is live. A non-nil value marks
|
|
// the record as soft-deleted: external auth, self-service, admin-read,
|
|
// and lobby-eligibility operations must reject subsequent access with
|
|
// `subject_not_found`.
|
|
DeletedAt *time.Time
|
|
}
|
|
|
|
// IsDeleted reports whether the account has been soft-deleted through the
|
|
// `DeleteUser` command.
|
|
func (record UserAccount) IsDeleted() bool {
|
|
return record.DeletedAt != nil
|
|
}
|
|
|
|
// Validate reports whether UserAccount satisfies the Stage 21 structural
|
|
// invariants, including the Stage 22 soft-delete rules.
|
|
func (record UserAccount) Validate() error {
|
|
if err := record.UserID.Validate(); err != nil {
|
|
return fmt.Errorf("user account user id: %w", err)
|
|
}
|
|
if err := record.Email.Validate(); err != nil {
|
|
return fmt.Errorf("user account email: %w", err)
|
|
}
|
|
if err := record.UserName.Validate(); err != nil {
|
|
return fmt.Errorf("user account user name: %w", err)
|
|
}
|
|
if err := record.DisplayName.Validate(); err != nil {
|
|
return fmt.Errorf("user account display name: %w", err)
|
|
}
|
|
if err := record.PreferredLanguage.Validate(); err != nil {
|
|
return fmt.Errorf("user account preferred language: %w", err)
|
|
}
|
|
if err := record.TimeZone.Validate(); err != nil {
|
|
return fmt.Errorf("user account time zone: %w", err)
|
|
}
|
|
if !record.DeclaredCountry.IsZero() {
|
|
if err := record.DeclaredCountry.Validate(); err != nil {
|
|
return fmt.Errorf("user account declared country: %w", err)
|
|
}
|
|
}
|
|
if err := common.ValidateTimestamp("user account created at", record.CreatedAt); err != nil {
|
|
return err
|
|
}
|
|
if err := common.ValidateTimestamp("user account updated at", record.UpdatedAt); err != nil {
|
|
return err
|
|
}
|
|
if record.UpdatedAt.Before(record.CreatedAt) {
|
|
return fmt.Errorf("user account updated at must not be before created at")
|
|
}
|
|
if record.DeletedAt != nil {
|
|
if err := common.ValidateTimestamp("user account deleted at", *record.DeletedAt); err != nil {
|
|
return err
|
|
}
|
|
if record.DeletedAt.Before(record.CreatedAt) {
|
|
return fmt.Errorf("user account deleted at must not be before created at")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|