feat: persist participant-scoped proposal recovery

This commit is contained in:
Josh Creek
2026-09-01 07:50:11 +01:00
parent 1eb6e8f9f4
commit 30b4560bd5
7 changed files with 217 additions and 20 deletions
+31 -18
View File
@@ -42,6 +42,9 @@ type SteamLoginProvider interface {
type SessionIssuer interface {
Issue(context.Context, string, time.Duration, time.Time) (domain.Session, string, error)
}
type ProposalBackend interface {
Get(context.Context, string, string, time.Time) (domain.Proposal, error)
}
type AssignmentView struct {
MatchID string `json:"match_id"`
@@ -57,24 +60,25 @@ type AssignmentView struct {
type AssignmentProvider func(context.Context, string, string, time.Time) (AssignmentView, error)
type Service struct {
Sessions *domain.SessionStore
SessionBackend SessionBackend
SessionIssuer SessionIssuer
SteamLogin SteamLoginProvider
Queue *domain.Queue
Candidate CandidateProvider
CandidateV2 CandidateProviderV2
QueueBackend QueueBackend
Probe ProbeProvider
Assignment AssignmentProvider
Now func() time.Time
Proposals map[string]*domain.Proposal
RankedProfiles map[string]domain.RankedProfile
TierPolicy domain.TierPolicy
RateLimiter *RateLimiter
proposalMu sync.Mutex
eventsMu sync.Mutex
events *eventHub
Sessions *domain.SessionStore
SessionBackend SessionBackend
SessionIssuer SessionIssuer
SteamLogin SteamLoginProvider
Queue *domain.Queue
Candidate CandidateProvider
CandidateV2 CandidateProviderV2
QueueBackend QueueBackend
Probe ProbeProvider
Assignment AssignmentProvider
Now func() time.Time
Proposals map[string]*domain.Proposal
ProposalBackend ProposalBackend
RankedProfiles map[string]domain.RankedProfile
TierPolicy domain.TierPolicy
RateLimiter *RateLimiter
proposalMu sync.Mutex
eventsMu sync.Mutex
events *eventHub
}
func (s *Service) Handler() http.Handler {
@@ -413,6 +417,15 @@ func (s *Service) proposalMutation(w http.ResponseWriter, r *http.Request) {
s.proposalMu.Lock()
defer s.proposalMu.Unlock()
proposal, exists := s.Proposals[parts[0]]
if s.ProposalBackend != nil {
proposalValue, providerErr := s.ProposalBackend.Get(r.Context(), playerID, parts[0], s.now())
if providerErr != nil {
writeError(w, http.StatusNotFound, "not_found")
return
}
proposal = &proposalValue
exists = true
}
if !exists || proposal == nil || !proposal.HasParticipant(playerID) {
writeError(w, http.StatusNotFound, "not_found")
return