Files
galaxy-game/authsession/internal/domain/sessionlimit/model.go
T
2026-04-08 16:23:07 +02:00

90 lines
2.6 KiB
Go

// Package sessionlimit defines the domain decision shape used for active
// device-session limit evaluation.
package sessionlimit
import (
"errors"
"fmt"
)
// Kind identifies the coarse outcome of evaluating the active-session limit.
type Kind string
const (
// KindDisabled reports that no configured limit is currently active.
KindDisabled Kind = "disabled"
// KindAllowed reports that creating the next session is allowed.
KindAllowed Kind = "allowed"
// KindExceeded reports that creating the next session would exceed the
// configured limit.
KindExceeded Kind = "exceeded"
)
// IsKnown reports whether Kind is one of the session-limit outcomes supported
// by the current domain model.
func (k Kind) IsKnown() bool {
switch k {
case KindDisabled, KindAllowed, KindExceeded:
return true
default:
return false
}
}
// Decision stores the result of evaluating one possible next session creation.
type Decision struct {
// Kind reports the coarse decision outcome.
Kind Kind
// ConfiguredLimit stores the active configured limit when one exists.
ConfiguredLimit *int
// ActiveSessionCount stores the current active-session count before create.
ActiveSessionCount int
// NextSessionCount stores the count that would exist after creating the next
// session.
NextSessionCount int
}
// Validate reports whether Decision satisfies the Stage-2 structural
// invariants.
func (d Decision) Validate() error {
if !d.Kind.IsKnown() {
return fmt.Errorf("session-limit decision kind %q is unsupported", d.Kind)
}
if d.ActiveSessionCount < 0 {
return errors.New("session-limit active session count must not be negative")
}
if d.NextSessionCount < 0 {
return errors.New("session-limit next session count must not be negative")
}
if d.NextSessionCount != d.ActiveSessionCount+1 {
return errors.New("session-limit next session count must equal active session count plus one")
}
switch d.Kind {
case KindDisabled:
if d.ConfiguredLimit != nil {
return errors.New("disabled session-limit decision must not contain configured limit")
}
case KindAllowed, KindExceeded:
if d.ConfiguredLimit == nil {
return errors.New("limited session-limit decision must contain configured limit")
}
if *d.ConfiguredLimit <= 0 {
return errors.New("session-limit configured limit must be positive")
}
if d.Kind == KindAllowed && d.NextSessionCount > *d.ConfiguredLimit {
return errors.New("allowed session-limit decision must not exceed configured limit")
}
if d.Kind == KindExceeded && d.NextSessionCount <= *d.ConfiguredLimit {
return errors.New("exceeded session-limit decision must be above configured limit")
}
}
return nil
}