From 0a2c6021e36be31aaffe8ace232179e2211b3140 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Tue, 2 May 2023 23:25:48 +0300 Subject: feat: game, chapter, map endpoints for records page --- docs/docs.go | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 222 insertions(+), 6 deletions(-) (limited to 'docs/docs.go') diff --git a/docs/docs.go b/docs/docs.go index 22d4362..788ca3d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -20,6 +20,55 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/chapters/{id}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "chapters" + ], + "summary": "Get chapters from the specified game id.", + "parameters": [ + { + "type": "integer", + "description": "Game ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Chapter" + } + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/demo": { "get": { "produces": [ @@ -94,6 +143,46 @@ const docTemplate = `{ } } }, + "/games": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "games" + ], + "summary": "Get games from the leaderboards.", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Game" + } + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/login": { "get": { "consumes": [ @@ -134,11 +223,57 @@ const docTemplate = `{ } } }, - "/maps/{id}/leaderboards": { + "/maps/{id}": { "get": { - "consumes": [ + "produces": [ "application/json" ], + "tags": [ + "maps" + ], + "summary": "Get maps from the specified chapter id.", + "parameters": [ + { + "type": "integer", + "description": "Chapter ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.MapShort" + } + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, + "/maps/{id}/leaderboards": { + "get": { "produces": [ "application/json" ], @@ -290,9 +425,6 @@ const docTemplate = `{ }, "/maps/{id}/summary": { "get": { - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], @@ -530,7 +662,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.Response" + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.SearchResponse" + } + } + } + ] } }, "400": { @@ -599,6 +743,31 @@ const docTemplate = `{ } }, "definitions": { + "models.Chapter": { + "type": "object", + "properties": { + "game_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "models.Game": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "models.LoginResponse": { "type": "object", "properties": { @@ -662,6 +831,20 @@ const docTemplate = `{ "records": {} } }, + "models.MapShort": { + "type": "object", + "properties": { + "chapter_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "models.MapSummary": { "type": "object", "properties": { @@ -784,6 +967,39 @@ const docTemplate = `{ "records": {} } }, + "models.SearchResponse": { + "type": "object", + "properties": { + "maps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + } + }, + "players": { + "type": "array", + "items": { + "type": "object", + "properties": { + "steam_id": { + "type": "string" + }, + "user_name": { + "type": "string" + } + } + } + } + } + }, "models.UserRanking": { "type": "object", "properties": { -- cgit v1.2.3 From 4b87005639dabaf84f50084df7a02812676a733c Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Tue, 2 May 2023 23:36:21 +0300 Subject: feat: add path request to the response with names --- backend/controllers/mapController.go | 26 +++++++++++++++++--------- backend/models/models.go | 20 ++++++++++++++------ docs/docs.go | 25 +++++++++++++++---------- docs/swagger.json | 25 +++++++++++++++---------- docs/swagger.yaml | 17 ++++++++++------- 5 files changed, 71 insertions(+), 42 deletions(-) (limited to 'docs/docs.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 2bf1fdc..506daa2 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -250,7 +250,7 @@ func FetchGames(c *gin.Context) { // @Tags chapters // @Produce json // @Param id path int true "Game ID" -// @Success 200 {object} models.Response{data=[]models.Chapter} +// @Success 200 {object} models.Response{data=models.ChaptersResponse} // @Failure 400 {object} models.Response // @Router /chapters/{id} [get] func FetchChapters(c *gin.Context) { @@ -260,25 +260,29 @@ func FetchChapters(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - rows, err := database.DB.Query(`SELECT id, name FROM chapters WHERE game_id = $1`, gameID) + var response models.ChaptersResponse + rows, err := database.DB.Query(`SELECT c.id, c.name, g.name FROM chapters c INNER JOIN games g ON c.game_id = g.id WHERE game_id = $1`, gameID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } var chapters []models.Chapter + var gameName string for rows.Next() { var chapter models.Chapter - if err := rows.Scan(&chapter.ID, &chapter.Name); err != nil { + if err := rows.Scan(&chapter.ID, &chapter.Name, &gameName); err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - chapter.GameID = intID chapters = append(chapters, chapter) } + response.Game.ID = intID + response.Game.Name = gameName + response.Chapters = chapters c.JSON(http.StatusOK, models.Response{ Success: true, Message: "Successfully retrieved chapters.", - Data: chapters, + Data: response, }) } @@ -298,24 +302,28 @@ func FetchChapterMaps(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - rows, err := database.DB.Query(`SELECT id, name FROM maps WHERE chapter_id = $1`, chapterID) + var response models.ChapterMapsResponse + rows, err := database.DB.Query(`SELECT m.id, m.name, c.name FROM maps m INNER JOIN chapters c ON m.chapter_id = c.id WHERE chapter_id = $1`, chapterID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } var maps []models.MapShort + var chapterName string for rows.Next() { var mapShort models.MapShort - if err := rows.Scan(&mapShort.ID, &mapShort.Name); err != nil { + if err := rows.Scan(&mapShort.ID, &mapShort.Name, &chapterName); err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - mapShort.ChapterID = intID maps = append(maps, mapShort) } + response.Chapter.ID = intID + response.Chapter.Name = chapterName + response.Maps = maps c.JSON(http.StatusOK, models.Response{ Success: true, Message: "Successfully retrieved maps.", - Data: maps, + Data: response, }) } diff --git a/backend/models/models.go b/backend/models/models.go index 8f77a93..6f5173a 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -158,16 +158,24 @@ type Game struct { Name string `json:"name"` } +type ChaptersResponse struct { + Game Game `json:"game"` + Chapters []Chapter `json:"chapters"` +} + type Chapter struct { - ID int `json:"id"` - GameID int `json:"game_id"` - Name string `json:"name"` + ID int `json:"id"` + Name string `json:"name"` } type MapShort struct { - ID int `json:"id"` - ChapterID int `json:"chapter_id"` - Name string `json:"name"` + ID int `json:"id"` + Name string `json:"name"` +} + +type ChapterMapsResponse struct { + Chapter Chapter `json:"chapter"` + Maps []MapShort `json:"maps"` } func ErrorResponse(message string) Response { diff --git a/docs/docs.go b/docs/docs.go index 788ca3d..164db20 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -50,10 +50,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.Chapter" - } + "$ref": "#/definitions/models.ChaptersResponse" } } } @@ -746,9 +743,6 @@ const docTemplate = `{ "models.Chapter": { "type": "object", "properties": { - "game_id": { - "type": "integer" - }, "id": { "type": "integer" }, @@ -757,6 +751,20 @@ const docTemplate = `{ } } }, + "models.ChaptersResponse": { + "type": "object", + "properties": { + "chapters": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Chapter" + } + }, + "game": { + "$ref": "#/definitions/models.Game" + } + } + }, "models.Game": { "type": "object", "properties": { @@ -834,9 +842,6 @@ const docTemplate = `{ "models.MapShort": { "type": "object", "properties": { - "chapter_id": { - "type": "integer" - }, "id": { "type": "integer" }, diff --git a/docs/swagger.json b/docs/swagger.json index ba0e8a3..653d52f 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -43,10 +43,7 @@ "type": "object", "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.Chapter" - } + "$ref": "#/definitions/models.ChaptersResponse" } } } @@ -739,9 +736,6 @@ "models.Chapter": { "type": "object", "properties": { - "game_id": { - "type": "integer" - }, "id": { "type": "integer" }, @@ -750,6 +744,20 @@ } } }, + "models.ChaptersResponse": { + "type": "object", + "properties": { + "chapters": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Chapter" + } + }, + "game": { + "$ref": "#/definitions/models.Game" + } + } + }, "models.Game": { "type": "object", "properties": { @@ -827,9 +835,6 @@ "models.MapShort": { "type": "object", "properties": { - "chapter_id": { - "type": "integer" - }, "id": { "type": "integer" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 8b66ec8..88f2d7f 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2,13 +2,20 @@ basePath: /v1 definitions: models.Chapter: properties: - game_id: - type: integer id: type: integer name: type: string type: object + models.ChaptersResponse: + properties: + chapters: + items: + $ref: '#/definitions/models.Chapter' + type: array + game: + $ref: '#/definitions/models.Game' + type: object models.Game: properties: id: @@ -59,8 +66,6 @@ definitions: type: object models.MapShort: properties: - chapter_id: - type: integer id: type: integer name: @@ -205,9 +210,7 @@ paths: - $ref: '#/definitions/models.Response' - properties: data: - items: - $ref: '#/definitions/models.Chapter' - type: array + $ref: '#/definitions/models.ChaptersResponse' type: object "400": description: Bad Request -- cgit v1.2.3 From 937160bfda2c8edc5ff5dd73899b517bb0ceb515 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 3 May 2023 16:05:30 +0300 Subject: fix: sql typos, routing change --- backend/controllers/homeController.go | 10 ++--- backend/controllers/mapController.go | 22 +++++------ backend/controllers/recordController.go | 12 +++--- backend/controllers/userController.go | 14 +++---- backend/middleware/auth.go | 2 +- backend/routes/routes.go | 4 +- docs/docs.go | 67 +++++++++++++++++++-------------- docs/swagger.json | 67 +++++++++++++++++++-------------- docs/swagger.yaml | 53 +++++++++++++++----------- 9 files changed, 140 insertions(+), 111 deletions(-) (limited to 'docs/docs.go') diff --git a/backend/controllers/homeController.go b/backend/controllers/homeController.go index 206e3ae..edb770f 100644 --- a/backend/controllers/homeController.go +++ b/backend/controllers/homeController.go @@ -29,7 +29,7 @@ func Home(c *gin.Context) { // @Failure 400 {object} models.Response // @Router /demo [get] func Rankings(c *gin.Context) { - rows, err := database.DB.Query(`SELECT steam_id, user_name FROM users;`) + rows, err := database.DB.Query(`SELECT steam_id, user_name FROM users`) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return @@ -46,7 +46,7 @@ func Rankings(c *gin.Context) { // Getting all sp records for each user var uniqueSingleUserRecords, totalSingleMaps int sql := `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps - WHERE is_coop = FALSE AND is_disabled = false) FROM records_sp WHERE user_id = $1;` + WHERE is_coop = FALSE AND is_disabled = false) FROM records_sp WHERE user_id = $1` err = database.DB.QueryRow(sql, userID).Scan(&uniqueSingleUserRecords, &totalSingleMaps) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -57,7 +57,7 @@ func Rankings(c *gin.Context) { var ranking models.UserRanking ranking.UserID = userID ranking.UserName = username - sql := `SELECT DISTINCT map_id, score_count FROM records_sp WHERE user_id = $1 ORDER BY map_id, score_count;` + sql := `SELECT DISTINCT map_id, score_count FROM records_sp WHERE user_id = $1 ORDER BY map_id, score_count` rows, err := database.DB.Query(sql, userID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -80,7 +80,7 @@ func Rankings(c *gin.Context) { // Getting all mp records for each user var uniqueMultiUserRecords, totalMultiMaps int sql = `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps - WHERE is_coop = TRUE AND is_disabled = false) FROM records_mp WHERE host_id = $1 OR partner_id = $2;` + WHERE is_coop = TRUE AND is_disabled = false) FROM records_mp WHERE host_id = $1 OR partner_id = $2` err = database.DB.QueryRow(sql, userID, userID).Scan(&uniqueMultiUserRecords, &totalMultiMaps) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -91,7 +91,7 @@ func Rankings(c *gin.Context) { var ranking models.UserRanking ranking.UserID = userID ranking.UserName = username - sql := `SELECT DISTINCT map_id, score_count FROM records_mp WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id, score_count;` + sql := `SELECT DISTINCT map_id, score_count FROM records_mp WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id, score_count` rows, err := database.DB.Query(sql, userID, userID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 506daa2..d8783b7 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -56,7 +56,7 @@ func FetchMapSummary(c *gin.Context) { FROM maps m INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id - WHERE m.id = $1;` + WHERE m.id = $1` // TODO: CategoryScores err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &mapSummaryData.Description, &mapSummaryData.Showcase, &routers, &mapSummaryData.Rating) if err != nil { @@ -68,7 +68,7 @@ func FetchMapSummary(c *gin.Context) { var historyDates pq.StringArray sql = `SELECT array_agg(user_name), array_agg(score_count), array_agg(record_date) FROM map_history - WHERE map_id = $1;` + WHERE map_id = $1` err = database.DB.QueryRow(sql, id).Scan(&historyNames, &historyScores, &historyDates) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -123,7 +123,7 @@ func FetchMapLeaderboards(c *gin.Context) { FROM maps m INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id - WHERE m.id = $1;` + WHERE m.id = $1` err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &isDisabled) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -144,7 +144,7 @@ func FetchMapLeaderboards(c *gin.Context) { FROM records_mp WHERE map_id = $1 ) sub - WHERE rn = 1;` + WHERE rn = 1` rows, err := database.DB.Query(sql, id) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -179,7 +179,7 @@ func FetchMapLeaderboards(c *gin.Context) { WHERE map_id = $1 ) sub INNER JOIN users ON user_id = users.steam_id - WHERE rn = 1;` + WHERE rn = 1` rows, err := database.DB.Query(sql, id) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -217,7 +217,7 @@ func FetchMapLeaderboards(c *gin.Context) { // GET Games // // @Summary Get games from the leaderboards. -// @Tags games +// @Tags games & chapters // @Produce json // @Success 200 {object} models.Response{data=[]models.Game} // @Failure 400 {object} models.Response @@ -247,12 +247,12 @@ func FetchGames(c *gin.Context) { // GET Chapters of a Game // // @Summary Get chapters from the specified game id. -// @Tags chapters +// @Tags games & chapters // @Produce json // @Param id path int true "Game ID" // @Success 200 {object} models.Response{data=models.ChaptersResponse} // @Failure 400 {object} models.Response -// @Router /chapters/{id} [get] +// @Router /games/{id} [get] func FetchChapters(c *gin.Context) { gameID := c.Param("id") intID, err := strconv.Atoi(gameID) @@ -289,12 +289,12 @@ func FetchChapters(c *gin.Context) { // GET Maps of a Chapter // // @Summary Get maps from the specified chapter id. -// @Tags maps +// @Tags games & chapters // @Produce json // @Param id path int true "Chapter ID" -// @Success 200 {object} models.Response{data=[]models.MapShort} +// @Success 200 {object} models.Response{data=models.ChapterMapsResponse} // @Failure 400 {object} models.Response -// @Router /maps/{id} [get] +// @Router /chapters/{id} [get] func FetchChapterMaps(c *gin.Context) { chapterID := c.Param("id") intID, err := strconv.Atoi(chapterID) diff --git a/backend/controllers/recordController.go b/backend/controllers/recordController.go index bafa844..627be57 100644 --- a/backend/controllers/recordController.go +++ b/backend/controllers/recordController.go @@ -46,7 +46,7 @@ func CreateRecordWithDemo(c *gin.Context) { var gameID int var isCoop bool var isDisabled bool - sql := `SELECT game_id, is_disabled FROM maps WHERE id = $1;` + sql := `SELECT game_id, is_disabled FROM maps WHERE id = $1` err := database.DB.QueryRow(sql, mapId).Scan(&gameID, &isDisabled) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -153,7 +153,7 @@ func CreateRecordWithDemo(c *gin.Context) { // Insert into records if isCoop { sql := `INSERT INTO records_mp(map_id,score_count,score_time,host_id,partner_id,host_demo_id,partner_demo_id) - VALUES($1, $2, $3, $4, $5, $6, $7);` + VALUES($1, $2, $3, $4, $5, $6, $7)` var hostID string var partnerID string if record.IsPartnerOrange { @@ -171,7 +171,7 @@ func CreateRecordWithDemo(c *gin.Context) { } // If a new world record based on portal count // if record.ScoreCount < wrScore { - // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3;`, record.ScoreCount, record.ScoreTime, mapId) + // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3`, record.ScoreCount, record.ScoreTime, mapId) // if err != nil { // c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) // return @@ -179,7 +179,7 @@ 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);` + VALUES($1, $2, $3, $4, $5)` _, err := tx.Exec(sql, mapId, record.ScoreCount, record.ScoreTime, user.(models.User).SteamID, hostDemoUUID) if err != nil { deleteFile(srv, fileID) @@ -188,7 +188,7 @@ func CreateRecordWithDemo(c *gin.Context) { } // If a new world record based on portal count // if record.ScoreCount < wrScore { - // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3;`, record.ScoreCount, record.ScoreTime, mapId) + // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3`, record.ScoreCount, record.ScoreTime, mapId) // if err != nil { // c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) // return @@ -224,7 +224,7 @@ func DownloadDemoWithID(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse("Invalid id given.")) return } - err := database.DB.QueryRow(`SELECT location_id FROM demos WHERE id = $1;`, uuid).Scan(&locationID) + err := database.DB.QueryRow(`SELECT location_id FROM demos WHERE id = $1`, uuid).Scan(&locationID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return diff --git a/backend/controllers/userController.go b/backend/controllers/userController.go index 5ad800d..adf936b 100644 --- a/backend/controllers/userController.go +++ b/backend/controllers/userController.go @@ -31,7 +31,7 @@ func Profile(c *gin.Context) { } // Retrieve singleplayer records var scoresSP []models.ScoreResponse - sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id;` + sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id` rows, err := database.DB.Query(sql, user.(models.User).SteamID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -58,7 +58,7 @@ func Profile(c *gin.Context) { // Retrieve multiplayer records var scoresMP []models.ScoreResponse sql = `SELECT id, map_id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date FROM records_mp - WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id;` + WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id` rows, err = database.DB.Query(sql, user.(models.User).SteamID, user.(models.User).SteamID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -119,7 +119,7 @@ func FetchUser(c *gin.Context) { } // Check if user exists var user models.User - err := database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1;`, id).Scan( + err := database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1`, id).Scan( &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt) if user.SteamID == "" { @@ -133,7 +133,7 @@ func FetchUser(c *gin.Context) { } // Retrieve singleplayer records var scoresSP []models.ScoreResponse - sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id;` + sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id` rows, err := database.DB.Query(sql, user.SteamID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -160,7 +160,7 @@ func FetchUser(c *gin.Context) { // Retrieve multiplayer records var scoresMP []models.ScoreResponse sql = `SELECT id, map_id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date FROM records_mp - WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id;` + WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id` rows, err = database.DB.Query(sql, user.SteamID, user.SteamID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) @@ -225,7 +225,7 @@ func UpdateUser(c *gin.Context) { } // Update profile _, err = database.DB.Exec(`UPDATE users SET username = $1, avatar_link = $2, country_code = $3, updated_at = $4 - WHERE steam_id = $5;`, profile.PersonaName, profile.AvatarFull, profile.LocCountryCode, time.Now().UTC(), user.(models.User).SteamID) + WHERE steam_id = $5`, profile.PersonaName, profile.AvatarFull, profile.LocCountryCode, time.Now().UTC(), user.(models.User).SteamID) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return @@ -268,7 +268,7 @@ func UpdateCountryCode(c *gin.Context) { return } var validCode string - err := database.DB.QueryRow(`SELECT country_code FROM countries WHERE country_code = $1;`, code).Scan(&validCode) + err := database.DB.QueryRow(`SELECT country_code FROM countries WHERE country_code = $1`, code).Scan(&validCode) if err != nil { c.JSON(http.StatusNotFound, models.ErrorResponse(err.Error())) return diff --git a/backend/middleware/auth.go b/backend/middleware/auth.go index cd00a30..14a0b78 100644 --- a/backend/middleware/auth.go +++ b/backend/middleware/auth.go @@ -36,7 +36,7 @@ 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 * FROM users WHERE steam_id = $1`, claims["sub"]).Scan( &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt) if user.SteamID == "" { diff --git a/backend/routes/routes.go b/backend/routes/routes.go index 2741208..2554fa4 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -26,10 +26,10 @@ func InitRoutes(router *gin.Engine) { v1.GET("/maps/:id/summary", middleware.CheckAuth, controllers.FetchMapSummary) v1.GET("/maps/:id/leaderboards", middleware.CheckAuth, controllers.FetchMapLeaderboards) v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) - v1.GET("/maps/:id", controllers.FetchChapterMaps) v1.GET("/rankings", middleware.CheckAuth, controllers.Rankings) v1.GET("/search", controllers.Search) v1.GET("/games", controllers.FetchGames) - v1.GET("/chapters/:id", controllers.FetchChapters) + v1.GET("/games/:id", controllers.FetchChapters) + v1.GET("/chapters/:id", controllers.FetchChapterMaps) } } diff --git a/docs/docs.go b/docs/docs.go index 164db20..cd129f0 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -26,13 +26,13 @@ const docTemplate = `{ "application/json" ], "tags": [ - "chapters" + "games \u0026 chapters" ], - "summary": "Get chapters from the specified game id.", + "summary": "Get maps from the specified chapter id.", "parameters": [ { "type": "integer", - "description": "Game ID", + "description": "Chapter ID", "name": "id", "in": "path", "required": true @@ -50,7 +50,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/models.ChaptersResponse" + "$ref": "#/definitions/models.ChapterMapsResponse" } } } @@ -146,7 +146,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "games" + "games \u0026 chapters" ], "summary": "Get games from the leaderboards.", "responses": { @@ -180,18 +180,24 @@ const docTemplate = `{ } } }, - "/login": { + "/games/{id}": { "get": { - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], "tags": [ - "login" + "games \u0026 chapters" + ], + "summary": "Get chapters from the specified game id.", + "parameters": [ + { + "type": "integer", + "description": "Game ID", + "name": "id", + "in": "path", + "required": true + } ], - "summary": "Get (redirect) login page for Steam auth.", "responses": { "200": { "description": "OK", @@ -204,7 +210,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/models.LoginResponse" + "$ref": "#/definitions/models.ChaptersResponse" } } } @@ -220,24 +226,18 @@ const docTemplate = `{ } } }, - "/maps/{id}": { + "/login": { "get": { + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "maps" - ], - "summary": "Get maps from the specified chapter id.", - "parameters": [ - { - "type": "integer", - "description": "Chapter ID", - "name": "id", - "in": "path", - "required": true - } + "login" ], + "summary": "Get (redirect) login page for Steam auth.", "responses": { "200": { "description": "OK", @@ -250,10 +250,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.MapShort" - } + "$ref": "#/definitions/models.LoginResponse" } } } @@ -751,6 +748,20 @@ const docTemplate = `{ } } }, + "models.ChapterMapsResponse": { + "type": "object", + "properties": { + "chapter": { + "$ref": "#/definitions/models.Chapter" + }, + "maps": { + "type": "array", + "items": { + "$ref": "#/definitions/models.MapShort" + } + } + } + }, "models.ChaptersResponse": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index 653d52f..442745f 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -19,13 +19,13 @@ "application/json" ], "tags": [ - "chapters" + "games \u0026 chapters" ], - "summary": "Get chapters from the specified game id.", + "summary": "Get maps from the specified chapter id.", "parameters": [ { "type": "integer", - "description": "Game ID", + "description": "Chapter ID", "name": "id", "in": "path", "required": true @@ -43,7 +43,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/models.ChaptersResponse" + "$ref": "#/definitions/models.ChapterMapsResponse" } } } @@ -139,7 +139,7 @@ "application/json" ], "tags": [ - "games" + "games \u0026 chapters" ], "summary": "Get games from the leaderboards.", "responses": { @@ -173,18 +173,24 @@ } } }, - "/login": { + "/games/{id}": { "get": { - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], "tags": [ - "login" + "games \u0026 chapters" + ], + "summary": "Get chapters from the specified game id.", + "parameters": [ + { + "type": "integer", + "description": "Game ID", + "name": "id", + "in": "path", + "required": true + } ], - "summary": "Get (redirect) login page for Steam auth.", "responses": { "200": { "description": "OK", @@ -197,7 +203,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/models.LoginResponse" + "$ref": "#/definitions/models.ChaptersResponse" } } } @@ -213,24 +219,18 @@ } } }, - "/maps/{id}": { + "/login": { "get": { + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "maps" - ], - "summary": "Get maps from the specified chapter id.", - "parameters": [ - { - "type": "integer", - "description": "Chapter ID", - "name": "id", - "in": "path", - "required": true - } + "login" ], + "summary": "Get (redirect) login page for Steam auth.", "responses": { "200": { "description": "OK", @@ -243,10 +243,7 @@ "type": "object", "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.MapShort" - } + "$ref": "#/definitions/models.LoginResponse" } } } @@ -744,6 +741,20 @@ } } }, + "models.ChapterMapsResponse": { + "type": "object", + "properties": { + "chapter": { + "$ref": "#/definitions/models.Chapter" + }, + "maps": { + "type": "array", + "items": { + "$ref": "#/definitions/models.MapShort" + } + } + } + }, "models.ChaptersResponse": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 88f2d7f..fa1a26d 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -7,6 +7,15 @@ definitions: name: type: string type: object + models.ChapterMapsResponse: + properties: + chapter: + $ref: '#/definitions/models.Chapter' + maps: + items: + $ref: '#/definitions/models.MapShort' + type: array + type: object models.ChaptersResponse: properties: chapters: @@ -195,7 +204,7 @@ paths: /chapters/{id}: get: parameters: - - description: Game ID + - description: Chapter ID in: path name: id required: true @@ -210,15 +219,15 @@ paths: - $ref: '#/definitions/models.Response' - properties: data: - $ref: '#/definitions/models.ChaptersResponse' + $ref: '#/definitions/models.ChapterMapsResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get chapters from the specified game id. + summary: Get maps from the specified chapter id. tags: - - chapters + - games & chapters /demo: get: produces: @@ -286,11 +295,15 @@ paths: $ref: '#/definitions/models.Response' summary: Get games from the leaderboards. tags: - - games - /login: + - games & chapters + /games/{id}: get: - consumes: - - application/json + parameters: + - description: Game ID + in: path + name: id + required: true + type: integer produces: - application/json responses: @@ -301,23 +314,19 @@ paths: - $ref: '#/definitions/models.Response' - properties: data: - $ref: '#/definitions/models.LoginResponse' + $ref: '#/definitions/models.ChaptersResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get (redirect) login page for Steam auth. + summary: Get chapters from the specified game id. tags: - - login - /maps/{id}: + - games & chapters + /login: get: - parameters: - - description: Chapter ID - in: path - name: id - required: true - type: integer + consumes: + - application/json produces: - application/json responses: @@ -328,17 +337,15 @@ paths: - $ref: '#/definitions/models.Response' - properties: data: - items: - $ref: '#/definitions/models.MapShort' - type: array + $ref: '#/definitions/models.LoginResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get maps from the specified chapter id. + summary: Get (redirect) login page for Steam auth. tags: - - maps + - login /maps/{id}/leaderboards: get: parameters: -- cgit v1.2.3