// Package evaluationguardstub provides an in-memory // ports.EvaluationGuardStore used by service-level capability evaluation // tests. Production code never wires this stub. package evaluationguardstub import ( "context" "errors" "fmt" "sync" "galaxy/lobby/internal/domain/common" "galaxy/lobby/internal/ports" ) // Store is a concurrency-safe in-memory implementation of // ports.EvaluationGuardStore. type Store struct { mu sync.Mutex marks map[common.GameID]struct{} } // NewStore constructs one empty Store ready for use. func NewStore() *Store { return &Store{marks: make(map[common.GameID]struct{})} } // IsEvaluated reports whether gameID is already marked. func (store *Store) IsEvaluated(ctx context.Context, gameID common.GameID) (bool, error) { if store == nil { return false, errors.New("is evaluated: nil store") } if ctx == nil { return false, errors.New("is evaluated: nil context") } if err := gameID.Validate(); err != nil { return false, fmt.Errorf("is evaluated: %w", err) } store.mu.Lock() defer store.mu.Unlock() _, ok := store.marks[gameID] return ok, nil } // MarkEvaluated records gameID as evaluated. Calling MarkEvaluated twice // for the same gameID is safe; the second call leaves the marker // untouched. func (store *Store) MarkEvaluated(ctx context.Context, gameID common.GameID) error { if store == nil { return errors.New("mark evaluated: nil store") } if ctx == nil { return errors.New("mark evaluated: nil context") } if err := gameID.Validate(); err != nil { return fmt.Errorf("mark evaluated: %w", err) } store.mu.Lock() defer store.mu.Unlock() store.marks[gameID] = struct{}{} return nil } // Compile-time interface assertion. var _ ports.EvaluationGuardStore = (*Store)(nil)