From d1757ea49c09314bb6f6c450d8b5f6111dd9c23c Mon Sep 17 00:00:00 2001 From: Alex Dyakonov Date: Fri, 4 Jul 2025 10:47:50 +0300 Subject: [PATCH 1/7] added migrations --- server-go/migrations/04072025_add_endtime_notnull.down.sql | 2 ++ server-go/migrations/04072025_add_endtime_notnull.up.sql | 5 +++++ 2 files changed, 7 insertions(+) create mode 100644 server-go/migrations/04072025_add_endtime_notnull.down.sql create mode 100644 server-go/migrations/04072025_add_endtime_notnull.up.sql diff --git a/server-go/migrations/04072025_add_endtime_notnull.down.sql b/server-go/migrations/04072025_add_endtime_notnull.down.sql new file mode 100644 index 00000000..44c24c22 --- /dev/null +++ b/server-go/migrations/04072025_add_endtime_notnull.down.sql @@ -0,0 +1,2 @@ + -- Откат: сделать поле end_time NULLABLE +ALTER TABLE tournaments ALTER COLUMN end_time DROP NOT NULL; diff --git a/server-go/migrations/04072025_add_endtime_notnull.up.sql b/server-go/migrations/04072025_add_endtime_notnull.up.sql new file mode 100644 index 00000000..c1c7918b --- /dev/null +++ b/server-go/migrations/04072025_add_endtime_notnull.up.sql @@ -0,0 +1,5 @@ + -- 1. Для существующих турниров, где end_time IS NULL, выставить start_time + interval '1 hour' +UPDATE tournaments SET end_time = start_time + interval '1 hour' WHERE end_time IS NULL; + +-- 2. Сделать поле end_time NOT NULL +ALTER TABLE tournaments ALTER COLUMN end_time SET NOT NULL; From ad360d485b50fe2ad363d360e165e8a2ee829d75 Mon Sep 17 00:00:00 2001 From: AlexDyakonov Date: Fri, 4 Jul 2025 11:01:29 +0300 Subject: [PATCH 2/7] added courts endpoint --- server-go/docs/docs.go | 58 +++++++++++++++++++ server-go/docs/swagger.json | 58 +++++++++++++++++++ server-go/docs/swagger.yaml | 38 ++++++++++++ .../pkg/gateways/rest/courts/handlers.go | 49 ++++++++++++++++ server-go/pkg/gateways/rest/courts/setup.go | 24 ++++++++ server-go/pkg/gateways/rest/router.go | 2 + 6 files changed, 229 insertions(+) create mode 100644 server-go/pkg/gateways/rest/courts/handlers.go create mode 100644 server-go/pkg/gateways/rest/courts/setup.go diff --git a/server-go/docs/docs.go b/server-go/docs/docs.go index 03a48465..029e061e 100644 --- a/server-go/docs/docs.go +++ b/server-go/docs/docs.go @@ -1399,6 +1399,64 @@ const docTemplate = `{ } } }, + "/courts": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Returns a list of all courts. Only available for authenticated Telegram admins.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "courts" + ], + "summary": "Get all courts", + "responses": { + "200": { + "description": "List of courts", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.Club" + } + } + }, + "401": { + "description": "User not authorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "403": { + "description": "Admin rights required", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal server error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, "/images/upload/avatar": { "post": { "security": [ diff --git a/server-go/docs/swagger.json b/server-go/docs/swagger.json index 9ab1e4c1..aba6641f 100644 --- a/server-go/docs/swagger.json +++ b/server-go/docs/swagger.json @@ -1391,6 +1391,64 @@ } } }, + "/courts": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Returns a list of all courts. Only available for authenticated Telegram admins.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "courts" + ], + "summary": "Get all courts", + "responses": { + "200": { + "description": "List of courts", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.Club" + } + } + }, + "401": { + "description": "User not authorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "403": { + "description": "Admin rights required", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal server error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, "/images/upload/avatar": { "post": { "security": [ diff --git a/server-go/docs/swagger.yaml b/server-go/docs/swagger.yaml index 58e28a98..7249c7b5 100644 --- a/server-go/docs/swagger.yaml +++ b/server-go/docs/swagger.yaml @@ -1471,6 +1471,44 @@ paths: summary: YooKassa webhook for payment notifications tags: - webhook + /courts: + get: + consumes: + - application/json + description: Returns a list of all courts. Only available for authenticated + Telegram admins. + produces: + - application/json + responses: + "200": + description: List of courts + schema: + items: + $ref: '#/definitions/domain.Club' + type: array + "401": + description: User not authorized + schema: + additionalProperties: + type: string + type: object + "403": + description: Admin rights required + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal server error + schema: + additionalProperties: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: Get all courts + tags: + - courts /images/upload/avatar: post: consumes: diff --git a/server-go/pkg/gateways/rest/courts/handlers.go b/server-go/pkg/gateways/rest/courts/handlers.go new file mode 100644 index 00000000..dd29986a --- /dev/null +++ b/server-go/pkg/gateways/rest/courts/handlers.go @@ -0,0 +1,49 @@ +package courts + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/shampsdev/go-telegram-template/pkg/domain" + "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/ginerr" + "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/middlewares" + "github.com/shampsdev/go-telegram-template/pkg/usecase" +) + +type Handler struct { + clubCase *usecase.Club +} + +func NewHandler(clubCase *usecase.Club) *Handler { + return &Handler{ + clubCase: clubCase, + } +} + +// GetCourts godoc +// @Summary Get all courts +// @Description Returns a list of all courts. Only available for authenticated Telegram admins. +// @Tags courts +// @Accept json +// @Produce json +// @Success 200 {array} domain.Club "List of courts" +// @Failure 401 {object} map[string]string "User not authorized" +// @Failure 403 {object} map[string]string "Admin rights required" +// @Failure 500 {object} map[string]string "Internal server error" +// @Security ApiKeyAuth +// @Router /courts [get] +func (h *Handler) GetCourts(c *gin.Context) { + user := middlewares.MustGetUser(c) + + filter := &domain.FilterClub{} + courts, err := h.clubCase.GetAll(usecase.NewContext(c, user), filter) + if ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to get courts") { + return + } + + if courts == nil { + courts = []*domain.Club{} + } + + c.JSON(http.StatusOK, courts) +} \ No newline at end of file diff --git a/server-go/pkg/gateways/rest/courts/setup.go b/server-go/pkg/gateways/rest/courts/setup.go new file mode 100644 index 00000000..d5af0d34 --- /dev/null +++ b/server-go/pkg/gateways/rest/courts/setup.go @@ -0,0 +1,24 @@ +package courts + +import ( + "github.com/gin-gonic/gin" + "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/middlewares" + "github.com/shampsdev/go-telegram-template/pkg/usecase" +) + +func Setup(r *gin.RouterGroup, useCases usecase.Cases) { + handler := NewHandler(useCases.Club) + + courtsGroup := r.Group("/courts") + { + // Применяем аутентификацию пользователя + courtsGroup.Use(middlewares.ExtractUserTGData()) + courtsGroup.Use(middlewares.AuthUser(useCases.User)) + + // Проверяем админские права через Telegram + courtsGroup.Use(middlewares.RequireTelegramAdmin(useCases.AdminUser)) + + // GET /courts - получить все корты (только для админов) + courtsGroup.GET("", handler.GetCourts) + } +} \ No newline at end of file diff --git a/server-go/pkg/gateways/rest/router.go b/server-go/pkg/gateways/rest/router.go index cec339b2..31281f29 100644 --- a/server-go/pkg/gateways/rest/router.go +++ b/server-go/pkg/gateways/rest/router.go @@ -12,6 +12,7 @@ import ( "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/admin_loyalties" "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/admin_registrations" "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/admin_users" + "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/courts" "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/image" "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/loyalty" "github.com/shampsdev/go-telegram-template/pkg/gateways/rest/middlewares" @@ -34,6 +35,7 @@ func setupRouter(ctx context.Context, r *gin.Engine, useCases usecase.Cases, cfg v1.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) user.Setup(v1, useCases) + courts.Setup(v1, useCases) image.Setup(v1, useCases) tournament.Setup(v1, useCases) loyalty.Setup(v1, useCases) From bcd427a8c5a2c2a96b7e135723d7b6bf12f26af5 Mon Sep 17 00:00:00 2001 From: AlexDyakonov Date: Fri, 4 Jul 2025 11:16:26 +0300 Subject: [PATCH 3/7] enhanced tournament filtering by adding additional user fields --- server-go/pkg/repo/pg/tournament.go | 94 +++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 6 deletions(-) diff --git a/server-go/pkg/repo/pg/tournament.go b/server-go/pkg/repo/pg/tournament.go index d687a522..ef01fa29 100644 --- a/server-go/pkg/repo/pg/tournament.go +++ b/server-go/pkg/repo/pg/tournament.go @@ -29,7 +29,8 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna `"t"."id"`, `"t"."name"`, `"t"."start_time"`, `"t"."end_time"`, `"t"."price"`, `"t"."rank_min"`, `"t"."rank_max"`, `"t"."max_users"`, `"t"."description"`, `"t"."tournament_type"`, `"c"."id"`, `"c"."name"`, `"c"."address"`, - `"u"."id"`, `"u"."telegram_id"`, `"u"."first_name"`, `"u"."last_name"`, `"u"."avatar"`, + `"u"."id"`, `"u"."telegram_id"`, `"u"."telegram_username"`, `"u"."first_name"`, `"u"."last_name"`, `"u"."avatar"`, + `"u"."bio"`, `"u"."rank"`, `"u"."city"`, `"u"."birth_date"`, `"u"."playing_position"`, `"u"."padel_profiles"`, `"u"."is_registered"`, `COUNT(CASE WHEN "r"."status" IN ('PENDING', 'ACTIVE') THEN 1 END) AS active_registrations`, ). From(`"tournaments" AS t`). @@ -82,8 +83,16 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna var clubID, clubName, clubAddress string var userID string var userTelegramID int64 + var userTelegramUsername pgtype.Text var userFirstName, userSecondName string var userAvatar pgtype.Text + var userBio pgtype.Text + var userRank float64 + var userCity pgtype.Text + var userBirthDate pgtype.Text + var userPlayingPosition pgtype.Text + var userPadelProfiles pgtype.Text + var userIsRegistered pgtype.Bool var activeRegistrations int err := rows.Scan( @@ -102,9 +111,17 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna &clubAddress, &userID, &userTelegramID, + &userTelegramUsername, &userFirstName, &userSecondName, &userAvatar, + &userBio, + &userRank, + &userCity, + &userBirthDate, + &userPlayingPosition, + &userPadelProfiles, + &userIsRegistered, &activeRegistrations, ) if err != nil { @@ -124,18 +141,42 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna Address: clubAddress, } - tournament.Organizator = domain.User{ + organizator := domain.User{ ID: userID, UserTGData: domain.UserTGData{ TelegramID: userTelegramID, FirstName: userFirstName, LastName: userSecondName, }, + Rank: userRank, + } + + if userTelegramUsername.Valid { + organizator.TelegramUsername = userTelegramUsername.String } if userAvatar.Valid { - tournament.Organizator.Avatar = userAvatar.String + organizator.Avatar = userAvatar.String + } + if userBio.Valid { + organizator.Bio = userBio.String + } + if userCity.Valid { + organizator.City = userCity.String + } + if userBirthDate.Valid { + organizator.BirthDate = userBirthDate.String + } + if userPlayingPosition.Valid { + organizator.PlayingPosition = domain.PlayingPosition(userPlayingPosition.String) + } + if userPadelProfiles.Valid { + organizator.PadelProfiles = userPadelProfiles.String + } + if userIsRegistered.Valid { + organizator.IsRegistered = userIsRegistered.Bool } + tournament.Organizator = organizator tournaments = append(tournaments, &tournament) } @@ -147,7 +188,8 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri `"t"."id"`, `"t"."name"`, `"t"."start_time"`, `"t"."end_time"`, `"t"."price"`, `"t"."rank_min"`, `"t"."rank_max"`, `"t"."max_users"`, `"t"."description"`, `"t"."tournament_type"`, `"c"."id"`, `"c"."name"`, `"c"."address"`, - `"org"."id"`, `"org"."telegram_id"`, `"org"."first_name"`, `"org"."last_name"`, `"org"."avatar"`, + `"org"."id"`, `"org"."telegram_id"`, `"org"."telegram_username"`, `"org"."first_name"`, `"org"."last_name"`, `"org"."avatar"`, + `"org"."bio"`, `"org"."rank"`, `"org"."city"`, `"org"."birth_date"`, `"org"."playing_position"`, `"org"."padel_profiles"`, `"org"."is_registered"`, ). From(`"tournaments" AS t`). Join(`"registrations" AS reg ON "t"."id" = "reg"."tournament_id"`). @@ -180,8 +222,16 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri var clubID, clubName, clubAddress string var orgID string var orgTelegramID int64 + var orgTelegramUsername pgtype.Text var orgFirstName, orgLastName string var orgAvatar pgtype.Text + var orgBio pgtype.Text + var orgRank float64 + var orgCity pgtype.Text + var orgBirthDate pgtype.Text + var orgPlayingPosition pgtype.Text + var orgPadelProfiles pgtype.Text + var orgIsRegistered pgtype.Bool err := rows.Scan( &tournament.ID, @@ -199,9 +249,17 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri &clubAddress, &orgID, &orgTelegramID, + &orgTelegramUsername, &orgFirstName, &orgLastName, &orgAvatar, + &orgBio, + &orgRank, + &orgCity, + &orgBirthDate, + &orgPlayingPosition, + &orgPadelProfiles, + &orgIsRegistered, ) if err != nil { return nil, fmt.Errorf("failed to scan row: %w", err) @@ -220,18 +278,42 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri Address: clubAddress, } - tournament.Organizator = domain.User{ + organizator := domain.User{ ID: orgID, UserTGData: domain.UserTGData{ TelegramID: orgTelegramID, FirstName: orgFirstName, LastName: orgLastName, }, + Rank: orgRank, + } + + if orgTelegramUsername.Valid { + organizator.TelegramUsername = orgTelegramUsername.String } if orgAvatar.Valid { - tournament.Organizator.Avatar = orgAvatar.String + organizator.Avatar = orgAvatar.String + } + if orgBio.Valid { + organizator.Bio = orgBio.String + } + if orgCity.Valid { + organizator.City = orgCity.String + } + if orgBirthDate.Valid { + organizator.BirthDate = orgBirthDate.String + } + if orgPlayingPosition.Valid { + organizator.PlayingPosition = domain.PlayingPosition(orgPlayingPosition.String) + } + if orgPadelProfiles.Valid { + organizator.PadelProfiles = orgPadelProfiles.String + } + if orgIsRegistered.Valid { + organizator.IsRegistered = orgIsRegistered.Bool } + tournament.Organizator = organizator tournaments = append(tournaments, &tournament) } From f01d1d0e810089e56623472986ba0552512eb586 Mon Sep 17 00:00:00 2001 From: AlexDyakonov Date: Fri, 4 Jul 2025 11:36:29 +0300 Subject: [PATCH 4/7] removed price field from tournament documentation and adjusted related data types for user birth dates in tournament filtering --- server-go/docs/docs.go | 1 - server-go/docs/swagger.json | 1 - server-go/docs/swagger.yaml | 1 - server-go/pkg/domain/tournament.go | 2 +- server-go/pkg/repo/pg/tournament.go | 8 ++++---- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/server-go/docs/docs.go b/server-go/docs/docs.go index 029e061e..c4640881 100644 --- a/server-go/docs/docs.go +++ b/server-go/docs/docs.go @@ -3021,7 +3021,6 @@ const docTemplate = `{ "maxUsers", "name", "organizatorId", - "price", "rankMax", "rankMin", "startTime", diff --git a/server-go/docs/swagger.json b/server-go/docs/swagger.json index aba6641f..9deb97e0 100644 --- a/server-go/docs/swagger.json +++ b/server-go/docs/swagger.json @@ -3013,7 +3013,6 @@ "maxUsers", "name", "organizatorId", - "price", "rankMax", "rankMin", "startTime", diff --git a/server-go/docs/swagger.yaml b/server-go/docs/swagger.yaml index 7249c7b5..7ba926c0 100644 --- a/server-go/docs/swagger.yaml +++ b/server-go/docs/swagger.yaml @@ -185,7 +185,6 @@ definitions: - maxUsers - name - organizatorId - - price - rankMax - rankMin - startTime diff --git a/server-go/pkg/domain/tournament.go b/server-go/pkg/domain/tournament.go index 8103f0f7..f032a872 100644 --- a/server-go/pkg/domain/tournament.go +++ b/server-go/pkg/domain/tournament.go @@ -22,7 +22,7 @@ type CreateTournament struct { Name string `json:"name" binding:"required"` StartTime time.Time `json:"startTime" binding:"required"` EndTime time.Time `json:"endTime"` - Price int `json:"price" binding:"required"` + Price int `json:"price"` RankMin float64 `json:"rankMin" binding:"required"` RankMax float64 `json:"rankMax" binding:"required"` MaxUsers int `json:"maxUsers" binding:"required"` diff --git a/server-go/pkg/repo/pg/tournament.go b/server-go/pkg/repo/pg/tournament.go index ef01fa29..e46c4271 100644 --- a/server-go/pkg/repo/pg/tournament.go +++ b/server-go/pkg/repo/pg/tournament.go @@ -89,7 +89,7 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna var userBio pgtype.Text var userRank float64 var userCity pgtype.Text - var userBirthDate pgtype.Text + var userBirthDate pgtype.Date var userPlayingPosition pgtype.Text var userPadelProfiles pgtype.Text var userIsRegistered pgtype.Bool @@ -164,7 +164,7 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna organizator.City = userCity.String } if userBirthDate.Valid { - organizator.BirthDate = userBirthDate.String + organizator.BirthDate = userBirthDate.Time.Format("2006-01-02") } if userPlayingPosition.Valid { organizator.PlayingPosition = domain.PlayingPosition(userPlayingPosition.String) @@ -228,7 +228,7 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri var orgBio pgtype.Text var orgRank float64 var orgCity pgtype.Text - var orgBirthDate pgtype.Text + var orgBirthDate pgtype.Date var orgPlayingPosition pgtype.Text var orgPadelProfiles pgtype.Text var orgIsRegistered pgtype.Bool @@ -301,7 +301,7 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri organizator.City = orgCity.String } if orgBirthDate.Valid { - organizator.BirthDate = orgBirthDate.String + organizator.BirthDate = orgBirthDate.Time.Format("2006-01-02") } if orgPlayingPosition.Valid { organizator.PlayingPosition = domain.PlayingPosition(orgPlayingPosition.String) From 9561973b4e2910aacfdcceb53727fb62a825a344 Mon Sep 17 00:00:00 2001 From: AlexDyakonov Date: Fri, 4 Jul 2025 12:07:44 +0300 Subject: [PATCH 5/7] fixed userrank --- server-go/pkg/repo/pg/admin_user.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server-go/pkg/repo/pg/admin_user.go b/server-go/pkg/repo/pg/admin_user.go index 2d8f787b..94561b68 100644 --- a/server-go/pkg/repo/pg/admin_user.go +++ b/server-go/pkg/repo/pg/admin_user.go @@ -88,7 +88,8 @@ func (r *AdminUserRepo) Filter(ctx context.Context, filter *domain.FilterAdminUs // User fields var userID, userTelegramUsername, userFirstName, userLastName, userAvatar, userBio, userCity, userPlayingPosition, userPadelProfiles pgtype.Text - var userTelegramID, userRank pgtype.Int8 + var userTelegramID pgtype.Int8 + var userRank pgtype.Float8 var userIsRegistered pgtype.Bool var userBirthDate pgtype.Date @@ -171,7 +172,7 @@ func (r *AdminUserRepo) Filter(ctx context.Context, filter *domain.FilterAdminUs user.Bio = userBio.String } if userRank.Valid { - user.Rank = float64(userRank.Int64) + user.Rank = userRank.Float64 } if userCity.Valid { user.City = userCity.String From e54f25669a68dda20f84dd6e1383d8aea779428e Mon Sep 17 00:00:00 2001 From: AlexDyakonov Date: Fri, 4 Jul 2025 12:45:07 +0300 Subject: [PATCH 6/7] Backend rename: club -> court --- server-go/docs/docs.go | 88 +++++++++++++++---- server-go/docs/swagger.json | 88 +++++++++++++++---- server-go/docs/swagger.yaml | 68 ++++++++++---- .../04072025_rename_clubs_to_courts.down.sql | 14 +++ .../04072025_rename_clubs_to_courts.up.sql | 14 +++ server-go/pkg/domain/{club.go => court.go} | 10 +-- server-go/pkg/domain/registration.go | 2 +- server-go/pkg/domain/tournament.go | 6 +- .../gateways/rest/admin_courts/handlers.go | 81 ++++++++++++----- .../pkg/gateways/rest/admin_courts/setup.go | 11 +-- .../pkg/gateways/rest/courts/handlers.go | 14 +-- server-go/pkg/gateways/rest/courts/setup.go | 2 +- server-go/pkg/repo/pg/{club.go => court.go} | 74 ++++++++-------- server-go/pkg/repo/pg/pg.go | 2 +- server-go/pkg/repo/pg/registration.go | 47 +++++----- server-go/pkg/repo/pg/tournament.go | 44 +++++----- server-go/pkg/repo/repo.go | 8 +- server-go/pkg/usecase/club.go | 50 ----------- server-go/pkg/usecase/court.go | 50 +++++++++++ server-go/pkg/usecase/registration.go | 6 +- server-go/pkg/usecase/usecase.go | 8 +- 21 files changed, 447 insertions(+), 240 deletions(-) create mode 100644 server-go/migrations/04072025_rename_clubs_to_courts.down.sql create mode 100644 server-go/migrations/04072025_rename_clubs_to_courts.up.sql rename server-go/pkg/domain/{club.go => court.go} (79%) rename server-go/pkg/repo/pg/{club.go => court.go} (54%) delete mode 100644 server-go/pkg/usecase/club.go create mode 100644 server-go/pkg/usecase/court.go diff --git a/server-go/docs/docs.go b/server-go/docs/docs.go index c4640881..c942f572 100644 --- a/server-go/docs/docs.go +++ b/server-go/docs/docs.go @@ -227,7 +227,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } } }, @@ -269,7 +269,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/domain.CreateClub" + "$ref": "#/definitions/domain.CreateCourt" } } ], @@ -277,7 +277,7 @@ const docTemplate = `{ "201": { "description": "Created", "schema": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } }, "400": { @@ -308,6 +308,62 @@ const docTemplate = `{ } }, "/admin/courts/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Get court by ID. Available for any admin.", + "produces": [ + "application/json" + ], + "tags": [ + "admin-courts" + ], + "summary": "Get court (Admin)", + "parameters": [ + { + "type": "string", + "description": "Court ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Court" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + }, "delete": { "security": [ { @@ -401,7 +457,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/domain.PatchClub" + "$ref": "#/definitions/domain.PatchCourt" } } ], @@ -409,7 +465,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } }, "400": { @@ -1423,7 +1479,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } } }, @@ -2935,7 +2991,7 @@ const docTemplate = `{ } } }, - "domain.Club": { + "domain.Court": { "type": "object", "properties": { "address": { @@ -2982,7 +3038,7 @@ const docTemplate = `{ } } }, - "domain.CreateClub": { + "domain.CreateCourt": { "type": "object", "required": [ "address", @@ -3017,7 +3073,7 @@ const docTemplate = `{ "domain.CreateTournament": { "type": "object", "required": [ - "clubId", + "courtId", "maxUsers", "name", "organizatorId", @@ -3027,7 +3083,7 @@ const docTemplate = `{ "tournamentType" ], "properties": { - "clubId": { + "courtId": { "type": "string" }, "description": { @@ -3192,7 +3248,7 @@ const docTemplate = `{ } } }, - "domain.PatchClub": { + "domain.PatchCourt": { "type": "object", "properties": { "address": { @@ -3223,7 +3279,7 @@ const docTemplate = `{ "domain.PatchTournament": { "type": "object", "properties": { - "clubId": { + "courtId": { "type": "string" }, "description": { @@ -3455,8 +3511,8 @@ const docTemplate = `{ "domain.Tournament": { "type": "object", "properties": { - "club": { - "$ref": "#/definitions/domain.Club" + "court": { + "$ref": "#/definitions/domain.Court" }, "description": { "type": "string" @@ -3502,8 +3558,8 @@ const docTemplate = `{ "domain.TournamentForRegistration": { "type": "object", "properties": { - "club": { - "$ref": "#/definitions/domain.Club" + "court": { + "$ref": "#/definitions/domain.Court" }, "description": { "type": "string" diff --git a/server-go/docs/swagger.json b/server-go/docs/swagger.json index 9deb97e0..1b40cddc 100644 --- a/server-go/docs/swagger.json +++ b/server-go/docs/swagger.json @@ -219,7 +219,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } } }, @@ -261,7 +261,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/domain.CreateClub" + "$ref": "#/definitions/domain.CreateCourt" } } ], @@ -269,7 +269,7 @@ "201": { "description": "Created", "schema": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } }, "400": { @@ -300,6 +300,62 @@ } }, "/admin/courts/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Get court by ID. Available for any admin.", + "produces": [ + "application/json" + ], + "tags": [ + "admin-courts" + ], + "summary": "Get court (Admin)", + "parameters": [ + { + "type": "string", + "description": "Court ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Court" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + }, "delete": { "security": [ { @@ -393,7 +449,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/domain.PatchClub" + "$ref": "#/definitions/domain.PatchCourt" } } ], @@ -401,7 +457,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } }, "400": { @@ -1415,7 +1471,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/domain.Club" + "$ref": "#/definitions/domain.Court" } } }, @@ -2927,7 +2983,7 @@ } } }, - "domain.Club": { + "domain.Court": { "type": "object", "properties": { "address": { @@ -2974,7 +3030,7 @@ } } }, - "domain.CreateClub": { + "domain.CreateCourt": { "type": "object", "required": [ "address", @@ -3009,7 +3065,7 @@ "domain.CreateTournament": { "type": "object", "required": [ - "clubId", + "courtId", "maxUsers", "name", "organizatorId", @@ -3019,7 +3075,7 @@ "tournamentType" ], "properties": { - "clubId": { + "courtId": { "type": "string" }, "description": { @@ -3184,7 +3240,7 @@ } } }, - "domain.PatchClub": { + "domain.PatchCourt": { "type": "object", "properties": { "address": { @@ -3215,7 +3271,7 @@ "domain.PatchTournament": { "type": "object", "properties": { - "clubId": { + "courtId": { "type": "string" }, "description": { @@ -3447,8 +3503,8 @@ "domain.Tournament": { "type": "object", "properties": { - "club": { - "$ref": "#/definitions/domain.Club" + "court": { + "$ref": "#/definitions/domain.Court" }, "description": { "type": "string" @@ -3494,8 +3550,8 @@ "domain.TournamentForRegistration": { "type": "object", "properties": { - "club": { - "$ref": "#/definitions/domain.Club" + "court": { + "$ref": "#/definitions/domain.Court" }, "description": { "type": "string" diff --git a/server-go/docs/swagger.yaml b/server-go/docs/swagger.yaml index 7ba926c0..41a52648 100644 --- a/server-go/docs/swagger.yaml +++ b/server-go/docs/swagger.yaml @@ -103,7 +103,7 @@ definitions: username: type: string type: object - domain.Club: + domain.Court: properties: address: type: string @@ -135,7 +135,7 @@ definitions: - user_id - username type: object - domain.CreateClub: + domain.CreateCourt: properties: address: type: string @@ -158,7 +158,7 @@ definitions: type: object domain.CreateTournament: properties: - clubId: + courtId: type: string description: type: string @@ -181,7 +181,7 @@ definitions: tournamentType: type: string required: - - clubId + - courtId - maxUsers - name - organizatorId @@ -275,7 +275,7 @@ definitions: username: type: string type: object - domain.PatchClub: + domain.PatchCourt: properties: address: type: string @@ -295,7 +295,7 @@ definitions: type: object domain.PatchTournament: properties: - clubId: + courtId: type: string description: type: string @@ -453,8 +453,8 @@ definitions: type: object domain.Tournament: properties: - club: - $ref: '#/definitions/domain.Club' + court: + $ref: '#/definitions/domain.Court' description: type: string endTime: @@ -484,8 +484,8 @@ definitions: type: object domain.TournamentForRegistration: properties: - club: - $ref: '#/definitions/domain.Club' + court: + $ref: '#/definitions/domain.Court' description: type: string endTime: @@ -805,7 +805,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/domain.Club' + $ref: '#/definitions/domain.Court' type: array "401": description: Unauthorized @@ -830,14 +830,14 @@ paths: name: court required: true schema: - $ref: '#/definitions/domain.CreateClub' + $ref: '#/definitions/domain.CreateCourt' produces: - application/json responses: "201": description: Created schema: - $ref: '#/definitions/domain.Club' + $ref: '#/definitions/domain.Court' "400": description: Bad Request schema: @@ -900,6 +900,42 @@ paths: summary: Delete court (Admin) tags: - admin-courts + get: + description: Get court by ID. Available for any admin. + parameters: + - description: Court ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.Court' + "400": + description: Bad Request + schema: + $ref: '#/definitions/domain.ErrorResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/domain.ErrorResponse' + "404": + description: Not Found + schema: + $ref: '#/definitions/domain.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/domain.ErrorResponse' + security: + - BearerAuth: [] + summary: Get court (Admin) + tags: + - admin-courts patch: consumes: - application/json @@ -915,14 +951,14 @@ paths: name: court required: true schema: - $ref: '#/definitions/domain.PatchClub' + $ref: '#/definitions/domain.PatchCourt' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/domain.Club' + $ref: '#/definitions/domain.Court' "400": description: Bad Request schema: @@ -1483,7 +1519,7 @@ paths: description: List of courts schema: items: - $ref: '#/definitions/domain.Club' + $ref: '#/definitions/domain.Court' type: array "401": description: User not authorized diff --git a/server-go/migrations/04072025_rename_clubs_to_courts.down.sql b/server-go/migrations/04072025_rename_clubs_to_courts.down.sql new file mode 100644 index 00000000..b782ce68 --- /dev/null +++ b/server-go/migrations/04072025_rename_clubs_to_courts.down.sql @@ -0,0 +1,14 @@ +-- Откат переименования courts обратно в clubs +-- Этап 1: Переименовать индекс обратно +DROP INDEX IF EXISTS idx_tournaments_court_id; +CREATE INDEX idx_tournaments_club_id ON tournaments(court_id); + +-- Этап 2: Переименовать constraint обратно +ALTER TABLE tournaments DROP CONSTRAINT fk_tournaments_court_id; +ALTER TABLE tournaments ADD CONSTRAINT fk_tournaments_club_id FOREIGN KEY (court_id) REFERENCES courts(id); + +-- Этап 3: Переименовать колонку обратно +ALTER TABLE tournaments RENAME COLUMN court_id TO club_id; + +-- Этап 4: Переименовать таблицу обратно +ALTER TABLE courts RENAME TO clubs; \ No newline at end of file diff --git a/server-go/migrations/04072025_rename_clubs_to_courts.up.sql b/server-go/migrations/04072025_rename_clubs_to_courts.up.sql new file mode 100644 index 00000000..f5b309e6 --- /dev/null +++ b/server-go/migrations/04072025_rename_clubs_to_courts.up.sql @@ -0,0 +1,14 @@ +-- Переименование таблицы clubs в courts +-- Этап 1: Переименовать таблицу +ALTER TABLE clubs RENAME TO courts; + +-- Этап 2: Переименовать колонку в tournaments +ALTER TABLE tournaments RENAME COLUMN club_id TO court_id; + +-- Этап 3: Переименовать constraint +ALTER TABLE tournaments DROP CONSTRAINT fk_tournaments_club_id; +ALTER TABLE tournaments ADD CONSTRAINT fk_tournaments_court_id FOREIGN KEY (court_id) REFERENCES courts(id); + +-- Этап 4: Переименовать индекс +DROP INDEX IF EXISTS idx_tournaments_club_id; +CREATE INDEX idx_tournaments_court_id ON tournaments(court_id); \ No newline at end of file diff --git a/server-go/pkg/domain/club.go b/server-go/pkg/domain/court.go similarity index 79% rename from server-go/pkg/domain/club.go rename to server-go/pkg/domain/court.go index 0fd70619..4cd9507d 100644 --- a/server-go/pkg/domain/club.go +++ b/server-go/pkg/domain/court.go @@ -1,22 +1,22 @@ package domain -type Club struct { +type Court struct { ID string `json:"id"` Name string `json:"name"` Address string `json:"address"` } -type CreateClub struct { +type CreateCourt struct { Name string `json:"name" binding:"required"` Address string `json:"address" binding:"required"` } -type PatchClub struct { +type PatchCourt struct { Name *string `json:"name,omitempty"` Address *string `json:"address,omitempty"` } -type FilterClub struct { +type FilterCourt struct { ID *string `json:"id,omitempty"` Name *string `json:"name,omitempty"` -} +} \ No newline at end of file diff --git a/server-go/pkg/domain/registration.go b/server-go/pkg/domain/registration.go index 0960ba49..3f119349 100644 --- a/server-go/pkg/domain/registration.go +++ b/server-go/pkg/domain/registration.go @@ -53,7 +53,7 @@ type TournamentForRegistration struct { RankMax float64 `json:"rankMax"` MaxUsers int `json:"maxUsers"` Description string `json:"description"` - Club Club `json:"club"` + Court Court `json:"court"` TournamentType string `json:"tournamentType"` Organizator User `json:"organizator"` } diff --git a/server-go/pkg/domain/tournament.go b/server-go/pkg/domain/tournament.go index f032a872..1e154b99 100644 --- a/server-go/pkg/domain/tournament.go +++ b/server-go/pkg/domain/tournament.go @@ -12,7 +12,7 @@ type Tournament struct { RankMax float64 `json:"rankMax"` MaxUsers int `json:"maxUsers"` Description string `json:"description"` - Club Club `json:"club"` + Court Court `json:"court"` TournamentType string `json:"tournamentType"` Organizator User `json:"organizator"` Participants []*Registration `json:"participants"` @@ -27,7 +27,7 @@ type CreateTournament struct { RankMax float64 `json:"rankMax" binding:"required"` MaxUsers int `json:"maxUsers" binding:"required"` Description string `json:"description"` - ClubID string `json:"clubId" binding:"required"` + CourtID string `json:"courtId" binding:"required"` TournamentType string `json:"tournamentType" binding:"required"` OrganizatorID string `json:"organizatorId" binding:"required"` } @@ -41,7 +41,7 @@ type PatchTournament struct { RankMax *float64 `json:"rankMax,omitempty"` MaxUsers *int `json:"maxUsers,omitempty"` Description *string `json:"description,omitempty"` - ClubID *string `json:"clubId,omitempty"` + CourtID *string `json:"courtId,omitempty"` TournamentType *string `json:"tournamentType,omitempty"` } diff --git a/server-go/pkg/gateways/rest/admin_courts/handlers.go b/server-go/pkg/gateways/rest/admin_courts/handlers.go index 25cd5ad4..62a96cb6 100644 --- a/server-go/pkg/gateways/rest/admin_courts/handlers.go +++ b/server-go/pkg/gateways/rest/admin_courts/handlers.go @@ -11,34 +11,34 @@ import ( ) type Handler struct { - clubCase *usecase.Club + courtCase *usecase.Court } -func NewHandler(clubCase *usecase.Club) *Handler { +func NewHandler(courtCase *usecase.Court) *Handler { return &Handler{ - clubCase: clubCase, + courtCase: courtCase, } } -// GetAllCourts получает все корты для админов +// GetCourts получает все корты для админов // @Summary Get all courts (Admin) // @Description Get all courts. Available for any admin. // @Tags admin-courts // @Produce json // @Security BearerAuth -// @Success 200 {array} domain.Club +// @Success 200 {array} domain.Court // @Failure 401 {object} domain.ErrorResponse // @Failure 500 {object} domain.ErrorResponse // @Router /admin/courts [get] -func (h *Handler) GetAllCourts(c *gin.Context) { - filter := &domain.FilterClub{} - courts, err := h.clubCase.GetAll(usecase.NewContext(c, nil), filter) +func (h *Handler) GetCourts(c *gin.Context) { + filter := &domain.FilterCourt{} + courts, err := h.courtCase.GetAll(usecase.NewContext(c, nil), filter) if ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to get courts") { return } if courts == nil { - courts = []*domain.Club{} + courts = []*domain.Court{} } c.JSON(http.StatusOK, courts) @@ -51,27 +51,27 @@ func (h *Handler) GetAllCourts(c *gin.Context) { // @Accept json // @Produce json // @Security BearerAuth -// @Param court body domain.CreateClub true "Court data" -// @Success 201 {object} domain.Club +// @Param court body domain.CreateCourt true "Court data" +// @Success 201 {object} domain.Court // @Failure 400 {object} domain.ErrorResponse // @Failure 401 {object} domain.ErrorResponse // @Failure 403 {object} domain.ErrorResponse // @Failure 500 {object} domain.ErrorResponse // @Router /admin/courts [post] func (h *Handler) CreateCourt(c *gin.Context) { - var createData domain.CreateClub + var createData domain.CreateCourt if err := c.ShouldBindJSON(&createData); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - id, err := h.clubCase.Create(usecase.NewContext(c, nil), &createData) + id, err := h.courtCase.Create(usecase.NewContext(c, nil), &createData) if ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to create court") { return } // Возвращаем созданный корт - court, err := h.clubCase.GetByID(usecase.NewContext(c, nil), id) + court, err := h.courtCase.GetByID(usecase.NewContext(c, nil), id) if ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to get created court") { return } @@ -79,7 +79,40 @@ func (h *Handler) CreateCourt(c *gin.Context) { c.JSON(http.StatusCreated, court) } -// PatchCourt обновляет корт +// GetCourt получает корт по ID +// @Summary Get court (Admin) +// @Description Get court by ID. Available for any admin. +// @Tags admin-courts +// @Produce json +// @Security BearerAuth +// @Param id path string true "Court ID" +// @Success 200 {object} domain.Court +// @Failure 400 {object} domain.ErrorResponse +// @Failure 401 {object} domain.ErrorResponse +// @Failure 404 {object} domain.ErrorResponse +// @Failure 500 {object} domain.ErrorResponse +// @Router /admin/courts/{id} [get] +func (h *Handler) GetCourt(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "Court ID is required"}) + return + } + + court, err := h.courtCase.GetByID(usecase.NewContext(c, nil), id) + if err != nil { + if err.Error() == fmt.Sprintf("court with id %s not found", id) { + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + return + } + ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to get court") + return + } + + c.JSON(http.StatusOK, court) +} + +// UpdateCourt обновляет корт // @Summary Update court (Admin) // @Description Update court data. Available only for superuser. // @Tags admin-courts @@ -87,30 +120,30 @@ func (h *Handler) CreateCourt(c *gin.Context) { // @Produce json // @Security BearerAuth // @Param id path string true "Court ID" -// @Param court body domain.PatchClub true "Court update data" -// @Success 200 {object} domain.Club +// @Param court body domain.PatchCourt true "Court update data" +// @Success 200 {object} domain.Court // @Failure 400 {object} domain.ErrorResponse // @Failure 401 {object} domain.ErrorResponse // @Failure 403 {object} domain.ErrorResponse // @Failure 404 {object} domain.ErrorResponse // @Failure 500 {object} domain.ErrorResponse // @Router /admin/courts/{id} [patch] -func (h *Handler) PatchCourt(c *gin.Context) { +func (h *Handler) UpdateCourt(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Court ID is required"}) return } - var patchData domain.PatchClub + var patchData domain.PatchCourt if err := c.ShouldBindJSON(&patchData); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - err := h.clubCase.Update(usecase.NewContext(c, nil), id, &patchData) + err := h.courtCase.Update(usecase.NewContext(c, nil), id, &patchData) if err != nil { - if err.Error() == fmt.Sprintf("club with id %s not found", id) { + if err.Error() == fmt.Sprintf("court with id %s not found", id) { c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) return } @@ -119,7 +152,7 @@ func (h *Handler) PatchCourt(c *gin.Context) { } // Возвращаем обновленный корт - court, err := h.clubCase.GetByID(usecase.NewContext(c, nil), id) + court, err := h.courtCase.GetByID(usecase.NewContext(c, nil), id) if ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to get updated court") { return } @@ -148,9 +181,9 @@ func (h *Handler) DeleteCourt(c *gin.Context) { return } - err := h.clubCase.Delete(usecase.NewContext(c, nil), id) + err := h.courtCase.Delete(usecase.NewContext(c, nil), id) if err != nil { - if err.Error() == fmt.Sprintf("club with id %s not found", id) { + if err.Error() == fmt.Sprintf("court with id %s not found", id) { c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) return } diff --git a/server-go/pkg/gateways/rest/admin_courts/setup.go b/server-go/pkg/gateways/rest/admin_courts/setup.go index a83b42b7..5df17392 100644 --- a/server-go/pkg/gateways/rest/admin_courts/setup.go +++ b/server-go/pkg/gateways/rest/admin_courts/setup.go @@ -7,23 +7,20 @@ import ( ) func Setup(r *gin.RouterGroup, useCases usecase.Cases) { - handler := NewHandler(useCases.Club) + handler := NewHandler(useCases.Court) adminCourtsGroup := r.Group("/admin/courts") { adminCourtsGroup.Use(middlewares.RequireAdminJWT(useCases.AdminUser)) - // GET /admin/courts - получить все корты (любой админ) - adminCourtsGroup.GET("", handler.GetAllCourts) + adminCourtsGroup.GET("", handler.GetCourts) - // Эндпоинты для изменения данных требуют права суперпользователя superUserGroup := adminCourtsGroup.Group("") superUserGroup.Use(middlewares.RequireAdminSuperuser()) superUserGroup.POST("", handler.CreateCourt) - - superUserGroup.PATCH("/:id", handler.PatchCourt) - + superUserGroup.GET("/:id", handler.GetCourt) + superUserGroup.PATCH("/:id", handler.UpdateCourt) superUserGroup.DELETE("/:id", handler.DeleteCourt) } } \ No newline at end of file diff --git a/server-go/pkg/gateways/rest/courts/handlers.go b/server-go/pkg/gateways/rest/courts/handlers.go index dd29986a..58ebd69b 100644 --- a/server-go/pkg/gateways/rest/courts/handlers.go +++ b/server-go/pkg/gateways/rest/courts/handlers.go @@ -11,12 +11,12 @@ import ( ) type Handler struct { - clubCase *usecase.Club + courtCase *usecase.Court } -func NewHandler(clubCase *usecase.Club) *Handler { +func NewHandler(courtCase *usecase.Court) *Handler { return &Handler{ - clubCase: clubCase, + courtCase: courtCase, } } @@ -26,7 +26,7 @@ func NewHandler(clubCase *usecase.Club) *Handler { // @Tags courts // @Accept json // @Produce json -// @Success 200 {array} domain.Club "List of courts" +// @Success 200 {array} domain.Court "List of courts" // @Failure 401 {object} map[string]string "User not authorized" // @Failure 403 {object} map[string]string "Admin rights required" // @Failure 500 {object} map[string]string "Internal server error" @@ -35,14 +35,14 @@ func NewHandler(clubCase *usecase.Club) *Handler { func (h *Handler) GetCourts(c *gin.Context) { user := middlewares.MustGetUser(c) - filter := &domain.FilterClub{} - courts, err := h.clubCase.GetAll(usecase.NewContext(c, user), filter) + filter := &domain.FilterCourt{} + courts, err := h.courtCase.GetAll(usecase.NewContext(c, user), filter) if ginerr.AbortIfErr(c, err, http.StatusInternalServerError, "Failed to get courts") { return } if courts == nil { - courts = []*domain.Club{} + courts = []*domain.Court{} } c.JSON(http.StatusOK, courts) diff --git a/server-go/pkg/gateways/rest/courts/setup.go b/server-go/pkg/gateways/rest/courts/setup.go index d5af0d34..932ec6e1 100644 --- a/server-go/pkg/gateways/rest/courts/setup.go +++ b/server-go/pkg/gateways/rest/courts/setup.go @@ -7,7 +7,7 @@ import ( ) func Setup(r *gin.RouterGroup, useCases usecase.Cases) { - handler := NewHandler(useCases.Club) + handler := NewHandler(useCases.Court) courtsGroup := r.Group("/courts") { diff --git a/server-go/pkg/repo/pg/club.go b/server-go/pkg/repo/pg/court.go similarity index 54% rename from server-go/pkg/repo/pg/club.go rename to server-go/pkg/repo/pg/court.go index f6af5f4e..487fed11 100644 --- a/server-go/pkg/repo/pg/club.go +++ b/server-go/pkg/repo/pg/court.go @@ -11,22 +11,22 @@ import ( "github.com/shampsdev/go-telegram-template/pkg/domain" ) -type ClubRepo struct { +type CourtRepo struct { db *pgxpool.Pool psql sq.StatementBuilderType } -func NewClubRepo(db *pgxpool.Pool) *ClubRepo { - return &ClubRepo{ +func NewCourtRepo(db *pgxpool.Pool) *CourtRepo { + return &CourtRepo{ db: db, psql: sq.StatementBuilder.PlaceholderFormat(sq.Dollar), } } -func (r *ClubRepo) Create(ctx context.Context, club *domain.CreateClub) (string, error) { - s := r.psql.Insert(`"clubs"`). +func (r *CourtRepo) Create(ctx context.Context, court *domain.CreateCourt) (string, error) { + s := r.psql.Insert(`"courts"`). Columns("name", "address"). - Values(club.Name, club.Address). + Values(court.Name, court.Address). Suffix("RETURNING id") sql, args, err := s.ToSql() @@ -37,14 +37,14 @@ func (r *ClubRepo) Create(ctx context.Context, club *domain.CreateClub) (string, var id string err = r.db.QueryRow(ctx, sql, args...).Scan(&id) if err != nil { - return "", fmt.Errorf("failed to create club: %w", err) + return "", fmt.Errorf("failed to create court: %w", err) } return id, nil } -func (r *ClubRepo) Filter(ctx context.Context, filter *domain.FilterClub) ([]*domain.Club, error) { - s := r.psql.Select("id", "name", "address").From(`"clubs"`) +func (r *CourtRepo) Filter(ctx context.Context, filter *domain.FilterCourt) ([]*domain.Court, error) { + s := r.psql.Select("id", "name", "address").From(`"courts"`) if filter.ID != nil { s = s.Where(sq.Eq{"id": *filter.ID}) @@ -61,48 +61,48 @@ func (r *ClubRepo) Filter(ctx context.Context, filter *domain.FilterClub) ([]*do rows, err := r.db.Query(ctx, sql, args...) if errors.Is(err, pgx.ErrNoRows) { - return []*domain.Club{}, nil + return []*domain.Court{}, nil } if err != nil { return nil, fmt.Errorf("failed to execute SQL: %w", err) } defer rows.Close() - clubs := []*domain.Club{} + courts := []*domain.Court{} for rows.Next() { - var club domain.Club + var court domain.Court err := rows.Scan( - &club.ID, - &club.Name, - &club.Address, + &court.ID, + &court.Name, + &court.Address, ) if err != nil { return nil, fmt.Errorf("failed to scan row: %w", err) } - clubs = append(clubs, &club) + courts = append(courts, &court) } if err = rows.Err(); err != nil { return nil, fmt.Errorf("error iterating rows: %w", err) } - return clubs, nil + return courts, nil } -func (r *ClubRepo) Patch(ctx context.Context, id string, club *domain.PatchClub) error { - s := r.psql.Update(`"clubs"`).Where(sq.Eq{"id": id}) +func (r *CourtRepo) Patch(ctx context.Context, id string, court *domain.PatchCourt) error { + s := r.psql.Update(`"courts"`).Where(sq.Eq{"id": id}) hasUpdates := false - if club.Name != nil { - s = s.Set("name", *club.Name) + if court.Name != nil { + s = s.Set("name", *court.Name) hasUpdates = true } - if club.Address != nil { - s = s.Set("address", *club.Address) + if court.Address != nil { + s = s.Set("address", *court.Address) hasUpdates = true } @@ -117,18 +117,18 @@ func (r *ClubRepo) Patch(ctx context.Context, id string, club *domain.PatchClub) result, err := r.db.Exec(ctx, sql, args...) if err != nil { - return fmt.Errorf("failed to update club: %w", err) + return fmt.Errorf("failed to update court: %w", err) } if result.RowsAffected() == 0 { - return fmt.Errorf("club with id %s not found", id) + return fmt.Errorf("court with id %s not found", id) } return nil } -func (r *ClubRepo) Delete(ctx context.Context, id string) error { - s := r.psql.Delete(`"clubs"`).Where(sq.Eq{"id": id}) +func (r *CourtRepo) Delete(ctx context.Context, id string) error { + s := r.psql.Delete(`"courts"`).Where(sq.Eq{"id": id}) sql, args, err := s.ToSql() if err != nil { @@ -137,27 +137,27 @@ func (r *ClubRepo) Delete(ctx context.Context, id string) error { result, err := r.db.Exec(ctx, sql, args...) if err != nil { - return fmt.Errorf("failed to delete club: %w", err) + return fmt.Errorf("failed to delete court: %w", err) } if result.RowsAffected() == 0 { - return fmt.Errorf("club with id %s not found", id) + return fmt.Errorf("court with id %s not found", id) } return nil } -// GetByID получает клуб по ID (вспомогательный метод) -func (r *ClubRepo) GetByID(ctx context.Context, id string) (*domain.Club, error) { - filter := &domain.FilterClub{ID: &id} - clubs, err := r.Filter(ctx, filter) +// GetByID получает корт по ID (вспомогательный метод) +func (r *CourtRepo) GetByID(ctx context.Context, id string) (*domain.Court, error) { + filter := &domain.FilterCourt{ID: &id} + courts, err := r.Filter(ctx, filter) if err != nil { return nil, err } - if len(clubs) == 0 { - return nil, fmt.Errorf("club with id %s not found", id) + if len(courts) == 0 { + return nil, fmt.Errorf("court with id %s not found", id) } - return clubs[0], nil -} + return courts[0], nil +} \ No newline at end of file diff --git a/server-go/pkg/repo/pg/pg.go b/server-go/pkg/repo/pg/pg.go index b5bce274..5b192c56 100644 --- a/server-go/pkg/repo/pg/pg.go +++ b/server-go/pkg/repo/pg/pg.go @@ -6,7 +6,7 @@ import "github.com/shampsdev/go-telegram-template/pkg/repo" var ( _ repo.User = &UserRepo{} _ repo.AdminUser = &AdminUserRepo{} - _ repo.Club = &ClubRepo{} + _ repo.Court = &CourtRepo{} _ repo.Tournament = &TournamentRepo{} _ repo.Loyalty = &LoyaltyRepo{} _ repo.Registration = &RegistrationRepo{} diff --git a/server-go/pkg/repo/pg/registration.go b/server-go/pkg/repo/pg/registration.go index f536bff5..8b78d373 100644 --- a/server-go/pkg/repo/pg/registration.go +++ b/server-go/pkg/repo/pg/registration.go @@ -42,37 +42,36 @@ func (r *RegistrationRepo) Create(ctx context.Context, registration *domain.Crea func (r *RegistrationRepo) Filter(ctx context.Context, filter *domain.FilterRegistration) ([]*domain.Registration, error) { s := r.psql.Select( - `"r"."id"`, `"r"."user_id"`, `"r"."tournament_id"`, `"r"."date"`, `"r"."status"`, + `"reg"."id"`, `"reg"."user_id"`, `"reg"."tournament_id"`, `"reg"."date"`, `"reg"."status"`, `"u"."id"`, `"u"."telegram_id"`, `"u"."telegram_username"`, `"u"."first_name"`, `"u"."last_name"`, `"u"."avatar"`, `"u"."bio"`, `"u"."rank"`, `"u"."city"`, `"u"."birth_date"`, `"u"."playing_position"`, `"u"."padel_profiles"`, `"u"."is_registered"`, - `"t"."id"`, `"t"."name"`, `"t"."start_time"`, `"t"."end_time"`, `"t"."price"`, - `"t"."rank_min"`, `"t"."rank_max"`, `"t"."max_users"`, `"t"."description"`, `"t"."tournament_type"`, + `"t"."id"`, `"t"."name"`, `"t"."start_time"`, `"t"."end_time"`, `"t"."price"`, `"t"."rank_min"`, `"t"."rank_max"`, `"t"."max_users"`, `"t"."description"`, `"t"."tournament_type"`, `"c"."id"`, `"c"."name"`, `"c"."address"`, `"org"."id"`, `"org"."telegram_id"`, `"org"."first_name"`, `"org"."last_name"`, `"org"."avatar"`, ). - From(`"registrations" AS r`). - LeftJoin(`"users" AS u ON "r"."user_id" = "u"."id"`). - LeftJoin(`"tournaments" AS t ON "r"."tournament_id" = "t"."id"`). - LeftJoin(`"clubs" AS c ON "t"."club_id" = "c"."id"`). - LeftJoin(`"users" AS org ON "t"."organizator_id" = "org"."id"`) + From(`"registrations" AS reg`). + Join(`"users" AS u ON "reg"."user_id" = "u"."id"`). + Join(`"tournaments" AS t ON "reg"."tournament_id" = "t"."id"`). + LeftJoin(`"courts" AS c ON "t"."court_id" = "c"."id"`). + Join(`"users" AS org ON "t"."organizator_id" = "org"."id"`) if filter.ID != nil { - s = s.Where(sq.Eq{`"r"."id"`: *filter.ID}) + s = s.Where(sq.Eq{`"reg"."id"`: *filter.ID}) } if filter.UserID != nil { - s = s.Where(sq.Eq{`"r"."user_id"`: *filter.UserID}) + s = s.Where(sq.Eq{`"reg"."user_id"`: *filter.UserID}) } if filter.TournamentID != nil { - s = s.Where(sq.Eq{`"r"."tournament_id"`: *filter.TournamentID}) + s = s.Where(sq.Eq{`"reg"."tournament_id"`: *filter.TournamentID}) } if filter.Status != nil { - s = s.Where(sq.Eq{`"r"."status"`: *filter.Status}) + s = s.Where(sq.Eq{`"reg"."status"`: *filter.Status}) } - s = s.OrderBy(`"r"."date" DESC`) + s = s.OrderBy(`"reg"."date" DESC`) sql, args, err := s.ToSql() if err != nil { @@ -93,7 +92,7 @@ func (r *RegistrationRepo) Filter(ctx context.Context, filter *domain.FilterRegi var registration domain.Registration var user domain.User var tournament domain.Tournament - var club domain.Club + var court domain.Court var organizator domain.User // Nullable fields @@ -137,9 +136,9 @@ func (r *RegistrationRepo) Filter(ctx context.Context, filter *domain.FilterRegi &tournament.MaxUsers, &tournamentDescription, &tournament.TournamentType, - &club.ID, - &club.Name, - &club.Address, + &court.ID, + &court.Name, + &court.Address, &organizator.ID, &organizator.TelegramID, &organizator.FirstName, @@ -193,7 +192,7 @@ func (r *RegistrationRepo) Filter(ctx context.Context, filter *domain.FilterRegi } // Set related entities - tournament.Club = club + tournament.Court = court tournament.Organizator = organizator registration.User = &user registrations = append(registrations, ®istration) @@ -245,7 +244,7 @@ func (r *RegistrationRepo) AdminFilter(ctx context.Context, filter *domain.Admin From(`"registrations" AS r`). LeftJoin(`"users" AS u ON "r"."user_id" = "u"."id"`). LeftJoin(`"tournaments" AS t ON "r"."tournament_id" = "t"."id"`). - LeftJoin(`"clubs" AS c ON "t"."club_id" = "c"."id"`). + LeftJoin(`"courts" AS c ON "t"."court_id" = "c"."id"`). LeftJoin(`"users" AS org ON "t"."organizator_id" = "org"."id"`) if filter.ID != nil { @@ -301,7 +300,7 @@ func (r *RegistrationRepo) AdminFilter(ctx context.Context, filter *domain.Admin var registration domain.RegistrationWithPayments var user domain.User var tournament domain.TournamentForRegistration - var club domain.Club + var court domain.Court var organizator domain.User // Nullable fields @@ -345,9 +344,9 @@ func (r *RegistrationRepo) AdminFilter(ctx context.Context, filter *domain.Admin &tournament.MaxUsers, &tournamentDescription, &tournament.TournamentType, - &club.ID, - &club.Name, - &club.Address, + &court.ID, + &court.Name, + &court.Address, &organizator.ID, &organizator.TelegramID, &organizator.FirstName, @@ -401,7 +400,7 @@ func (r *RegistrationRepo) AdminFilter(ctx context.Context, filter *domain.Admin } // Set related entities - tournament.Club = club + tournament.Court = court tournament.Organizator = organizator registration.User = &user registration.Tournament = &tournament diff --git a/server-go/pkg/repo/pg/tournament.go b/server-go/pkg/repo/pg/tournament.go index e46c4271..2dd769b1 100644 --- a/server-go/pkg/repo/pg/tournament.go +++ b/server-go/pkg/repo/pg/tournament.go @@ -34,7 +34,7 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna `COUNT(CASE WHEN "r"."status" IN ('PENDING', 'ACTIVE') THEN 1 END) AS active_registrations`, ). From(`"tournaments" AS t`). - Join(`"clubs" AS c ON "t"."club_id" = "c"."id"`). + Join(`"courts" AS c ON "t"."court_id" = "c"."id"`). Join(`"users" AS u ON "t"."organizator_id" = "u"."id"`). LeftJoin(`"registrations" AS r ON "t"."id" = "r"."tournament_id"`). GroupBy(`"t"."id"`, `"c"."id"`, `"u"."id"`) @@ -80,7 +80,7 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna var tournament domain.Tournament var endTime pgtype.Timestamp var description pgtype.Text - var clubID, clubName, clubAddress string + var courtID, courtName, courtAddress string var userID string var userTelegramID int64 var userTelegramUsername pgtype.Text @@ -106,9 +106,9 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna &tournament.MaxUsers, &description, &tournament.TournamentType, - &clubID, - &clubName, - &clubAddress, + &courtID, + &courtName, + &courtAddress, &userID, &userTelegramID, &userTelegramUsername, @@ -135,10 +135,10 @@ func (r *TournamentRepo) Filter(ctx context.Context, filter *domain.FilterTourna tournament.Description = description.String } - tournament.Club = domain.Club{ - ID: clubID, - Name: clubName, - Address: clubAddress, + tournament.Court = domain.Court{ + ID: courtID, + Name: courtName, + Address: courtAddress, } organizator := domain.User{ @@ -194,7 +194,7 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri From(`"tournaments" AS t`). Join(`"registrations" AS reg ON "t"."id" = "reg"."tournament_id"`). Join(`"users" AS u ON "reg"."user_id" = "u"."id"`). - Join(`"clubs" AS c ON "t"."club_id" = "c"."id"`). + Join(`"courts" AS c ON "t"."court_id" = "c"."id"`). Join(`"users" AS org ON "t"."organizator_id" = "org"."id"`). Where(sq.Eq{`"u"."id"`: userID}). Where(sq.Eq{`"reg"."status"`: []string{"ACTIVE", "CANCELED"}}). @@ -219,7 +219,7 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri var tournament domain.Tournament var endTime pgtype.Timestamp var description pgtype.Text - var clubID, clubName, clubAddress string + var courtID, courtName, courtAddress string var orgID string var orgTelegramID int64 var orgTelegramUsername pgtype.Text @@ -244,9 +244,9 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri &tournament.MaxUsers, &description, &tournament.TournamentType, - &clubID, - &clubName, - &clubAddress, + &courtID, + &courtName, + &courtAddress, &orgID, &orgTelegramID, &orgTelegramUsername, @@ -272,10 +272,10 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri tournament.Description = description.String } - tournament.Club = domain.Club{ - ID: clubID, - Name: clubName, - Address: clubAddress, + tournament.Court = domain.Court{ + ID: courtID, + Name: courtName, + Address: courtAddress, } organizator := domain.User{ @@ -323,10 +323,10 @@ func (r *TournamentRepo) GetTournamentsByUserID(ctx context.Context, userID stri func (r *TournamentRepo) Create(ctx context.Context, tournament *domain.CreateTournament) (string, error) { s := r.psql.Insert(`"tournaments"`). Columns("name", "start_time", "end_time", "price", "rank_min", "rank_max", - "max_users", "description", "club_id", "tournament_type", "organizator_id"). + "max_users", "description", "court_id", "tournament_type", "organizator_id"). Values(tournament.Name, tournament.StartTime, tournament.EndTime, tournament.Price, tournament.RankMin, tournament.RankMax, tournament.MaxUsers, tournament.Description, - tournament.ClubID, tournament.TournamentType, tournament.OrganizatorID). + tournament.CourtID, tournament.TournamentType, tournament.OrganizatorID). Suffix("RETURNING id") sql, args, err := s.ToSql() @@ -366,8 +366,8 @@ func (r *TournamentRepo) Patch(ctx context.Context, id string, tournament *domai if tournament.Description != nil { s = s.Set("description", *tournament.Description) } - if tournament.ClubID != nil { - s = s.Set("club_id", *tournament.ClubID) + if tournament.CourtID != nil { + s = s.Set("court_id", *tournament.CourtID) } if tournament.TournamentType != nil { s = s.Set("tournament_type", *tournament.TournamentType) diff --git a/server-go/pkg/repo/repo.go b/server-go/pkg/repo/repo.go index cd290988..702e4097 100644 --- a/server-go/pkg/repo/repo.go +++ b/server-go/pkg/repo/repo.go @@ -28,10 +28,10 @@ type AdminUser interface { UpdatePassword(ctx context.Context, id string, passwordHash string) error } -type Club interface { - Create(ctx context.Context, club *domain.CreateClub) (string, error) - Patch(ctx context.Context, id string, club *domain.PatchClub) error - Filter(ctx context.Context, filter *domain.FilterClub) ([]*domain.Club, error) +type Court interface { + Create(ctx context.Context, court *domain.CreateCourt) (string, error) + Patch(ctx context.Context, id string, court *domain.PatchCourt) error + Filter(ctx context.Context, filter *domain.FilterCourt) ([]*domain.Court, error) Delete(ctx context.Context, id string) error } diff --git a/server-go/pkg/usecase/club.go b/server-go/pkg/usecase/club.go deleted file mode 100644 index 3c319718..00000000 --- a/server-go/pkg/usecase/club.go +++ /dev/null @@ -1,50 +0,0 @@ -package usecase - -import ( - "context" - - "github.com/shampsdev/go-telegram-template/pkg/domain" - "github.com/shampsdev/go-telegram-template/pkg/repo" -) - -type Club struct { - ctx context.Context - clubRepo repo.Club -} - -func NewClub(ctx context.Context, clubRepo repo.Club) *Club { - return &Club{ - ctx: ctx, - clubRepo: clubRepo, - } -} - -func (c *Club) Create(ctx Context, club *domain.CreateClub) (string, error) { - return c.clubRepo.Create(ctx.Context, club) -} - -func (c *Club) Update(ctx Context, id string, club *domain.PatchClub) error { - return c.clubRepo.Patch(ctx.Context, id, club) -} - -func (c *Club) GetAll(ctx Context, filter *domain.FilterClub) ([]*domain.Club, error) { - return c.clubRepo.Filter(ctx.Context, filter) -} - -func (c *Club) GetByID(ctx Context, id string) (*domain.Club, error) { - filter := &domain.FilterClub{ID: &id} - clubs, err := c.clubRepo.Filter(ctx.Context, filter) - if err != nil { - return nil, err - } - - if len(clubs) == 0 { - return nil, repo.ErrNotFound - } - - return clubs[0], nil -} - -func (c *Club) Delete(ctx Context, id string) error { - return c.clubRepo.Delete(ctx.Context, id) -} \ No newline at end of file diff --git a/server-go/pkg/usecase/court.go b/server-go/pkg/usecase/court.go new file mode 100644 index 00000000..08e824ad --- /dev/null +++ b/server-go/pkg/usecase/court.go @@ -0,0 +1,50 @@ +package usecase + +import ( + "context" + + "github.com/shampsdev/go-telegram-template/pkg/domain" + "github.com/shampsdev/go-telegram-template/pkg/repo" +) + +type Court struct { + ctx context.Context + courtRepo repo.Court +} + +func NewCourt(ctx context.Context, courtRepo repo.Court) *Court { + return &Court{ + ctx: ctx, + courtRepo: courtRepo, + } +} + +func (c *Court) Create(ctx Context, court *domain.CreateCourt) (string, error) { + return c.courtRepo.Create(ctx.Context, court) +} + +func (c *Court) Update(ctx Context, id string, court *domain.PatchCourt) error { + return c.courtRepo.Patch(ctx.Context, id, court) +} + +func (c *Court) GetAll(ctx Context, filter *domain.FilterCourt) ([]*domain.Court, error) { + return c.courtRepo.Filter(ctx.Context, filter) +} + +func (c *Court) GetByID(ctx Context, id string) (*domain.Court, error) { + filter := &domain.FilterCourt{ID: &id} + courts, err := c.courtRepo.Filter(ctx.Context, filter) + if err != nil { + return nil, err + } + + if len(courts) == 0 { + return nil, repo.ErrNotFound + } + + return courts[0], nil +} + +func (c *Court) Delete(ctx Context, id string) error { + return c.courtRepo.Delete(ctx.Context, id) +} \ No newline at end of file diff --git a/server-go/pkg/usecase/registration.go b/server-go/pkg/usecase/registration.go index 3475cc66..f522dd8e 100644 --- a/server-go/pkg/usecase/registration.go +++ b/server-go/pkg/usecase/registration.go @@ -336,7 +336,7 @@ func (r *Registration) GetUserRegistrationsWithTournament(ctx context.Context, u continue } - regWithTournament.Tournament = &domain.TournamentForRegistration{ + tournamentForReg := domain.TournamentForRegistration{ ID: tournament.ID, Name: tournament.Name, StartTime: tournament.StartTime, @@ -346,11 +346,13 @@ func (r *Registration) GetUserRegistrationsWithTournament(ctx context.Context, u RankMax: tournament.RankMax, MaxUsers: tournament.MaxUsers, Description: tournament.Description, - Club: tournament.Club, + Court: tournament.Court, TournamentType: tournament.TournamentType, Organizator: tournament.Organizator, } + regWithTournament.Tournament = &tournamentForReg + result = append(result, regWithTournament) } diff --git a/server-go/pkg/usecase/usecase.go b/server-go/pkg/usecase/usecase.go index 3df9639a..72a9d1c7 100644 --- a/server-go/pkg/usecase/usecase.go +++ b/server-go/pkg/usecase/usecase.go @@ -13,7 +13,7 @@ type Cases struct { User *User AdminUser *AdminUser Image *Image - Club *Club + Court *Court Tournament *Tournament Loyalty *Loyalty Registration *Registration @@ -24,7 +24,7 @@ type Cases struct { func Setup(ctx context.Context, cfg *config.Config, db *pgxpool.Pool) Cases { userRepo := pg.NewUserRepo(db) adminUserRepo := pg.NewAdminUserRepo(db) - clubRepo := pg.NewClubRepo(db) + courtRepo := pg.NewCourtRepo(db) tournamentRepo := pg.NewTournamentRepo(db) loyaltyRepo := pg.NewLoyaltyRepo(db) registrationRepo := pg.NewRegistrationRepo(db) @@ -39,7 +39,7 @@ func Setup(ctx context.Context, cfg *config.Config, db *pgxpool.Pool) Cases { userCase := NewUser(ctx, userRepo, storage) adminUserCase := NewAdminUser(ctx, adminUserRepo, cfg) imageCase := NewImage(ctx, storage) - clubCase := NewClub(ctx, clubRepo) + courtCase := NewCourt(ctx, courtRepo) tournamentCase := NewTournament(ctx, tournamentRepo, registrationRepo) loyaltyCase := NewLoyalty(ctx, loyaltyRepo) registrationCase := NewRegistration(ctx, registrationRepo, tournamentRepo, paymentRepo) @@ -50,7 +50,7 @@ func Setup(ctx context.Context, cfg *config.Config, db *pgxpool.Pool) Cases { User: userCase, AdminUser: adminUserCase, Image: imageCase, - Club: clubCase, + Court: courtCase, Tournament: tournamentCase, Loyalty: loyaltyCase, Registration: registrationCase, From 13bfa12d2a9715a765d26c122fb93f014831a8ff Mon Sep 17 00:00:00 2001 From: AlexDyakonov Date: Fri, 4 Jul 2025 12:48:45 +0300 Subject: [PATCH 7/7] rebane club->court --- admin-new/src/api/registrations.ts | 2 +- admin-new/src/shared/types.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/admin-new/src/api/registrations.ts b/admin-new/src/api/registrations.ts index 3c866dd7..d0a1812b 100644 --- a/admin-new/src/api/registrations.ts +++ b/admin-new/src/api/registrations.ts @@ -20,7 +20,7 @@ export interface Tournament { rankMax: number; maxUsers: number; description: string; - club: { + court: { id: string; name: string; address: string; diff --git a/admin-new/src/shared/types.ts b/admin-new/src/shared/types.ts index 4d107f6e..a3f82b57 100644 --- a/admin-new/src/shared/types.ts +++ b/admin-new/src/shared/types.ts @@ -1,4 +1,4 @@ -export interface Club { +export interface Court { id: string name: string address: string @@ -10,7 +10,7 @@ export interface Tournament { start_time: string end_time?: string price: number - club_id: string + court_id: string tournament_type: string rank_min: number rank_max: number