aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNidboj132 <lol2s@vp.pl>2023-05-06 16:11:37 +0200
committerGitHub <noreply@github.com>2023-05-06 16:11:37 +0200
commitcbe16bdb713a5d82a7a67a4a2a4f1d49b59663ae (patch)
tree4d04c0cdea26e0e497134b99c0e34a7d9d478f34
parentlogin test (diff)
parentfix: allow credentials cors (diff)
downloadlphub-cbe16bdb713a5d82a7a67a4a2a4f1d49b59663ae.tar.gz
lphub-cbe16bdb713a5d82a7a67a4a2a4f1d49b59663ae.tar.bz2
lphub-cbe16bdb713a5d82a7a67a4a2a4f1d49b59663ae.zip
Merge branch 'pektezol:main' into main
-rw-r--r--backend/controllers/homeController.go10
-rw-r--r--backend/controllers/mapController.go126
-rw-r--r--backend/controllers/recordController.go12
-rw-r--r--backend/controllers/userController.go14
-rw-r--r--backend/middleware/auth.go2
-rw-r--r--backend/models/models.go25
-rw-r--r--backend/routes/routes.go3
-rw-r--r--docs/docs.go246
-rw-r--r--docs/swagger.json246
-rw-r--r--docs/swagger.yaml148
-rw-r--r--main.go9
11 files changed, 794 insertions, 47 deletions
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) {
29// @Failure 400 {object} models.Response 29// @Failure 400 {object} models.Response
30// @Router /demo [get] 30// @Router /demo [get]
31func Rankings(c *gin.Context) { 31func Rankings(c *gin.Context) {
32 rows, err := database.DB.Query(`SELECT steam_id, user_name FROM users;`) 32 rows, err := database.DB.Query(`SELECT steam_id, user_name FROM users`)
33 if err != nil { 33 if err != nil {
34 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 34 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
35 return 35 return
@@ -46,7 +46,7 @@ func Rankings(c *gin.Context) {
46 // Getting all sp records for each user 46 // Getting all sp records for each user
47 var uniqueSingleUserRecords, totalSingleMaps int 47 var uniqueSingleUserRecords, totalSingleMaps int
48 sql := `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps 48 sql := `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps
49 WHERE is_coop = FALSE AND is_disabled = false) FROM records_sp WHERE user_id = $1;` 49 WHERE is_coop = FALSE AND is_disabled = false) FROM records_sp WHERE user_id = $1`
50 err = database.DB.QueryRow(sql, userID).Scan(&uniqueSingleUserRecords, &totalSingleMaps) 50 err = database.DB.QueryRow(sql, userID).Scan(&uniqueSingleUserRecords, &totalSingleMaps)
51 if err != nil { 51 if err != nil {
52 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 52 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -57,7 +57,7 @@ func Rankings(c *gin.Context) {
57 var ranking models.UserRanking 57 var ranking models.UserRanking
58 ranking.UserID = userID 58 ranking.UserID = userID
59 ranking.UserName = username 59 ranking.UserName = username
60 sql := `SELECT DISTINCT map_id, score_count FROM records_sp WHERE user_id = $1 ORDER BY map_id, score_count;` 60 sql := `SELECT DISTINCT map_id, score_count FROM records_sp WHERE user_id = $1 ORDER BY map_id, score_count`
61 rows, err := database.DB.Query(sql, userID) 61 rows, err := database.DB.Query(sql, userID)
62 if err != nil { 62 if err != nil {
63 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 63 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -80,7 +80,7 @@ func Rankings(c *gin.Context) {
80 // Getting all mp records for each user 80 // Getting all mp records for each user
81 var uniqueMultiUserRecords, totalMultiMaps int 81 var uniqueMultiUserRecords, totalMultiMaps int
82 sql = `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps 82 sql = `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps
83 WHERE is_coop = TRUE AND is_disabled = false) FROM records_mp WHERE host_id = $1 OR partner_id = $2;` 83 WHERE is_coop = TRUE AND is_disabled = false) FROM records_mp WHERE host_id = $1 OR partner_id = $2`
84 err = database.DB.QueryRow(sql, userID, userID).Scan(&uniqueMultiUserRecords, &totalMultiMaps) 84 err = database.DB.QueryRow(sql, userID, userID).Scan(&uniqueMultiUserRecords, &totalMultiMaps)
85 if err != nil { 85 if err != nil {
86 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 86 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -91,7 +91,7 @@ func Rankings(c *gin.Context) {
91 var ranking models.UserRanking 91 var ranking models.UserRanking
92 ranking.UserID = userID 92 ranking.UserID = userID
93 ranking.UserName = username 93 ranking.UserName = username
94 sql := `SELECT DISTINCT map_id, score_count FROM records_mp WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id, score_count;` 94 sql := `SELECT DISTINCT map_id, score_count FROM records_mp WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id, score_count`
95 rows, err := database.DB.Query(sql, userID, userID) 95 rows, err := database.DB.Query(sql, userID, userID)
96 if err != nil { 96 if err != nil {
97 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 97 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go
index bd85a97..d8783b7 100644
--- a/backend/controllers/mapController.go
+++ b/backend/controllers/mapController.go
@@ -15,7 +15,6 @@ import (
15// 15//
16// @Summary Get map summary with specified id. 16// @Summary Get map summary with specified id.
17// @Tags maps 17// @Tags maps
18// @Accept json
19// @Produce json 18// @Produce json
20// @Param id path int true "Map ID" 19// @Param id path int true "Map ID"
21// @Success 200 {object} models.Response{data=models.Map{data=models.MapSummary}} 20// @Success 200 {object} models.Response{data=models.Map{data=models.MapSummary}}
@@ -57,7 +56,7 @@ func FetchMapSummary(c *gin.Context) {
57 FROM maps m 56 FROM maps m
58 INNER JOIN games g ON m.game_id = g.id 57 INNER JOIN games g ON m.game_id = g.id
59 INNER JOIN chapters c ON m.chapter_id = c.id 58 INNER JOIN chapters c ON m.chapter_id = c.id
60 WHERE m.id = $1;` 59 WHERE m.id = $1`
61 // TODO: CategoryScores 60 // TODO: CategoryScores
62 err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &mapSummaryData.Description, &mapSummaryData.Showcase, &routers, &mapSummaryData.Rating) 61 err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &mapSummaryData.Description, &mapSummaryData.Showcase, &routers, &mapSummaryData.Rating)
63 if err != nil { 62 if err != nil {
@@ -69,7 +68,7 @@ func FetchMapSummary(c *gin.Context) {
69 var historyDates pq.StringArray 68 var historyDates pq.StringArray
70 sql = `SELECT array_agg(user_name), array_agg(score_count), array_agg(record_date) 69 sql = `SELECT array_agg(user_name), array_agg(score_count), array_agg(record_date)
71 FROM map_history 70 FROM map_history
72 WHERE map_id = $1;` 71 WHERE map_id = $1`
73 err = database.DB.QueryRow(sql, id).Scan(&historyNames, &historyScores, &historyDates) 72 err = database.DB.QueryRow(sql, id).Scan(&historyNames, &historyScores, &historyDates)
74 if err != nil { 73 if err != nil {
75 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 74 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -103,7 +102,6 @@ func FetchMapSummary(c *gin.Context) {
103// 102//
104// @Summary Get map leaderboards with specified id. 103// @Summary Get map leaderboards with specified id.
105// @Tags maps 104// @Tags maps
106// @Accept json
107// @Produce json 105// @Produce json
108// @Param id path int true "Map ID" 106// @Param id path int true "Map ID"
109// @Success 200 {object} models.Response{data=models.Map{data=models.MapRecords}} 107// @Success 200 {object} models.Response{data=models.Map{data=models.MapRecords}}
@@ -125,7 +123,7 @@ func FetchMapLeaderboards(c *gin.Context) {
125 FROM maps m 123 FROM maps m
126 INNER JOIN games g ON m.game_id = g.id 124 INNER JOIN games g ON m.game_id = g.id
127 INNER JOIN chapters c ON m.chapter_id = c.id 125 INNER JOIN chapters c ON m.chapter_id = c.id
128 WHERE m.id = $1;` 126 WHERE m.id = $1`
129 err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &isDisabled) 127 err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &isDisabled)
130 if err != nil { 128 if err != nil {
131 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 129 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -146,7 +144,7 @@ func FetchMapLeaderboards(c *gin.Context) {
146 FROM records_mp 144 FROM records_mp
147 WHERE map_id = $1 145 WHERE map_id = $1
148 ) sub 146 ) sub
149 WHERE rn = 1;` 147 WHERE rn = 1`
150 rows, err := database.DB.Query(sql, id) 148 rows, err := database.DB.Query(sql, id)
151 if err != nil { 149 if err != nil {
152 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 150 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -181,7 +179,7 @@ func FetchMapLeaderboards(c *gin.Context) {
181 WHERE map_id = $1 179 WHERE map_id = $1
182 ) sub 180 ) sub
183 INNER JOIN users ON user_id = users.steam_id 181 INNER JOIN users ON user_id = users.steam_id
184 WHERE rn = 1;` 182 WHERE rn = 1`
185 rows, err := database.DB.Query(sql, id) 183 rows, err := database.DB.Query(sql, id)
186 if err != nil { 184 if err != nil {
187 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 185 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -215,3 +213,117 @@ func FetchMapLeaderboards(c *gin.Context) {
215 Data: mapData, 213 Data: mapData,
216 }) 214 })
217} 215}
216
217// GET Games
218//
219// @Summary Get games from the leaderboards.
220// @Tags games & chapters
221// @Produce json
222// @Success 200 {object} models.Response{data=[]models.Game}
223// @Failure 400 {object} models.Response
224// @Router /games [get]
225func FetchGames(c *gin.Context) {
226 rows, err := database.DB.Query(`SELECT id, name FROM games`)
227 if err != nil {
228 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
229 return
230 }
231 var games []models.Game
232 for rows.Next() {
233 var game models.Game
234 if err := rows.Scan(&game.ID, &game.Name); err != nil {
235 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
236 return
237 }
238 games = append(games, game)
239 }
240 c.JSON(http.StatusOK, models.Response{
241 Success: true,
242 Message: "Successfully retrieved games.",
243 Data: games,
244 })
245}
246
247// GET Chapters of a Game
248//
249// @Summary Get chapters from the specified game id.
250// @Tags games & chapters
251// @Produce json
252// @Param id path int true "Game ID"
253// @Success 200 {object} models.Response{data=models.ChaptersResponse}
254// @Failure 400 {object} models.Response
255// @Router /games/{id} [get]
256func FetchChapters(c *gin.Context) {
257 gameID := c.Param("id")
258 intID, err := strconv.Atoi(gameID)
259 if err != nil {
260 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
261 return
262 }
263 var response models.ChaptersResponse
264 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)
265 if err != nil {
266 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
267 return
268 }
269 var chapters []models.Chapter
270 var gameName string
271 for rows.Next() {
272 var chapter models.Chapter
273 if err := rows.Scan(&chapter.ID, &chapter.Name, &gameName); err != nil {
274 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
275 return
276 }
277 chapters = append(chapters, chapter)
278 }
279 response.Game.ID = intID
280 response.Game.Name = gameName
281 response.Chapters = chapters
282 c.JSON(http.StatusOK, models.Response{
283 Success: true,
284 Message: "Successfully retrieved chapters.",
285 Data: response,
286 })
287}
288
289// GET Maps of a Chapter
290//
291// @Summary Get maps from the specified chapter id.
292// @Tags games & chapters
293// @Produce json
294// @Param id path int true "Chapter ID"
295// @Success 200 {object} models.Response{data=models.ChapterMapsResponse}
296// @Failure 400 {object} models.Response
297// @Router /chapters/{id} [get]
298func FetchChapterMaps(c *gin.Context) {
299 chapterID := c.Param("id")
300 intID, err := strconv.Atoi(chapterID)
301 if err != nil {
302 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
303 return
304 }
305 var response models.ChapterMapsResponse
306 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)
307 if err != nil {
308 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
309 return
310 }
311 var maps []models.MapShort
312 var chapterName string
313 for rows.Next() {
314 var mapShort models.MapShort
315 if err := rows.Scan(&mapShort.ID, &mapShort.Name, &chapterName); err != nil {
316 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
317 return
318 }
319 maps = append(maps, mapShort)
320 }
321 response.Chapter.ID = intID
322 response.Chapter.Name = chapterName
323 response.Maps = maps
324 c.JSON(http.StatusOK, models.Response{
325 Success: true,
326 Message: "Successfully retrieved maps.",
327 Data: response,
328 })
329}
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) {
46 var gameID int 46 var gameID int
47 var isCoop bool 47 var isCoop bool
48 var isDisabled bool 48 var isDisabled bool
49 sql := `SELECT game_id, is_disabled FROM maps WHERE id = $1;` 49 sql := `SELECT game_id, is_disabled FROM maps WHERE id = $1`
50 err := database.DB.QueryRow(sql, mapId).Scan(&gameID, &isDisabled) 50 err := database.DB.QueryRow(sql, mapId).Scan(&gameID, &isDisabled)
51 if err != nil { 51 if err != nil {
52 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 52 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -153,7 +153,7 @@ func CreateRecordWithDemo(c *gin.Context) {
153 // Insert into records 153 // Insert into records
154 if isCoop { 154 if isCoop {
155 sql := `INSERT INTO records_mp(map_id,score_count,score_time,host_id,partner_id,host_demo_id,partner_demo_id) 155 sql := `INSERT INTO records_mp(map_id,score_count,score_time,host_id,partner_id,host_demo_id,partner_demo_id)
156 VALUES($1, $2, $3, $4, $5, $6, $7);` 156 VALUES($1, $2, $3, $4, $5, $6, $7)`
157 var hostID string 157 var hostID string
158 var partnerID string 158 var partnerID string
159 if record.IsPartnerOrange { 159 if record.IsPartnerOrange {
@@ -171,7 +171,7 @@ func CreateRecordWithDemo(c *gin.Context) {
171 } 171 }
172 // If a new world record based on portal count 172 // If a new world record based on portal count
173 // if record.ScoreCount < wrScore { 173 // if record.ScoreCount < wrScore {
174 // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3;`, record.ScoreCount, record.ScoreTime, mapId) 174 // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3`, record.ScoreCount, record.ScoreTime, mapId)
175 // if err != nil { 175 // if err != nil {
176 // c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 176 // c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
177 // return 177 // return
@@ -179,7 +179,7 @@ func CreateRecordWithDemo(c *gin.Context) {
179 // } 179 // }
180 } else { 180 } else {
181 sql := `INSERT INTO records_sp(map_id,score_count,score_time,user_id,demo_id) 181 sql := `INSERT INTO records_sp(map_id,score_count,score_time,user_id,demo_id)
182 VALUES($1, $2, $3, $4, $5);` 182 VALUES($1, $2, $3, $4, $5)`
183 _, err := tx.Exec(sql, mapId, record.ScoreCount, record.ScoreTime, user.(models.User).SteamID, hostDemoUUID) 183 _, err := tx.Exec(sql, mapId, record.ScoreCount, record.ScoreTime, user.(models.User).SteamID, hostDemoUUID)
184 if err != nil { 184 if err != nil {
185 deleteFile(srv, fileID) 185 deleteFile(srv, fileID)
@@ -188,7 +188,7 @@ func CreateRecordWithDemo(c *gin.Context) {
188 } 188 }
189 // If a new world record based on portal count 189 // If a new world record based on portal count
190 // if record.ScoreCount < wrScore { 190 // if record.ScoreCount < wrScore {
191 // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3;`, record.ScoreCount, record.ScoreTime, mapId) 191 // _, err := tx.Exec(`UPDATE maps SET wr_score = $1, wr_time = $2 WHERE id = $3`, record.ScoreCount, record.ScoreTime, mapId)
192 // if err != nil { 192 // if err != nil {
193 // c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 193 // c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
194 // return 194 // return
@@ -224,7 +224,7 @@ func DownloadDemoWithID(c *gin.Context) {
224 c.JSON(http.StatusBadRequest, models.ErrorResponse("Invalid id given.")) 224 c.JSON(http.StatusBadRequest, models.ErrorResponse("Invalid id given."))
225 return 225 return
226 } 226 }
227 err := database.DB.QueryRow(`SELECT location_id FROM demos WHERE id = $1;`, uuid).Scan(&locationID) 227 err := database.DB.QueryRow(`SELECT location_id FROM demos WHERE id = $1`, uuid).Scan(&locationID)
228 if err != nil { 228 if err != nil {
229 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 229 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
230 return 230 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) {
31 } 31 }
32 // Retrieve singleplayer records 32 // Retrieve singleplayer records
33 var scoresSP []models.ScoreResponse 33 var scoresSP []models.ScoreResponse
34 sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id;` 34 sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id`
35 rows, err := database.DB.Query(sql, user.(models.User).SteamID) 35 rows, err := database.DB.Query(sql, user.(models.User).SteamID)
36 if err != nil { 36 if err != nil {
37 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 37 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -58,7 +58,7 @@ func Profile(c *gin.Context) {
58 // Retrieve multiplayer records 58 // Retrieve multiplayer records
59 var scoresMP []models.ScoreResponse 59 var scoresMP []models.ScoreResponse
60 sql = `SELECT id, map_id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date FROM records_mp 60 sql = `SELECT id, map_id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date FROM records_mp
61 WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id;` 61 WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id`
62 rows, err = database.DB.Query(sql, user.(models.User).SteamID, user.(models.User).SteamID) 62 rows, err = database.DB.Query(sql, user.(models.User).SteamID, user.(models.User).SteamID)
63 if err != nil { 63 if err != nil {
64 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 64 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -119,7 +119,7 @@ func FetchUser(c *gin.Context) {
119 } 119 }
120 // Check if user exists 120 // Check if user exists
121 var user models.User 121 var user models.User
122 err := database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1;`, id).Scan( 122 err := database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1`, id).Scan(
123 &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, 123 &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode,
124 &user.CreatedAt, &user.UpdatedAt) 124 &user.CreatedAt, &user.UpdatedAt)
125 if user.SteamID == "" { 125 if user.SteamID == "" {
@@ -133,7 +133,7 @@ func FetchUser(c *gin.Context) {
133 } 133 }
134 // Retrieve singleplayer records 134 // Retrieve singleplayer records
135 var scoresSP []models.ScoreResponse 135 var scoresSP []models.ScoreResponse
136 sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id;` 136 sql := `SELECT id, map_id, score_count, score_time, demo_id, record_date FROM records_sp WHERE user_id = $1 ORDER BY map_id`
137 rows, err := database.DB.Query(sql, user.SteamID) 137 rows, err := database.DB.Query(sql, user.SteamID)
138 if err != nil { 138 if err != nil {
139 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 139 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -160,7 +160,7 @@ func FetchUser(c *gin.Context) {
160 // Retrieve multiplayer records 160 // Retrieve multiplayer records
161 var scoresMP []models.ScoreResponse 161 var scoresMP []models.ScoreResponse
162 sql = `SELECT id, map_id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date FROM records_mp 162 sql = `SELECT id, map_id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date FROM records_mp
163 WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id;` 163 WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id`
164 rows, err = database.DB.Query(sql, user.SteamID, user.SteamID) 164 rows, err = database.DB.Query(sql, user.SteamID, user.SteamID)
165 if err != nil { 165 if err != nil {
166 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 166 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -225,7 +225,7 @@ func UpdateUser(c *gin.Context) {
225 } 225 }
226 // Update profile 226 // Update profile
227 _, err = database.DB.Exec(`UPDATE users SET username = $1, avatar_link = $2, country_code = $3, updated_at = $4 227 _, err = database.DB.Exec(`UPDATE users SET username = $1, avatar_link = $2, country_code = $3, updated_at = $4
228 WHERE steam_id = $5;`, profile.PersonaName, profile.AvatarFull, profile.LocCountryCode, time.Now().UTC(), user.(models.User).SteamID) 228 WHERE steam_id = $5`, profile.PersonaName, profile.AvatarFull, profile.LocCountryCode, time.Now().UTC(), user.(models.User).SteamID)
229 if err != nil { 229 if err != nil {
230 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 230 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
231 return 231 return
@@ -268,7 +268,7 @@ func UpdateCountryCode(c *gin.Context) {
268 return 268 return
269 } 269 }
270 var validCode string 270 var validCode string
271 err := database.DB.QueryRow(`SELECT country_code FROM countries WHERE country_code = $1;`, code).Scan(&validCode) 271 err := database.DB.QueryRow(`SELECT country_code FROM countries WHERE country_code = $1`, code).Scan(&validCode)
272 if err != nil { 272 if err != nil {
273 c.JSON(http.StatusNotFound, models.ErrorResponse(err.Error())) 273 c.JSON(http.StatusNotFound, models.ErrorResponse(err.Error()))
274 return 274 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) {
36 } 36 }
37 // Get user from DB 37 // Get user from DB
38 var user models.User 38 var user models.User
39 database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1;`, claims["sub"]).Scan( 39 database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1`, claims["sub"]).Scan(
40 &user.SteamID, &user.UserName, &user.AvatarLink, 40 &user.SteamID, &user.UserName, &user.AvatarLink,
41 &user.CountryCode, &user.CreatedAt, &user.UpdatedAt) 41 &user.CountryCode, &user.CreatedAt, &user.UpdatedAt)
42 if user.SteamID == "" { 42 if user.SteamID == "" {
diff --git a/backend/models/models.go b/backend/models/models.go
index cdcd111..6f5173a 100644
--- a/backend/models/models.go
+++ b/backend/models/models.go
@@ -153,6 +153,31 @@ type PlayerSummaries struct {
153 GameServerIp string `json:"gameserverip"` 153 GameServerIp string `json:"gameserverip"`
154} 154}
155 155
156type Game struct {
157 ID int `json:"id"`
158 Name string `json:"name"`
159}
160
161type ChaptersResponse struct {
162 Game Game `json:"game"`
163 Chapters []Chapter `json:"chapters"`
164}
165
166type Chapter struct {
167 ID int `json:"id"`
168 Name string `json:"name"`
169}
170
171type MapShort struct {
172 ID int `json:"id"`
173 Name string `json:"name"`
174}
175
176type ChapterMapsResponse struct {
177 Chapter Chapter `json:"chapter"`
178 Maps []MapShort `json:"maps"`
179}
180
156func ErrorResponse(message string) Response { 181func ErrorResponse(message string) Response {
157 return Response{ 182 return Response{
158 Success: false, 183 Success: false,
diff --git a/backend/routes/routes.go b/backend/routes/routes.go
index 53d4e78..2554fa4 100644
--- a/backend/routes/routes.go
+++ b/backend/routes/routes.go
@@ -28,5 +28,8 @@ func InitRoutes(router *gin.Engine) {
28 v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) 28 v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo)
29 v1.GET("/rankings", middleware.CheckAuth, controllers.Rankings) 29 v1.GET("/rankings", middleware.CheckAuth, controllers.Rankings)
30 v1.GET("/search", controllers.Search) 30 v1.GET("/search", controllers.Search)
31 v1.GET("/games", controllers.FetchGames)
32 v1.GET("/games/:id", controllers.FetchChapters)
33 v1.GET("/chapters/:id", controllers.FetchChapterMaps)
31 } 34 }
32} 35}
diff --git a/docs/docs.go b/docs/docs.go
index 22d4362..cd129f0 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -20,6 +20,52 @@ const docTemplate = `{
20 "host": "{{.Host}}", 20 "host": "{{.Host}}",
21 "basePath": "{{.BasePath}}", 21 "basePath": "{{.BasePath}}",
22 "paths": { 22 "paths": {
23 "/chapters/{id}": {
24 "get": {
25 "produces": [
26 "application/json"
27 ],
28 "tags": [
29 "games \u0026 chapters"
30 ],
31 "summary": "Get maps from the specified chapter id.",
32 "parameters": [
33 {
34 "type": "integer",
35 "description": "Chapter ID",
36 "name": "id",
37 "in": "path",
38 "required": true
39 }
40 ],
41 "responses": {
42 "200": {
43 "description": "OK",
44 "schema": {
45 "allOf": [
46 {
47 "$ref": "#/definitions/models.Response"
48 },
49 {
50 "type": "object",
51 "properties": {
52 "data": {
53 "$ref": "#/definitions/models.ChapterMapsResponse"
54 }
55 }
56 }
57 ]
58 }
59 },
60 "400": {
61 "description": "Bad Request",
62 "schema": {
63 "$ref": "#/definitions/models.Response"
64 }
65 }
66 }
67 }
68 },
23 "/demo": { 69 "/demo": {
24 "get": { 70 "get": {
25 "produces": [ 71 "produces": [
@@ -94,6 +140,92 @@ const docTemplate = `{
94 } 140 }
95 } 141 }
96 }, 142 },
143 "/games": {
144 "get": {
145 "produces": [
146 "application/json"
147 ],
148 "tags": [
149 "games \u0026 chapters"
150 ],
151 "summary": "Get games from the leaderboards.",
152 "responses": {
153 "200": {
154 "description": "OK",
155 "schema": {
156 "allOf": [
157 {
158 "$ref": "#/definitions/models.Response"
159 },
160 {
161 "type": "object",
162 "properties": {
163 "data": {
164 "type": "array",
165 "items": {
166 "$ref": "#/definitions/models.Game"
167 }
168 }
169 }
170 }
171 ]
172 }
173 },
174 "400": {
175 "description": "Bad Request",
176 "schema": {
177 "$ref": "#/definitions/models.Response"
178 }
179 }
180 }
181 }
182 },
183 "/games/{id}": {
184 "get": {
185 "produces": [
186 "application/json"
187 ],
188 "tags": [
189 "games \u0026 chapters"
190 ],
191 "summary": "Get chapters from the specified game id.",
192 "parameters": [
193 {
194 "type": "integer",
195 "description": "Game ID",
196 "name": "id",
197 "in": "path",
198 "required": true
199 }
200 ],
201 "responses": {
202 "200": {
203 "description": "OK",
204 "schema": {
205 "allOf": [
206 {
207 "$ref": "#/definitions/models.Response"
208 },
209 {
210 "type": "object",
211 "properties": {
212 "data": {
213 "$ref": "#/definitions/models.ChaptersResponse"
214 }
215 }
216 }
217 ]
218 }
219 },
220 "400": {
221 "description": "Bad Request",
222 "schema": {
223 "$ref": "#/definitions/models.Response"
224 }
225 }
226 }
227 }
228 },
97 "/login": { 229 "/login": {
98 "get": { 230 "get": {
99 "consumes": [ 231 "consumes": [
@@ -136,9 +268,6 @@ const docTemplate = `{
136 }, 268 },
137 "/maps/{id}/leaderboards": { 269 "/maps/{id}/leaderboards": {
138 "get": { 270 "get": {
139 "consumes": [
140 "application/json"
141 ],
142 "produces": [ 271 "produces": [
143 "application/json" 272 "application/json"
144 ], 273 ],
@@ -290,9 +419,6 @@ const docTemplate = `{
290 }, 419 },
291 "/maps/{id}/summary": { 420 "/maps/{id}/summary": {
292 "get": { 421 "get": {
293 "consumes": [
294 "application/json"
295 ],
296 "produces": [ 422 "produces": [
297 "application/json" 423 "application/json"
298 ], 424 ],
@@ -530,7 +656,19 @@ const docTemplate = `{
530 "200": { 656 "200": {
531 "description": "OK", 657 "description": "OK",
532 "schema": { 658 "schema": {
533 "$ref": "#/definitions/models.Response" 659 "allOf": [
660 {
661 "$ref": "#/definitions/models.Response"
662 },
663 {
664 "type": "object",
665 "properties": {
666 "data": {
667 "$ref": "#/definitions/models.SearchResponse"
668 }
669 }
670 }
671 ]
534 } 672 }
535 }, 673 },
536 "400": { 674 "400": {
@@ -599,6 +737,56 @@ const docTemplate = `{
599 } 737 }
600 }, 738 },
601 "definitions": { 739 "definitions": {
740 "models.Chapter": {
741 "type": "object",
742 "properties": {
743 "id": {
744 "type": "integer"
745 },
746 "name": {
747 "type": "string"
748 }
749 }
750 },
751 "models.ChapterMapsResponse": {
752 "type": "object",
753 "properties": {
754 "chapter": {
755 "$ref": "#/definitions/models.Chapter"
756 },
757 "maps": {
758 "type": "array",
759 "items": {
760 "$ref": "#/definitions/models.MapShort"
761 }
762 }
763 }
764 },
765 "models.ChaptersResponse": {
766 "type": "object",
767 "properties": {
768 "chapters": {
769 "type": "array",
770 "items": {
771 "$ref": "#/definitions/models.Chapter"
772 }
773 },
774 "game": {
775 "$ref": "#/definitions/models.Game"
776 }
777 }
778 },
779 "models.Game": {
780 "type": "object",
781 "properties": {
782 "id": {
783 "type": "integer"
784 },
785 "name": {
786 "type": "string"
787 }
788 }
789 },
602 "models.LoginResponse": { 790 "models.LoginResponse": {
603 "type": "object", 791 "type": "object",
604 "properties": { 792 "properties": {
@@ -662,6 +850,17 @@ const docTemplate = `{
662 "records": {} 850 "records": {}
663 } 851 }
664 }, 852 },
853 "models.MapShort": {
854 "type": "object",
855 "properties": {
856 "id": {
857 "type": "integer"
858 },
859 "name": {
860 "type": "string"
861 }
862 }
863 },
665 "models.MapSummary": { 864 "models.MapSummary": {
666 "type": "object", 865 "type": "object",
667 "properties": { 866 "properties": {
@@ -784,6 +983,39 @@ const docTemplate = `{
784 "records": {} 983 "records": {}
785 } 984 }
786 }, 985 },
986 "models.SearchResponse": {
987 "type": "object",
988 "properties": {
989 "maps": {
990 "type": "array",
991 "items": {
992 "type": "object",
993 "properties": {
994 "id": {
995 "type": "integer"
996 },
997 "name": {
998 "type": "string"
999 }
1000 }
1001 }
1002 },
1003 "players": {
1004 "type": "array",
1005 "items": {
1006 "type": "object",
1007 "properties": {
1008 "steam_id": {
1009 "type": "string"
1010 },
1011 "user_name": {
1012 "type": "string"
1013 }
1014 }
1015 }
1016 }
1017 }
1018 },
787 "models.UserRanking": { 1019 "models.UserRanking": {
788 "type": "object", 1020 "type": "object",
789 "properties": { 1021 "properties": {
diff --git a/docs/swagger.json b/docs/swagger.json
index 0bebe1c..442745f 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -13,6 +13,52 @@
13 "host": "lp.ardapektezol.com/api", 13 "host": "lp.ardapektezol.com/api",
14 "basePath": "/v1", 14 "basePath": "/v1",
15 "paths": { 15 "paths": {
16 "/chapters/{id}": {
17 "get": {
18 "produces": [
19 "application/json"
20 ],
21 "tags": [
22 "games \u0026 chapters"
23 ],
24 "summary": "Get maps from the specified chapter id.",
25 "parameters": [
26 {
27 "type": "integer",
28 "description": "Chapter ID",
29 "name": "id",
30 "in": "path",
31 "required": true
32 }
33 ],
34 "responses": {
35 "200": {
36 "description": "OK",
37 "schema": {
38 "allOf": [
39 {
40 "$ref": "#/definitions/models.Response"
41 },
42 {
43 "type": "object",
44 "properties": {
45 "data": {
46 "$ref": "#/definitions/models.ChapterMapsResponse"
47 }
48 }
49 }
50 ]
51 }
52 },
53 "400": {
54 "description": "Bad Request",
55 "schema": {
56 "$ref": "#/definitions/models.Response"
57 }
58 }
59 }
60 }
61 },
16 "/demo": { 62 "/demo": {
17 "get": { 63 "get": {
18 "produces": [ 64 "produces": [
@@ -87,6 +133,92 @@
87 } 133 }
88 } 134 }
89 }, 135 },
136 "/games": {
137 "get": {
138 "produces": [
139 "application/json"
140 ],
141 "tags": [
142 "games \u0026 chapters"
143 ],
144 "summary": "Get games from the leaderboards.",
145 "responses": {
146 "200": {
147 "description": "OK",
148 "schema": {
149 "allOf": [
150 {
151 "$ref": "#/definitions/models.Response"
152 },
153 {
154 "type": "object",
155 "properties": {
156 "data": {
157 "type": "array",
158 "items": {
159 "$ref": "#/definitions/models.Game"
160 }
161 }
162 }
163 }
164 ]
165 }
166 },
167 "400": {
168 "description": "Bad Request",
169 "schema": {
170 "$ref": "#/definitions/models.Response"
171 }
172 }
173 }
174 }
175 },
176 "/games/{id}": {
177 "get": {
178 "produces": [
179 "application/json"
180 ],
181 "tags": [
182 "games \u0026 chapters"
183 ],
184 "summary": "Get chapters from the specified game id.",
185 "parameters": [
186 {
187 "type": "integer",
188 "description": "Game ID",
189 "name": "id",
190 "in": "path",
191 "required": true
192 }
193 ],
194 "responses": {
195 "200": {
196 "description": "OK",
197 "schema": {
198 "allOf": [
199 {
200 "$ref": "#/definitions/models.Response"
201 },
202 {
203 "type": "object",
204 "properties": {
205 "data": {
206 "$ref": "#/definitions/models.ChaptersResponse"
207 }
208 }
209 }
210 ]
211 }
212 },
213 "400": {
214 "description": "Bad Request",
215 "schema": {
216 "$ref": "#/definitions/models.Response"
217 }
218 }
219 }
220 }
221 },
90 "/login": { 222 "/login": {
91 "get": { 223 "get": {
92 "consumes": [ 224 "consumes": [
@@ -129,9 +261,6 @@
129 }, 261 },
130 "/maps/{id}/leaderboards": { 262 "/maps/{id}/leaderboards": {
131 "get": { 263 "get": {
132 "consumes": [
133 "application/json"
134 ],
135 "produces": [ 264 "produces": [
136 "application/json" 265 "application/json"
137 ], 266 ],
@@ -283,9 +412,6 @@
283 }, 412 },
284 "/maps/{id}/summary": { 413 "/maps/{id}/summary": {
285 "get": { 414 "get": {
286 "consumes": [
287 "application/json"
288 ],
289 "produces": [ 415 "produces": [
290 "application/json" 416 "application/json"
291 ], 417 ],
@@ -523,7 +649,19 @@
523 "200": { 649 "200": {
524 "description": "OK", 650 "description": "OK",
525 "schema": { 651 "schema": {
526 "$ref": "#/definitions/models.Response" 652 "allOf": [
653 {
654 "$ref": "#/definitions/models.Response"
655 },
656 {
657 "type": "object",
658 "properties": {
659 "data": {
660 "$ref": "#/definitions/models.SearchResponse"
661 }
662 }
663 }
664 ]
527 } 665 }
528 }, 666 },
529 "400": { 667 "400": {
@@ -592,6 +730,56 @@
592 } 730 }
593 }, 731 },
594 "definitions": { 732 "definitions": {
733 "models.Chapter": {
734 "type": "object",
735 "properties": {
736 "id": {
737 "type": "integer"
738 },
739 "name": {
740 "type": "string"
741 }
742 }
743 },
744 "models.ChapterMapsResponse": {
745 "type": "object",
746 "properties": {
747 "chapter": {
748 "$ref": "#/definitions/models.Chapter"
749 },
750 "maps": {
751 "type": "array",
752 "items": {
753 "$ref": "#/definitions/models.MapShort"
754 }
755 }
756 }
757 },
758 "models.ChaptersResponse": {
759 "type": "object",
760 "properties": {
761 "chapters": {
762 "type": "array",
763 "items": {
764 "$ref": "#/definitions/models.Chapter"
765 }
766 },
767 "game": {
768 "$ref": "#/definitions/models.Game"
769 }
770 }
771 },
772 "models.Game": {
773 "type": "object",
774 "properties": {
775 "id": {
776 "type": "integer"
777 },
778 "name": {
779 "type": "string"
780 }
781 }
782 },
595 "models.LoginResponse": { 783 "models.LoginResponse": {
596 "type": "object", 784 "type": "object",
597 "properties": { 785 "properties": {
@@ -655,6 +843,17 @@
655 "records": {} 843 "records": {}
656 } 844 }
657 }, 845 },
846 "models.MapShort": {
847 "type": "object",
848 "properties": {
849 "id": {
850 "type": "integer"
851 },
852 "name": {
853 "type": "string"
854 }
855 }
856 },
658 "models.MapSummary": { 857 "models.MapSummary": {
659 "type": "object", 858 "type": "object",
660 "properties": { 859 "properties": {
@@ -777,6 +976,39 @@
777 "records": {} 976 "records": {}
778 } 977 }
779 }, 978 },
979 "models.SearchResponse": {
980 "type": "object",
981 "properties": {
982 "maps": {
983 "type": "array",
984 "items": {
985 "type": "object",
986 "properties": {
987 "id": {
988 "type": "integer"
989 },
990 "name": {
991 "type": "string"
992 }
993 }
994 }
995 },
996 "players": {
997 "type": "array",
998 "items": {
999 "type": "object",
1000 "properties": {
1001 "steam_id": {
1002 "type": "string"
1003 },
1004 "user_name": {
1005 "type": "string"
1006 }
1007 }
1008 }
1009 }
1010 }
1011 },
780 "models.UserRanking": { 1012 "models.UserRanking": {
781 "type": "object", 1013 "type": "object",
782 "properties": { 1014 "properties": {
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index f719008..fa1a26d 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -1,5 +1,37 @@
1basePath: /v1 1basePath: /v1
2definitions: 2definitions:
3 models.Chapter:
4 properties:
5 id:
6 type: integer
7 name:
8 type: string
9 type: object
10 models.ChapterMapsResponse:
11 properties:
12 chapter:
13 $ref: '#/definitions/models.Chapter'
14 maps:
15 items:
16 $ref: '#/definitions/models.MapShort'
17 type: array
18 type: object
19 models.ChaptersResponse:
20 properties:
21 chapters:
22 items:
23 $ref: '#/definitions/models.Chapter'
24 type: array
25 game:
26 $ref: '#/definitions/models.Game'
27 type: object
28 models.Game:
29 properties:
30 id:
31 type: integer
32 name:
33 type: string
34 type: object
3 models.LoginResponse: 35 models.LoginResponse:
4 properties: 36 properties:
5 token: 37 token:
@@ -41,6 +73,13 @@ definitions:
41 properties: 73 properties:
42 records: {} 74 records: {}
43 type: object 75 type: object
76 models.MapShort:
77 properties:
78 id:
79 type: integer
80 name:
81 type: string
82 type: object
44 models.MapSummary: 83 models.MapSummary:
45 properties: 84 properties:
46 category_scores: 85 category_scores:
@@ -122,6 +161,27 @@ definitions:
122 type: integer 161 type: integer
123 records: {} 162 records: {}
124 type: object 163 type: object
164 models.SearchResponse:
165 properties:
166 maps:
167 items:
168 properties:
169 id:
170 type: integer
171 name:
172 type: string
173 type: object
174 type: array
175 players:
176 items:
177 properties:
178 steam_id:
179 type: string
180 user_name:
181 type: string
182 type: object
183 type: array
184 type: object
125 models.UserRanking: 185 models.UserRanking:
126 properties: 186 properties:
127 total_score: 187 total_score:
@@ -141,6 +201,33 @@ info:
141 title: Least Portals Database API 201 title: Least Portals Database API
142 version: "1.0" 202 version: "1.0"
143paths: 203paths:
204 /chapters/{id}:
205 get:
206 parameters:
207 - description: Chapter ID
208 in: path
209 name: id
210 required: true
211 type: integer
212 produces:
213 - application/json
214 responses:
215 "200":
216 description: OK
217 schema:
218 allOf:
219 - $ref: '#/definitions/models.Response'
220 - properties:
221 data:
222 $ref: '#/definitions/models.ChapterMapsResponse'
223 type: object
224 "400":
225 description: Bad Request
226 schema:
227 $ref: '#/definitions/models.Response'
228 summary: Get maps from the specified chapter id.
229 tags:
230 - games & chapters
144 /demo: 231 /demo:
145 get: 232 get:
146 produces: 233 produces:
@@ -186,6 +273,56 @@ paths:
186 summary: Get demo with specified demo uuid. 273 summary: Get demo with specified demo uuid.
187 tags: 274 tags:
188 - demo 275 - demo
276 /games:
277 get:
278 produces:
279 - application/json
280 responses:
281 "200":
282 description: OK
283 schema:
284 allOf:
285 - $ref: '#/definitions/models.Response'
286 - properties:
287 data:
288 items:
289 $ref: '#/definitions/models.Game'
290 type: array
291 type: object
292 "400":
293 description: Bad Request
294 schema:
295 $ref: '#/definitions/models.Response'
296 summary: Get games from the leaderboards.
297 tags:
298 - games & chapters
299 /games/{id}:
300 get:
301 parameters:
302 - description: Game ID
303 in: path
304 name: id
305 required: true
306 type: integer
307 produces:
308 - application/json
309 responses:
310 "200":
311 description: OK
312 schema:
313 allOf:
314 - $ref: '#/definitions/models.Response'
315 - properties:
316 data:
317 $ref: '#/definitions/models.ChaptersResponse'
318 type: object
319 "400":
320 description: Bad Request
321 schema:
322 $ref: '#/definitions/models.Response'
323 summary: Get chapters from the specified game id.
324 tags:
325 - games & chapters
189 /login: 326 /login:
190 get: 327 get:
191 consumes: 328 consumes:
@@ -211,8 +348,6 @@ paths:
211 - login 348 - login
212 /maps/{id}/leaderboards: 349 /maps/{id}/leaderboards:
213 get: 350 get:
214 consumes:
215 - application/json
216 parameters: 351 parameters:
217 - description: Map ID 352 - description: Map ID
218 in: path 353 in: path
@@ -305,8 +440,6 @@ paths:
305 - maps 440 - maps
306 /maps/{id}/summary: 441 /maps/{id}/summary:
307 get: 442 get:
308 consumes:
309 - application/json
310 parameters: 443 parameters:
311 - description: Map ID 444 - description: Map ID
312 in: path 445 in: path
@@ -447,7 +580,12 @@ paths:
447 "200": 580 "200":
448 description: OK 581 description: OK
449 schema: 582 schema:
450 $ref: '#/definitions/models.Response' 583 allOf:
584 - $ref: '#/definitions/models.Response'
585 - properties:
586 data:
587 $ref: '#/definitions/models.SearchResponse'
588 type: object
451 "400": 589 "400":
452 description: Bad Request 590 description: Bad Request
453 schema: 591 schema:
diff --git a/main.go b/main.go
index 991f3c0..ec26280 100644
--- a/main.go
+++ b/main.go
@@ -5,6 +5,7 @@ import (
5 "log" 5 "log"
6 "os" 6 "os"
7 7
8 "github.com/gin-gonic/contrib/cors"
8 "github.com/gin-gonic/gin" 9 "github.com/gin-gonic/gin"
9 "github.com/joho/godotenv" 10 "github.com/joho/godotenv"
10 "github.com/pektezol/leastportals/backend/database" 11 "github.com/pektezol/leastportals/backend/database"
@@ -19,8 +20,8 @@ import (
19// @license.name GNU General Public License, Version 2 20// @license.name GNU General Public License, Version 2
20// @license.url https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 21// @license.url https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 22
22// @host lp.ardapektezol.com/api 23// @host lp.ardapektezol.com/api
23// @BasePath /v1 24// @BasePath /v1
24func main() { 25func main() {
25 if os.Getenv("ENV") == "PROD" { 26 if os.Getenv("ENV") == "PROD" {
26 gin.SetMode(gin.ReleaseMode) 27 gin.SetMode(gin.ReleaseMode)
@@ -30,6 +31,10 @@ func main() {
30 log.Fatal("Error loading .env file") 31 log.Fatal("Error loading .env file")
31 } 32 }
32 router := gin.Default() 33 router := gin.Default()
34 config := cors.DefaultConfig()
35 config.AllowAllOrigins = true
36 config.AllowCredentials = true
37 router.Use(cors.New(config))
33 database.ConnectDB() 38 database.ConnectDB()
34 // For frontend static serving - only for local debug 39 // For frontend static serving - only for local debug
35 // router.Use(static.Serve("/", static.LocalFile("./frontend/build", true))) 40 // router.Use(static.Serve("/", static.LocalFile("./frontend/build", true)))