Add participant creation functionality to event API, including backend service and database integration. Update frontend to support participant registration and enhance UI for displaying registered players.
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"mixmaker/backend/internal/domain"
|
||||
@@ -18,6 +19,7 @@ type Store interface {
|
||||
DeleteSession(context.Context, string) error
|
||||
UpdatePlayer(context.Context, domain.Player) (domain.Player, error)
|
||||
ListPlayers(context.Context) ([]domain.Player, error)
|
||||
CreateParticipant(context.Context, domain.Player, domain.RSVP) (domain.Player, domain.RSVP, error)
|
||||
CreateEvent(context.Context, domain.Event) (domain.Event, error)
|
||||
GetEvent(context.Context, string) (domain.Event, error)
|
||||
UpdateEvent(context.Context, domain.Event) (domain.Event, error)
|
||||
@@ -174,6 +176,47 @@ func (s *Service) SetRSVP(ctx context.Context, actor domain.Account, actorPlayer
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (s *Service) CreateParticipant(ctx context.Context, actor domain.Account, eventID, displayName string, ratings domain.Ratings, status domain.RSVPStatus) (domain.Player, domain.RSVP, error) {
|
||||
if !actor.IsAdmin() {
|
||||
return domain.Player{}, domain.RSVP{}, domain.ErrForbidden
|
||||
}
|
||||
displayName = strings.TrimSpace(displayName)
|
||||
if displayName == "" {
|
||||
return domain.Player{}, domain.RSVP{}, fmt.Errorf("%w: display name is required", domain.ErrInvalid)
|
||||
}
|
||||
if err := ratings.Validate(); err != nil {
|
||||
return domain.Player{}, domain.RSVP{}, err
|
||||
}
|
||||
if _, err := s.Store.GetEvent(ctx, eventID); err != nil {
|
||||
return domain.Player{}, domain.RSVP{}, err
|
||||
}
|
||||
now := s.Now()
|
||||
player := domain.Player{
|
||||
ID: NewID(),
|
||||
DisplayName: displayName,
|
||||
Ratings: ratings,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
rsvp := domain.RSVP{
|
||||
EventID: eventID,
|
||||
PlayerID: player.ID,
|
||||
ActorAccountID: actor.ID,
|
||||
Status: status,
|
||||
Source: domain.SourceAdmin,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
if err := rsvp.Validate(); err != nil {
|
||||
return domain.Player{}, domain.RSVP{}, err
|
||||
}
|
||||
player, rsvp, err := s.Store.CreateParticipant(ctx, player, rsvp)
|
||||
if err == nil {
|
||||
_ = s.Store.AppendAudit(ctx, actor.ID, "participant.created", eventID, map[string]any{"player": player, "rsvp": rsvp})
|
||||
s.Bus.Publish("event:"+eventID, rsvp)
|
||||
}
|
||||
return player, rsvp, err
|
||||
}
|
||||
|
||||
func (s *Service) Balance(ctx context.Context, actor domain.Account, eventID string) ([]domain.BalanceCandidate, error) {
|
||||
if !actor.IsAdmin() {
|
||||
return nil, domain.ErrForbidden
|
||||
|
||||
Reference in New Issue
Block a user