From b960100d246a2c54778dc3501599adb1d7e4b224 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Sat, 17 Jun 2023 17:26:46 +0300 Subject: fix: reorganize models (#44) --- backend/models/requests.go | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 backend/models/requests.go (limited to 'backend/models/requests.go') diff --git a/backend/models/requests.go b/backend/models/requests.go new file mode 100644 index 0000000..49b2d75 --- /dev/null +++ b/backend/models/requests.go @@ -0,0 +1,8 @@ +package models + +type RecordRequest struct { + ScoreCount int `json:"score_count" form:"score_count" binding:"required"` + ScoreTime int `json:"score_time" form:"score_time" binding:"required"` + PartnerID string `json:"partner_id" form:"partner_id" binding:"required"` + IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange" binding:"required"` +} -- cgit v1.2.3 From 8cce8b446e63d03161f0807c76721b40d851b50d Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 28 Jun 2023 23:27:22 +0300 Subject: feat: mod edit for map summary Former-commit-id: dbef520658347a8c23546371ced24f1c0271749d --- backend/controllers/modController.go | 91 ++++++++++++++++++++++++++++++++++++ backend/middleware/auth.go | 10 +++- backend/models/models.go | 1 + backend/models/requests.go | 29 ++++++++++-- backend/routes/routes.go | 1 + 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 backend/controllers/modController.go (limited to 'backend/models/requests.go') diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go new file mode 100644 index 0000000..ebf1cb7 --- /dev/null +++ b/backend/controllers/modController.go @@ -0,0 +1,91 @@ +package controllers + +import ( + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/pektezol/leastportals/backend/database" + "github.com/pektezol/leastportals/backend/models" +) + +// PUT Map Summary +// +// @Summary Edit map summary with specified map id. +// @Tags maps +// @Produce json +// @Param id path int true "Map ID" +// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [put] +func EditMapSummary(c *gin.Context) { + // Check if user exists + user, exists := c.Get("user") + if !exists { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) + return + } + var moderator bool + for _, title := range user.(models.User).Titles { + if title == "Moderator" { + moderator = true + } + } + if !moderator { + c.JSON(http.StatusUnauthorized, "Insufficient permissions.") + return + } + // Bind parameter and body + id := c.Param("id") + mapID, err := strconv.Atoi(id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + var request models.EditMapSummaryRequest + if err := c.BindJSON(&request); err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Fetch route category and score count + var categoryID, scoreCount int + sql := `SELECT mr.category_id, mr.score_count + FROM map_routes mr + INNER JOIN maps m + WHERE m.id = $1 AND mr.id = $2` + err = database.DB.QueryRow(sql, mapID, request.RouteID).Scan(&categoryID, &scoreCount) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Start database transaction + tx, err := database.DB.Begin() + if err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) + return + } + defer tx.Rollback() + // Update database with new data + sql = `UPDATE map_routes SET score_count = $2, description = $3, showcase = $4 WHERE id = $1` + _, err = tx.Exec(sql, request.RouteID, request.ScoreCount, request.Description, request.Showcase) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + sql = `UPDATE map_history SET user_name = $3, score_count = $4, record_date = $5 WHERE map_id = $1 AND category_id = $2` + _, err = tx.Exec(sql, mapID, categoryID, request.UserName, request.ScoreCount, request.RecordDate) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + if err = tx.Commit(); err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) + return + } + // Return response + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully updated map summary.", + Data: request, + }) +} diff --git a/backend/middleware/auth.go b/backend/middleware/auth.go index 14a0b78..86e79d9 100644 --- a/backend/middleware/auth.go +++ b/backend/middleware/auth.go @@ -36,13 +36,21 @@ func CheckAuth(c *gin.Context) { } // Get user from DB var user models.User - database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1`, claims["sub"]).Scan( + database.DB.QueryRow(`SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, array_agg(t.) FROM users u WHERE steam_id = $1`, claims["sub"]).Scan( &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt) if user.SteamID == "" { c.Next() return } + // Get user titles from DB + user.Titles = []string{} + rows, _ := database.DB.Query(`SELECT t.title_name FROM titles t WHERE t.user_id = $1`, user.SteamID) + for rows.Next() { + var title string + rows.Scan(&title) + user.Titles = append(user.Titles, title) + } c.Set("user", user) c.Next() } else { diff --git a/backend/models/models.go b/backend/models/models.go index 7b8cbc4..5355a9f 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -11,6 +11,7 @@ type User struct { CountryCode string `json:"country_code"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` + Titles []string `json:"titles"` } type UserShort struct { diff --git a/backend/models/requests.go b/backend/models/requests.go index 49b2d75..e95eab6 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -1,8 +1,29 @@ package models +import ( + "mime/multipart" + "time" +) + +type EditMapSummaryRequest struct { + RouteID int `json:"route_id" binding:"required"` + Description string `json:"description" binding:"required"` + Showcase string `json:"showcase" binding:"required"` + UserName string `json:"user_name" binding:"required"` + ScoreCount int `json:"score_count" binding:"required"` + RecordDate time.Time `json:"record_date" binding:"required"` +} + +type CreateMapHistoryRequest struct { + CategoryID int `json:"category_id" binding:"required"` + UserName string `json:"user_name" binding:"required"` + ScoreCount int `json:"score_count" binding:"required"` + RecordDate time.Time `json:"record_date" binding:"required"` +} + type RecordRequest struct { - ScoreCount int `json:"score_count" form:"score_count" binding:"required"` - ScoreTime int `json:"score_time" form:"score_time" binding:"required"` - PartnerID string `json:"partner_id" form:"partner_id" binding:"required"` - IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange" binding:"required"` + HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required"` + PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo"` + IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange"` + PartnerID string `json:"partner_id" form:"partner_id"` } diff --git a/backend/routes/routes.go b/backend/routes/routes.go index bf8a995..93dc1dd 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -26,6 +26,7 @@ func InitRoutes(router *gin.Engine) { v1.GET("/users/:id", middleware.CheckAuth, controllers.FetchUser) v1.GET("/demos", controllers.DownloadDemoWithID) v1.GET("/maps/:id/summary", middleware.CheckAuth, controllers.FetchMapSummary) + v1.PUT("/maps/:id/summary", middleware.CheckAuth, controllers.EditMapSummary) v1.GET("/maps/:id/leaderboards", middleware.CheckAuth, controllers.FetchMapLeaderboards) v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) v1.GET("/rankings", middleware.CheckAuth, controllers.Rankings) -- cgit v1.2.3 From 7050773414c550b7693c41a9bdd8cb390d7ef647 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 29 Jun 2023 10:45:12 +0300 Subject: fix: record controller Former-commit-id: bff6b62474e02f644d93f49827145cfd92682c6f --- backend/controllers/recordController.go | 87 +++++++++-------------- backend/models/requests.go | 4 +- backend/parser/parser.go | 7 ++ docs/docs.go | 118 ++++++++++++++++++++++++-------- docs/swagger.json | 112 ++++++++++++++++++++++-------- docs/swagger.yaml | 78 +++++++++++++++------ 6 files changed, 269 insertions(+), 137 deletions(-) create mode 100644 backend/parser/parser.go (limited to 'backend/models/requests.go') diff --git a/backend/controllers/recordController.go b/backend/controllers/recordController.go index 627be57..aec31bb 100644 --- a/backend/controllers/recordController.go +++ b/backend/controllers/recordController.go @@ -5,14 +5,15 @@ import ( b64 "encoding/base64" "io" "log" + "mime/multipart" "net/http" "os" - "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/pektezol/leastportals/backend/database" "github.com/pektezol/leastportals/backend/models" + "github.com/pektezol/leastportals/backend/parser" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" "google.golang.org/api/drive/v3" @@ -25,9 +26,8 @@ import ( // @Accept mpfd // @Produce json // @Param Authorization header string true "JWT Token" -// @Param demos formData []file true "Demos" -// @Param score_count formData int true "Score Count" -// @Param score_time formData int true "Score Time" +// @Param host_demo formData file true "Host Demo" +// @Param partner_demo formData file true "Partner Demo" // @Param is_partner_orange formData boolean true "Is Partner Orange" // @Param partner_id formData string true "Partner ID" // @Success 200 {object} models.Response{data=models.RecordRequest} @@ -43,11 +43,11 @@ func CreateRecordWithDemo(c *gin.Context) { return } // Check if map is sp or mp - var gameID int + var gameName string var isCoop bool var isDisabled bool - sql := `SELECT game_id, is_disabled FROM maps WHERE id = $1` - err := database.DB.QueryRow(sql, mapId).Scan(&gameID, &isDisabled) + sql := `SELECT g.name, m.is_disabled FROM maps m INNER JOIN games g ON m.game_id=g.id WHERE id = $1` + err := database.DB.QueryRow(sql, mapId).Scan(&gameName, &isDisabled) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return @@ -56,51 +56,23 @@ func CreateRecordWithDemo(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse("Map is not available for competitive boards.")) return } - if gameID == 2 { + if gameName == "Portal 2 - Cooperative" { isCoop = true } // Get record request var record models.RecordRequest - score_count, err := strconv.Atoi(c.PostForm("score_count")) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - score_time, err := strconv.Atoi(c.PostForm("score_time")) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - is_partner_orange, err := strconv.ParseBool(c.PostForm("is_partner_orange")) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - record.ScoreCount = score_count - record.ScoreTime = score_time - record.PartnerID = c.PostForm("partner_id") - record.IsPartnerOrange = is_partner_orange - if record.PartnerID == "" { - c.JSON(http.StatusBadRequest, models.ErrorResponse("No partner id given.")) - return - } - // Multipart form - form, err := c.MultipartForm() - if err != nil { + if err := c.ShouldBind(&record); err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - files := form.File["demos"] - if len(files) != 2 && isCoop { - c.JSON(http.StatusBadRequest, models.ErrorResponse("Not enough demos for coop submission.")) - return - } - if len(files) != 1 && !isCoop { - c.JSON(http.StatusBadRequest, models.ErrorResponse("Too many demos for singleplayer submission.")) + if isCoop && (record.PartnerDemo == nil || record.PartnerID == "") { + c.JSON(http.StatusBadRequest, models.ErrorResponse("Invalid entry for coop record submission.")) return } - var hostDemoUUID string - var partnerDemoUUID string + // Demo files + demoFiles := []*multipart.FileHeader{record.HostDemo, record.PartnerDemo} + var hostDemoUUID, hostDemoFileID, partnerDemoUUID, partnerDemoFileID string + var hostDemoScoreCount, hostDemoScoreTime int client := serviceAccount() srv, err := drive.New(client) if err != nil { @@ -115,16 +87,15 @@ func CreateRecordWithDemo(c *gin.Context) { } // Defer to a rollback in case anything fails defer tx.Rollback() - fileID := "" - for i, header := range files { + for i, header := range demoFiles { uuid := uuid.New().String() // Upload & insert into demos - err = c.SaveUploadedFile(header, "docs/"+header.Filename) + err = c.SaveUploadedFile(header, "parser/demos/"+header.Filename) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - f, err := os.Open("docs/" + header.Filename) + f, err := os.Open("parser/demos/" + header.Filename) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return @@ -135,11 +106,16 @@ func CreateRecordWithDemo(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - fileID = file.Id + hostDemoScoreCount, hostDemoScoreTime, err = parser.ProcessDemo(record.HostDemo) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } if i == 0 { + hostDemoFileID = file.Id hostDemoUUID = uuid - } - if i == 1 { + } else if i == 1 { + partnerDemoFileID = file.Id partnerDemoUUID = uuid } _, err = tx.Exec(`INSERT INTO demos (id,location_id) VALUES ($1,$2)`, uuid, file.Id) @@ -148,7 +124,7 @@ func CreateRecordWithDemo(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - os.Remove("docs/" + header.Filename) + os.Remove("parser/demos/" + header.Filename) } // Insert into records if isCoop { @@ -163,9 +139,10 @@ func CreateRecordWithDemo(c *gin.Context) { partnerID = user.(models.User).SteamID hostID = record.PartnerID } - _, err := tx.Exec(sql, mapId, record.ScoreCount, record.ScoreTime, hostID, partnerID, hostDemoUUID, partnerDemoUUID) + _, err := tx.Exec(sql, mapId, hostDemoScoreCount, hostDemoScoreTime, hostID, partnerID, hostDemoUUID, partnerDemoUUID) if err != nil { - deleteFile(srv, fileID) + deleteFile(srv, hostDemoFileID) + deleteFile(srv, partnerDemoFileID) c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } @@ -180,9 +157,9 @@ func CreateRecordWithDemo(c *gin.Context) { } else { sql := `INSERT INTO records_sp(map_id,score_count,score_time,user_id,demo_id) VALUES($1, $2, $3, $4, $5)` - _, err := tx.Exec(sql, mapId, record.ScoreCount, record.ScoreTime, user.(models.User).SteamID, hostDemoUUID) + _, err := tx.Exec(sql, mapId, hostDemoScoreCount, hostDemoScoreTime, user.(models.User).SteamID, hostDemoUUID) if err != nil { - deleteFile(srv, fileID) + deleteFile(srv, hostDemoFileID) c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } diff --git a/backend/models/requests.go b/backend/models/requests.go index e95eab6..4b4657b 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -22,8 +22,8 @@ type CreateMapHistoryRequest struct { } type RecordRequest struct { - HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required"` - PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo"` + HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` + PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange"` PartnerID string `json:"partner_id" form:"partner_id"` } diff --git a/backend/parser/parser.go b/backend/parser/parser.go new file mode 100644 index 0000000..6f9a24f --- /dev/null +++ b/backend/parser/parser.go @@ -0,0 +1,7 @@ +package parser + +import "mime/multipart" + +func ProcessDemo(demo *multipart.FileHeader) (scoreCount int, scoreTime int, err error) { + return 0, 0, nil +} diff --git a/docs/docs.go b/docs/docs.go index a0aad6f..090d3e8 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,5 +1,5 @@ -// Package docs GENERATED BY SWAG; DO NOT EDIT -// This file was generated by swaggo/swag +// Code generated by swaggo/swag. DO NOT EDIT. + package docs import "github.com/swaggo/swag" @@ -345,26 +345,16 @@ const docTemplate = `{ "required": true }, { - "type": "array", - "items": { - "type": "file" - }, - "description": "Demos", - "name": "demos", + "type": "file", + "description": "Host Demo", + "name": "host_demo", "in": "formData", "required": true }, { - "type": "integer", - "description": "Score Count", - "name": "score_count", - "in": "formData", - "required": true - }, - { - "type": "integer", - "description": "Score Time", - "name": "score_time", + "type": "file", + "description": "Partner Demo", + "name": "partner_demo", "in": "formData", "required": true }, @@ -461,6 +451,50 @@ const docTemplate = `{ } } } + }, + "put": { + "produces": [ + "application/json" + ], + "tags": [ + "maps" + ], + "summary": "Edit map summary with specified map id.", + "parameters": [ + { + "type": "integer", + "description": "Map ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.EditMapSummaryRequest" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } } }, "/profile": { @@ -843,6 +877,37 @@ const docTemplate = `{ } } }, + "models.EditMapSummaryRequest": { + "type": "object", + "required": [ + "description", + "record_date", + "route_id", + "score_count", + "showcase", + "user_name" + ], + "properties": { + "description": { + "type": "string" + }, + "record_date": { + "type": "string" + }, + "route_id": { + "type": "integer" + }, + "score_count": { + "type": "integer" + }, + "showcase": { + "type": "string" + }, + "user_name": { + "type": "string" + } + } + }, "models.Game": { "type": "object", "properties": { @@ -874,6 +939,9 @@ const docTemplate = `{ "id": { "type": "integer" }, + "image": { + "type": "string" + }, "map_name": { "type": "string" } @@ -1003,24 +1071,12 @@ const docTemplate = `{ }, "models.RecordRequest": { "type": "object", - "required": [ - "is_partner_orange", - "partner_id", - "score_count", - "score_time" - ], "properties": { "is_partner_orange": { "type": "boolean" }, "partner_id": { "type": "string" - }, - "score_count": { - "type": "integer" - }, - "score_time": { - "type": "integer" } } }, @@ -1100,6 +1156,8 @@ var SwaggerInfo = &swag.Spec{ Description: "Backend API endpoints for the Least Portals Database.", InfoInstanceName: "swagger", SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", } func init() { diff --git a/docs/swagger.json b/docs/swagger.json index 2279ff6..62079b1 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -338,26 +338,16 @@ "required": true }, { - "type": "array", - "items": { - "type": "file" - }, - "description": "Demos", - "name": "demos", + "type": "file", + "description": "Host Demo", + "name": "host_demo", "in": "formData", "required": true }, { - "type": "integer", - "description": "Score Count", - "name": "score_count", - "in": "formData", - "required": true - }, - { - "type": "integer", - "description": "Score Time", - "name": "score_time", + "type": "file", + "description": "Partner Demo", + "name": "partner_demo", "in": "formData", "required": true }, @@ -454,6 +444,50 @@ } } } + }, + "put": { + "produces": [ + "application/json" + ], + "tags": [ + "maps" + ], + "summary": "Edit map summary with specified map id.", + "parameters": [ + { + "type": "integer", + "description": "Map ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.EditMapSummaryRequest" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } } }, "/profile": { @@ -836,6 +870,37 @@ } } }, + "models.EditMapSummaryRequest": { + "type": "object", + "required": [ + "description", + "record_date", + "route_id", + "score_count", + "showcase", + "user_name" + ], + "properties": { + "description": { + "type": "string" + }, + "record_date": { + "type": "string" + }, + "route_id": { + "type": "integer" + }, + "score_count": { + "type": "integer" + }, + "showcase": { + "type": "string" + }, + "user_name": { + "type": "string" + } + } + }, "models.Game": { "type": "object", "properties": { @@ -867,6 +932,9 @@ "id": { "type": "integer" }, + "image": { + "type": "string" + }, "map_name": { "type": "string" } @@ -996,24 +1064,12 @@ }, "models.RecordRequest": { "type": "object", - "required": [ - "is_partner_orange", - "partner_id", - "score_count", - "score_time" - ], "properties": { "is_partner_orange": { "type": "boolean" }, "partner_id": { "type": "string" - }, - "score_count": { - "type": "integer" - }, - "score_time": { - "type": "integer" } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ba4775a..9d58620 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -32,6 +32,28 @@ definitions: game: $ref: '#/definitions/models.Game' type: object + models.EditMapSummaryRequest: + properties: + description: + type: string + record_date: + type: string + route_id: + type: integer + score_count: + type: integer + showcase: + type: string + user_name: + type: string + required: + - description + - record_date + - route_id + - score_count + - showcase + - user_name + type: object models.Game: properties: id: @@ -52,6 +74,8 @@ definitions: type: string id: type: integer + image: + type: string map_name: type: string type: object @@ -140,15 +164,6 @@ definitions: type: boolean partner_id: type: string - score_count: - type: integer - score_time: - type: integer - required: - - is_partner_orange - - partner_id - - score_count - - score_time type: object models.Response: properties: @@ -388,23 +403,16 @@ paths: name: Authorization required: true type: string - - description: Demos - in: formData - items: - type: file - name: demos - required: true - type: array - - description: Score Count + - description: Host Demo in: formData - name: score_count + name: host_demo required: true - type: integer - - description: Score Time + type: file + - description: Partner Demo in: formData - name: score_time + name: partner_demo required: true - type: integer + type: file - description: Is Partner Orange in: formData name: is_partner_orange @@ -465,6 +473,32 @@ paths: summary: Get map summary with specified id. tags: - maps + put: + parameters: + - description: Map ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/models.Response' + - properties: + data: + $ref: '#/definitions/models.EditMapSummaryRequest' + type: object + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Response' + summary: Edit map summary with specified map id. + tags: + - maps /profile: get: consumes: -- cgit v1.2.3 From 84346e6006d6e88dfef99550da3c2e80071f0197 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 29 Jun 2023 12:32:28 +0300 Subject: feat: support for multiple route edit, image field Former-commit-id: 3820c1363ece1c6616ec0297e44de851bae410af --- backend/controllers/modController.go | 49 ++++++++++++++++++++---------------- backend/models/requests.go | 5 ++++ docs/docs.go | 45 ++++++++++++++++----------------- docs/swagger.json | 45 ++++++++++++++++----------------- docs/swagger.yaml | 27 ++++++++++---------- 5 files changed, 88 insertions(+), 83 deletions(-) (limited to 'backend/models/requests.go') diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index 9d14f92..7c258ef 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -48,17 +48,6 @@ func EditMapSummary(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - // Fetch route category and score count - var categoryID, scoreCount int - sql := `SELECT mr.category_id, mr.score_count - FROM map_routes mr - INNER JOIN maps m - WHERE m.id = $1 AND mr.id = $2` - err = database.DB.QueryRow(sql, mapID, request.RouteID).Scan(&categoryID, &scoreCount) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } // Start database transaction tx, err := database.DB.Begin() if err != nil { @@ -66,18 +55,34 @@ func EditMapSummary(c *gin.Context) { return } defer tx.Rollback() - // Update database with new data - sql = `UPDATE map_routes SET score_count = $2, description = $3, showcase = $4 WHERE id = $1` - _, err = tx.Exec(sql, request.RouteID, request.ScoreCount, request.Description, request.Showcase) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return + if request.Image != "" { + tx.Exec(`UPDATE maps m SET image = $2 WHERE m.id = $1`, mapID, request.Image) } - sql = `UPDATE map_history SET user_name = $3, score_count = $4, record_date = $5 WHERE map_id = $1 AND category_id = $2` - _, err = tx.Exec(sql, mapID, categoryID, request.UserName, request.ScoreCount, request.RecordDate) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return + for _, route := range request.Routes { + // Fetch route category and score count + var categoryID, scoreCount int + sql := `SELECT mr.category_id, mr.score_count + FROM map_routes mr + INNER JOIN maps m + WHERE m.id = $1 AND mr.id = $2` + err = database.DB.QueryRow(sql, mapID, route.RouteID).Scan(&categoryID, &scoreCount) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Update database with new data + sql = `UPDATE map_routes SET score_count = $2, description = $3, showcase = $4 WHERE id = $1` + _, err = tx.Exec(sql, route.RouteID, route.ScoreCount, route.Description, route.Showcase) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + sql = `UPDATE map_history SET user_name = $3, score_count = $4, record_date = $5 WHERE map_id = $1 AND category_id = $2` + _, err = tx.Exec(sql, mapID, categoryID, route.UserName, route.ScoreCount, route.RecordDate) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } } if err = tx.Commit(); err != nil { c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) diff --git a/backend/models/requests.go b/backend/models/requests.go index 4b4657b..7a00567 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -6,6 +6,11 @@ import ( ) type EditMapSummaryRequest struct { + Image string `json:"image" binding:"required"` + Routes []EditMapSummaryRequestDetails `json:"routes" binding:"dive"` +} + +type EditMapSummaryRequestDetails struct { RouteID int `json:"route_id" binding:"required"` Description string `json:"description" binding:"required"` Showcase string `json:"showcase" binding:"required"` diff --git a/docs/docs.go b/docs/docs.go index 91f91ef..8318e14 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -377,19 +377,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "allOf": [ - { - "$ref": "#/definitions/models.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.RecordRequest" - } - } - } - ] + "$ref": "#/definitions/models.Response" } }, "400": { @@ -887,6 +875,23 @@ const docTemplate = `{ } }, "models.EditMapSummaryRequest": { + "type": "object", + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string" + }, + "routes": { + "type": "array", + "items": { + "$ref": "#/definitions/models.EditMapSummaryRequestDetails" + } + } + } + }, + "models.EditMapSummaryRequestDetails": { "type": "object", "required": [ "description", @@ -991,6 +996,9 @@ const docTemplate = `{ "rating": { "type": "number" }, + "route_id": { + "type": "integer" + }, "showcase": { "type": "string" } @@ -1078,17 +1086,6 @@ const docTemplate = `{ } } }, - "models.RecordRequest": { - "type": "object", - "properties": { - "is_partner_orange": { - "type": "boolean" - }, - "partner_id": { - "type": "string" - } - } - }, "models.Response": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index c6bbfbc..212ebee 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -370,19 +370,7 @@ "200": { "description": "OK", "schema": { - "allOf": [ - { - "$ref": "#/definitions/models.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.RecordRequest" - } - } - } - ] + "$ref": "#/definitions/models.Response" } }, "400": { @@ -880,6 +868,23 @@ } }, "models.EditMapSummaryRequest": { + "type": "object", + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string" + }, + "routes": { + "type": "array", + "items": { + "$ref": "#/definitions/models.EditMapSummaryRequestDetails" + } + } + } + }, + "models.EditMapSummaryRequestDetails": { "type": "object", "required": [ "description", @@ -984,6 +989,9 @@ "rating": { "type": "number" }, + "route_id": { + "type": "integer" + }, "showcase": { "type": "string" } @@ -1071,17 +1079,6 @@ } } }, - "models.RecordRequest": { - "type": "object", - "properties": { - "is_partner_orange": { - "type": "boolean" - }, - "partner_id": { - "type": "string" - } - } - }, "models.Response": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4291cfc..ba20f6d 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -33,6 +33,17 @@ definitions: $ref: '#/definitions/models.Game' type: object models.EditMapSummaryRequest: + properties: + image: + type: string + routes: + items: + $ref: '#/definitions/models.EditMapSummaryRequestDetails' + type: array + required: + - image + type: object + models.EditMapSummaryRequestDetails: properties: description: type: string @@ -102,6 +113,8 @@ definitions: $ref: '#/definitions/models.MapHistory' rating: type: number + route_id: + type: integer showcase: type: string type: object @@ -158,13 +171,6 @@ definitions: $ref: '#/definitions/models.UserRanking' type: array type: object - models.RecordRequest: - properties: - is_partner_orange: - type: boolean - partner_id: - type: string - type: object models.Response: properties: data: {} @@ -429,12 +435,7 @@ paths: "200": description: OK schema: - allOf: - - $ref: '#/definitions/models.Response' - - properties: - data: - $ref: '#/definitions/models.RecordRequest' - type: object + $ref: '#/definitions/models.Response' "400": description: Bad Request schema: -- cgit v1.2.3 From 41529b1d6938c52fcbc52aa50a186a0d368d70e5 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 29 Jun 2023 18:57:39 +0300 Subject: feat: return back to single map summary edit Former-commit-id: 853dd376267ea63e67b1e4e7041f4c5c5f1be380 --- backend/controllers/modController.go | 45 ++++++++++++++++-------------------- backend/models/requests.go | 19 +++++++-------- 2 files changed, 28 insertions(+), 36 deletions(-) (limited to 'backend/models/requests.go') diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index 7c258ef..5fe0f68 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -55,34 +55,29 @@ func EditMapSummary(c *gin.Context) { return } defer tx.Rollback() - if request.Image != "" { - tx.Exec(`UPDATE maps m SET image = $2 WHERE m.id = $1`, mapID, request.Image) - } - for _, route := range request.Routes { - // Fetch route category and score count - var categoryID, scoreCount int - sql := `SELECT mr.category_id, mr.score_count + // Fetch route category and score count + var categoryID, scoreCount int + sql := `SELECT mr.category_id, mr.score_count FROM map_routes mr INNER JOIN maps m WHERE m.id = $1 AND mr.id = $2` - err = database.DB.QueryRow(sql, mapID, route.RouteID).Scan(&categoryID, &scoreCount) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - // Update database with new data - sql = `UPDATE map_routes SET score_count = $2, description = $3, showcase = $4 WHERE id = $1` - _, err = tx.Exec(sql, route.RouteID, route.ScoreCount, route.Description, route.Showcase) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - sql = `UPDATE map_history SET user_name = $3, score_count = $4, record_date = $5 WHERE map_id = $1 AND category_id = $2` - _, err = tx.Exec(sql, mapID, categoryID, route.UserName, route.ScoreCount, route.RecordDate) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } + err = database.DB.QueryRow(sql, mapID, request.RouteID).Scan(&categoryID, &scoreCount) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Update database with new data + sql = `UPDATE map_routes SET score_count = $2, description = $3, showcase = $4 WHERE id = $1` + _, err = tx.Exec(sql, request.RouteID, request.ScoreCount, request.Description, request.Showcase) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + sql = `UPDATE map_history SET user_name = $3, score_count = $4, record_date = $5 WHERE map_id = $1 AND category_id = $2` + _, err = tx.Exec(sql, mapID, categoryID, request.UserName, request.ScoreCount, request.RecordDate) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return } if err = tx.Commit(); err != nil { c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) diff --git a/backend/models/requests.go b/backend/models/requests.go index 7a00567..767b4d8 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -5,12 +5,16 @@ import ( "time" ) -type EditMapSummaryRequest struct { - Image string `json:"image" binding:"required"` - Routes []EditMapSummaryRequestDetails `json:"routes" binding:"dive"` +type CreateMapSummaryRequest struct { + CategoryID int `json:"category_id" binding:"required"` + Description string `json:"description" binding:"required"` + Showcase string `json:"showcase" binding:"required"` + UserName string `json:"user_name" binding:"required"` + ScoreCount int `json:"score_count" binding:"required"` + RecordDate time.Time `json:"record_date" binding:"required"` } -type EditMapSummaryRequestDetails struct { +type EditMapSummaryRequest struct { RouteID int `json:"route_id" binding:"required"` Description string `json:"description" binding:"required"` Showcase string `json:"showcase" binding:"required"` @@ -19,13 +23,6 @@ type EditMapSummaryRequestDetails struct { RecordDate time.Time `json:"record_date" binding:"required"` } -type CreateMapHistoryRequest struct { - CategoryID int `json:"category_id" binding:"required"` - UserName string `json:"user_name" binding:"required"` - ScoreCount int `json:"score_count" binding:"required"` - RecordDate time.Time `json:"record_date" binding:"required"` -} - type RecordRequest struct { HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` -- cgit v1.2.3 From f9ebd85d20cfa794468f9b07b4b781bcd6b686ab Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 29 Jun 2023 19:34:25 +0300 Subject: feat: delete map summary Former-commit-id: bd5bc84fc142f44bfa3c1c1ddc35e435a3f816bf --- backend/controllers/modController.go | 91 +++++++++++++++++++++++++++++++++++- backend/models/requests.go | 4 ++ 2 files changed, 94 insertions(+), 1 deletion(-) (limited to 'backend/models/requests.go') diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index 75be112..9398b2c 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -89,7 +89,7 @@ func CreateMapSummary(c *gin.Context) { // Return response c.JSON(http.StatusOK, models.Response{ Success: true, - Message: "Successfully updated map summary.", + Message: "Successfully created map summary.", Data: request, }) } @@ -175,3 +175,92 @@ func EditMapSummary(c *gin.Context) { Data: request, }) } + +// DELETE Map Summary +// +// @Summary Delete map summary with specified map id. +// @Tags maps +// @Produce json +// @Param id path int true "Map ID" +// @Param request body models.DeleteMapSummaryRequest true "Body" +// @Success 200 {object} models.Response{data=models.DeleteMapSummaryRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [post] +func DeleteMapSummary(c *gin.Context) { + // Check if user exists + user, exists := c.Get("user") + if !exists { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) + return + } + var moderator bool + for _, title := range user.(models.User).Titles { + if title == "Moderator" { + moderator = true + } + } + if !moderator { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("Insufficient permissions.")) + return + } + // Bind parameter and body + id := c.Param("id") + mapID, err := strconv.Atoi(id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + var request models.DeleteMapSummaryRequest + if err := c.BindJSON(&request); err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Start database transaction + tx, err := database.DB.Begin() + if err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) + return + } + defer tx.Rollback() + // Fetch route category and score count + var checkMapID, scoreCount, mapHistoryID int + sql := `SELECT m.id, mr.score_count FROM maps m INNER JOIN map_routes mr ON m.id=mr.map_id WHERE m.id = $1 AND mr.id = $2` + err = database.DB.QueryRow(sql, mapID, request.RouteID).Scan(&checkMapID, &scoreCount) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + if mapID != checkMapID { + c.JSON(http.StatusBadRequest, models.ErrorResponse("Map ID does not exist.")) + return + } + sql = `SELECT mh.id FROM maps m INNER JOIN map_routes mr ON m.id=mr.map_id INNER JOIN map_history mh ON m.id=mh.map_id WHERE m.id = $1 AND mr.id = $2 AND mh.score_count = $3` + err = database.DB.QueryRow(sql, mapID, request.RouteID, scoreCount).Scan(&mapHistoryID) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Update database with new data + sql = `DELETE FROM map_routes mr WHERE mr.id = $1 ` + _, err = tx.Exec(sql, request.RouteID) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + sql = `DELETE FROM map_history mh WHERE mh.id = $1` + _, err = tx.Exec(sql, mapHistoryID) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + if err = tx.Commit(); err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) + return + } + // Return response + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully delete map summary.", + Data: request, + }) +} diff --git a/backend/models/requests.go b/backend/models/requests.go index 767b4d8..f275203 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -23,6 +23,10 @@ type EditMapSummaryRequest struct { RecordDate time.Time `json:"record_date" binding:"required"` } +type DeleteMapSummaryRequest struct { + RouteID int `json:"route_id" binding:"required"` +} + type RecordRequest struct { HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` -- cgit v1.2.3 From 311a039edc8f91666c8d05acd94aabab20833ffe Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:26:24 +0300 Subject: feat: edit map image Former-commit-id: 288e6772dda69a9543a01db85069c95476addd4e --- backend/controllers/modController.go | 55 ++++++++++++++++++ backend/models/requests.go | 4 ++ backend/routes/routes.go | 1 + docs/docs.go | 104 ++++++++++++++++++++++++++++++++++- docs/swagger.json | 104 ++++++++++++++++++++++++++++++++++- docs/swagger.yaml | 63 ++++++++++++++++++++- 6 files changed, 328 insertions(+), 3 deletions(-) (limited to 'backend/models/requests.go') diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index ff79e3e..98fb165 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -264,3 +264,58 @@ func DeleteMapSummary(c *gin.Context) { Data: request, }) } + +// PUT Map Image +// +// @Description Edit map image with specified map id. +// @Tags maps +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param id path int true "Map ID" +// @Param request body models.EditMapImageRequest true "Body" +// @Success 200 {object} models.Response{data=models.EditMapImageRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/image [put] +func EditMapImage(c *gin.Context) { + // Check if user exists + user, exists := c.Get("user") + if !exists { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) + return + } + var moderator bool + for _, title := range user.(models.User).Titles { + if title == "Moderator" { + moderator = true + } + } + if !moderator { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("Insufficient permissions.")) + return + } + // Bind parameter and body + id := c.Param("id") + mapID, err := strconv.Atoi(id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + var request models.EditMapImageRequest + if err := c.BindJSON(&request); err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Update database with new data + sql := `UPDATE maps SET image = $2 WHERE id = $1` + _, err = database.DB.Exec(sql, mapID, request.Image) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Return response + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully updated map image.", + Data: request, + }) +} diff --git a/backend/models/requests.go b/backend/models/requests.go index f275203..fac05b6 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -27,6 +27,10 @@ type DeleteMapSummaryRequest struct { RouteID int `json:"route_id" binding:"required"` } +type EditMapImageRequest struct { + Image string `json:"image" binding:"required"` +} + type RecordRequest struct { HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` diff --git a/backend/routes/routes.go b/backend/routes/routes.go index a39c8c4..1377d32 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -29,6 +29,7 @@ func InitRoutes(router *gin.Engine) { v1.POST("/maps/:id/summary", middleware.CheckAuth, controllers.CreateMapSummary) v1.PUT("/maps/:id/summary", middleware.CheckAuth, controllers.EditMapSummary) v1.DELETE("/maps/:id/summary", middleware.CheckAuth, controllers.DeleteMapSummary) + v1.PUT("/maps/:id/image", middleware.CheckAuth, controllers.EditMapImage) v1.GET("/maps/:id/leaderboards", controllers.FetchMapLeaderboards) v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) v1.GET("/rankings", controllers.Rankings) diff --git a/docs/docs.go b/docs/docs.go index 57984f4..13d4cf6 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -229,6 +229,68 @@ const docTemplate = `{ } } }, + "/maps/{id}/image": { + "put": { + "description": "Edit map image with specified map id.", + "produces": [ + "application/json" + ], + "tags": [ + "maps" + ], + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Map ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/maps/{id}/leaderboards": { "get": { "description": "Get map leaderboards with specified id.", @@ -344,7 +406,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.Response" + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.RecordResponse" + } + } + } + ] } }, "400": { @@ -1047,6 +1121,17 @@ const docTemplate = `{ } } }, + "models.EditMapImageRequest": { + "type": "object", + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string" + } + } + }, "models.EditMapSummaryRequest": { "type": "object", "required": [ @@ -1084,6 +1169,9 @@ const docTemplate = `{ "id": { "type": "integer" }, + "is_coop": { + "type": "boolean" + }, "name": { "type": "string" } @@ -1112,6 +1200,9 @@ const docTemplate = `{ "image": { "type": "string" }, + "is_coop": { + "type": "boolean" + }, "map_name": { "type": "string" } @@ -1242,6 +1333,17 @@ const docTemplate = `{ } } }, + "models.RecordResponse": { + "type": "object", + "properties": { + "score_count": { + "type": "integer" + }, + "score_time": { + "type": "integer" + } + } + }, "models.Response": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index ef422ab..f644288 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -222,6 +222,68 @@ } } }, + "/maps/{id}/image": { + "put": { + "description": "Edit map image with specified map id.", + "produces": [ + "application/json" + ], + "tags": [ + "maps" + ], + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Map ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/maps/{id}/leaderboards": { "get": { "description": "Get map leaderboards with specified id.", @@ -337,7 +399,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.Response" + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.RecordResponse" + } + } + } + ] } }, "400": { @@ -1040,6 +1114,17 @@ } } }, + "models.EditMapImageRequest": { + "type": "object", + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string" + } + } + }, "models.EditMapSummaryRequest": { "type": "object", "required": [ @@ -1077,6 +1162,9 @@ "id": { "type": "integer" }, + "is_coop": { + "type": "boolean" + }, "name": { "type": "string" } @@ -1105,6 +1193,9 @@ "image": { "type": "string" }, + "is_coop": { + "type": "boolean" + }, "map_name": { "type": "string" } @@ -1235,6 +1326,17 @@ } } }, + "models.RecordResponse": { + "type": "object", + "properties": { + "score_count": { + "type": "integer" + }, + "score_time": { + "type": "integer" + } + } + }, "models.Response": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 2fed413..3b706ea 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -61,6 +61,13 @@ definitions: required: - route_id type: object + models.EditMapImageRequest: + properties: + image: + type: string + required: + - image + type: object models.EditMapSummaryRequest: properties: description: @@ -87,6 +94,8 @@ definitions: properties: id: type: integer + is_coop: + type: boolean name: type: string type: object @@ -105,6 +114,8 @@ definitions: type: integer image: type: string + is_coop: + type: boolean map_name: type: string type: object @@ -189,6 +200,13 @@ definitions: $ref: '#/definitions/models.UserRanking' type: array type: object + models.RecordResponse: + properties: + score_count: + type: integer + score_time: + type: integer + type: object models.Response: properties: data: {} @@ -364,6 +382,44 @@ paths: $ref: '#/definitions/models.Response' tags: - login + /maps/{id}/image: + put: + description: Edit map image with specified map id. + parameters: + - description: JWT Token + in: header + name: Authorization + required: true + type: string + - description: Map ID + in: path + name: id + required: true + type: integer + - description: Body + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.EditMapImageRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/models.Response' + - properties: + data: + $ref: '#/definitions/models.EditMapImageRequest' + type: object + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Response' + tags: + - maps /maps/{id}/leaderboards: get: description: Get map leaderboards with specified id. @@ -435,7 +491,12 @@ paths: "200": description: OK schema: - $ref: '#/definitions/models.Response' + allOf: + - $ref: '#/definitions/models.Response' + - properties: + data: + $ref: '#/definitions/models.RecordResponse' + type: object "400": description: Bad Request schema: -- cgit v1.2.3 From 5e8b4791a06c8fa00e56f4d043d25d00ef003c76 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 12 Jul 2023 18:44:40 +0300 Subject: fix: 0 score count / showcase not required (#47) Former-commit-id: 2a1cea87348e0af8d97512a46093bd38768257ef --- backend/models/requests.go | 8 ++++---- docs/docs.go | 2 -- docs/swagger.json | 2 -- docs/swagger.yaml | 2 -- 4 files changed, 4 insertions(+), 10 deletions(-) (limited to 'backend/models/requests.go') diff --git a/backend/models/requests.go b/backend/models/requests.go index fac05b6..0113597 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -8,18 +8,18 @@ import ( type CreateMapSummaryRequest struct { CategoryID int `json:"category_id" binding:"required"` Description string `json:"description" binding:"required"` - Showcase string `json:"showcase" binding:"required"` + Showcase string `json:"showcase"` UserName string `json:"user_name" binding:"required"` - ScoreCount int `json:"score_count" binding:"required"` + ScoreCount *int `json:"score_count" binding:"required"` RecordDate time.Time `json:"record_date" binding:"required"` } type EditMapSummaryRequest struct { RouteID int `json:"route_id" binding:"required"` Description string `json:"description" binding:"required"` - Showcase string `json:"showcase" binding:"required"` + Showcase string `json:"showcase"` UserName string `json:"user_name" binding:"required"` - ScoreCount int `json:"score_count" binding:"required"` + ScoreCount *int `json:"score_count" binding:"required"` RecordDate time.Time `json:"record_date" binding:"required"` } diff --git a/docs/docs.go b/docs/docs.go index 13d4cf6..423afad 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1086,7 +1086,6 @@ const docTemplate = `{ "description", "record_date", "score_count", - "showcase", "user_name" ], "properties": { @@ -1139,7 +1138,6 @@ const docTemplate = `{ "record_date", "route_id", "score_count", - "showcase", "user_name" ], "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index f644288..2e1a789 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1079,7 +1079,6 @@ "description", "record_date", "score_count", - "showcase", "user_name" ], "properties": { @@ -1132,7 +1131,6 @@ "record_date", "route_id", "score_count", - "showcase", "user_name" ], "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 3b706ea..7571073 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -51,7 +51,6 @@ definitions: - description - record_date - score_count - - showcase - user_name type: object models.DeleteMapSummaryRequest: @@ -87,7 +86,6 @@ definitions: - record_date - route_id - score_count - - showcase - user_name type: object models.Game: -- cgit v1.2.3