Files
mixmaker/backend/internal/adapter/httpapi/workflow_handlers.go
lemintare ae19c03542
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / compose (push) Has been cancelled
Add Discord event announcement functionality to backend
This commit introduces a new Discord event announcer to the backend, allowing for event announcements via Discord. It includes the addition of new environment variables for Discord configuration in `.env.example` and `compose.yaml`. The `main.go` file has been updated to initialize the announcer, and a new `discord` package has been created, containing the announcer logic and tests. Additionally, the service layer has been modified to support bracket draft management, enhancing the overall event workflow. Integration tests have been updated to ensure proper functionality of the new features.
2026-07-19 11:21:11 +03:00

352 lines
11 KiB
Go

package httpapi
import (
"net/http"
"github.com/go-chi/chi/v5"
"mixmaker/backend/internal/domain"
)
func (s *Server) cancelEvent(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.CancelEvent(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) deleteEvent(w http.ResponseWriter, r *http.Request) {
err := s.service.DeleteEvent(r.Context(), who(r).account, chi.URLParam(r, "eventID"))
respond(w, nil, err, http.StatusNoContent)
}
func (s *Server) closeRegistration(w http.ResponseWriter, r *http.Request) {
var in struct {
RulesetID string `json:"rulesetId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.CloseRegistration(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.RulesetID, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) generateWorkflowBalance(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.GenerateBalance(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) getRoster(w http.ResponseWriter, r *http.Request) {
out, err := s.store.GetRoster(r.Context(), chi.URLParam(r, "eventID"))
respond(w, out, err, http.StatusOK)
}
func (s *Server) selectWorkflowBalance(w http.ResponseWriter, r *http.Request) {
var in struct {
Candidate domain.BalanceCandidate `json:"candidate"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.SelectWorkflowBalance(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.Candidate, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) swapRoster(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamAID string `json:"teamAId"`
PlayerAID string `json:"playerAId"`
TeamBID string `json:"teamBId"`
PlayerBID string `json:"playerBId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.SwapRoster(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.TeamAID, in.PlayerAID, in.TeamBID, in.PlayerBID, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) moveRosterPlayer(w http.ResponseWriter, r *http.Request) {
var in struct {
FromTeamID string `json:"fromTeamId"`
PlayerID string `json:"playerId"`
ToTeamID string `json:"toTeamId"`
Role domain.Role `json:"role"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.MoveRosterPlayer(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.FromTeamID, in.PlayerID, in.ToTeamID, in.Role, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) placeReservePlayer(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamID string `json:"teamId"`
ReservePlayerID string `json:"reservePlayerId"`
Role domain.Role `json:"role"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.PlaceReservePlayer(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.TeamID, in.ReservePlayerID, in.Role, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) removeRosterPlayer(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamID string `json:"teamId"`
PlayerID string `json:"playerId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.RemoveRosterPlayer(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.TeamID, in.PlayerID, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) substituteRoster(w http.ResponseWriter, r *http.Request) {
s.handleSubstitute(w, r, false)
}
func (s *Server) emergencySubstitute(w http.ResponseWriter, r *http.Request) {
s.handleSubstitute(w, r, true)
}
func (s *Server) handleSubstitute(w http.ResponseWriter, r *http.Request, emergency bool) {
var in struct {
TeamID string `json:"teamId"`
OutgoingPlayerID string `json:"outgoingPlayerId"`
ReservePlayerID string `json:"reservePlayerId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.SubstituteRoster(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.TeamID, in.OutgoingPlayerID, in.ReservePlayerID, in.ExpectedVersion, emergency)
respond(w, out, err, http.StatusOK)
}
func (s *Server) setRosterCaptain(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamID string `json:"teamId"`
PlayerID string `json:"playerId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.SetRosterCaptain(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.TeamID, in.PlayerID, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) confirmRosters(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
ExpectedRosterVersion int `json:"expectedRosterVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.ConfirmRosters(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion, in.ExpectedRosterVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) getBracketDraft(w http.ResponseWriter, r *http.Request) {
out, err := s.store.GetBracketDraft(r.Context(), chi.URLParam(r, "eventID"))
respond(w, out, err, http.StatusOK)
}
func (s *Server) initializeBracket(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.InitializeBracket(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusCreated)
}
func (s *Server) updateBracket(w http.ResponseWriter, r *http.Request) {
var in struct {
Matches []domain.BracketMatch `json:"matches"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.UpdateBracket(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.Matches, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) resetBracket(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.ResetBracket(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) confirmBracket(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.ConfirmBracket(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) revertWorkflowStage(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.RevertWorkflowStage(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) startScrim(w http.ResponseWriter, r *http.Request) {
var in struct {
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
out, err := s.service.StartScrim(r.Context(), who(r).account, chi.URLParam(r, "eventID"), in.ExpectedVersion)
respond(w, out, err, http.StatusCreated)
}
func (s *Server) tossSeriesCoin(w http.ResponseWriter, r *http.Request) {
var in struct {
Seed string `json:"seed"`
ActingTeamID string `json:"actingTeamId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
series, err := s.store.GetSeries(r.Context(), chi.URLParam(r, "id"))
if err == nil {
err = s.authorizeTeam(r, series.EventID, in.ActingTeamID)
}
if err != nil {
writeError(w, err)
return
}
id := who(r)
out, err := s.service.TossSeriesCoin(r.Context(), id.account, id.player, series.ID, in.Seed, in.ActingTeamID, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) banSeriesMap(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamID string `json:"teamId"`
Map string `json:"map"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
series, err := s.store.GetSeries(r.Context(), chi.URLParam(r, "id"))
if err == nil {
err = s.authorizeTeam(r, series.EventID, in.TeamID)
}
if err != nil {
writeError(w, err)
return
}
id := who(r)
out, err := s.service.BanSeriesMap(r.Context(), id.account, id.player, series.ID, in.TeamID, in.Map, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) pickSeriesMap(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamID string `json:"teamId"`
Map string `json:"map"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
series, err := s.store.GetSeries(r.Context(), chi.URLParam(r, "id"))
if err == nil {
err = s.authorizeTeam(r, series.EventID, in.TeamID)
}
if err != nil {
writeError(w, err)
return
}
id := who(r)
out, err := s.service.PickSeriesMap(r.Context(), id.account, id.player, series.ID, in.TeamID, in.Map, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) banSeriesHero(w http.ResponseWriter, r *http.Request) {
var in struct {
TeamID string `json:"teamId"`
Hero string `json:"hero"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
series, err := s.store.GetSeries(r.Context(), chi.URLParam(r, "id"))
if err == nil {
err = s.authorizeTeam(r, series.EventID, in.TeamID)
}
if err != nil {
writeError(w, err)
return
}
id := who(r)
out, err := s.service.BanSeriesHero(r.Context(), id.account, id.player, series.ID, in.TeamID, in.Hero, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}
func (s *Server) recordSeriesResult(w http.ResponseWriter, r *http.Request) {
var in struct {
Outcome domain.MapOutcome `json:"outcome"`
ActingTeamID string `json:"actingTeamId"`
ExpectedVersion int `json:"expectedVersion"`
}
if !decode(w, r, &in) {
return
}
series, err := s.store.GetSeries(r.Context(), chi.URLParam(r, "id"))
if err == nil {
err = s.authorizeTeam(r, series.EventID, in.ActingTeamID)
}
if err != nil {
writeError(w, err)
return
}
id := who(r)
out, err := s.service.RecordSeriesResult(r.Context(), id.account, id.player, series.ID, in.ActingTeamID, in.Outcome, in.ExpectedVersion)
respond(w, out, err, http.StatusOK)
}