aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-08-20 12:51:26 +0300
committerArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-08-20 12:51:26 +0300
commitca7acc2fdc6e6c8371ca5bbeeaabb02d11bb1bee (patch)
tree1196cbb2b253ecaddd80934cc849cfd52f68b3e4 /backend
parentfix: change map history from timestamp to date (diff)
downloadlphub-ca7acc2fdc6e6c8371ca5bbeeaabb02d11bb1bee.tar.gz
lphub-ca7acc2fdc6e6c8371ca5bbeeaabb02d11bb1bee.tar.bz2
lphub-ca7acc2fdc6e6c8371ca5bbeeaabb02d11bb1bee.zip
refactor: move structs around for better understanding
Former-commit-id: 0030a6b0c7b228772d8e27f5722ee6de1718786b
Diffstat (limited to 'backend')
-rw-r--r--backend/controllers/homeController.go18
-rw-r--r--backend/controllers/loginController.go16
-rw-r--r--backend/controllers/mapController.go27
-rw-r--r--backend/controllers/modController.go67
-rw-r--r--backend/controllers/recordController.go20
-rw-r--r--backend/controllers/userController.go43
-rw-r--r--backend/models/models.go14
-rw-r--r--backend/models/requests.go39
-rw-r--r--backend/models/responses.go64
9 files changed, 152 insertions, 156 deletions
diff --git a/backend/controllers/homeController.go b/backend/controllers/homeController.go
index c94590a..d1b99cb 100644
--- a/backend/controllers/homeController.go
+++ b/backend/controllers/homeController.go
@@ -10,6 +10,16 @@ import (
10 "github.com/pektezol/leastportalshub/backend/models" 10 "github.com/pektezol/leastportalshub/backend/models"
11) 11)
12 12
13type SearchResponse struct {
14 Players []models.UserShort `json:"players"`
15 Maps []models.MapShort `json:"maps"`
16}
17
18type RankingsResponse struct {
19 RankingsSP []models.UserRanking `json:"rankings_sp"`
20 RankingsMP []models.UserRanking `json:"rankings_mp"`
21}
22
13func Home(c *gin.Context) { 23func Home(c *gin.Context) {
14 user, exists := c.Get("user") 24 user, exists := c.Get("user")
15 if !exists { 25 if !exists {
@@ -26,7 +36,7 @@ func Home(c *gin.Context) {
26// @Description Get rankings of every player. 36// @Description Get rankings of every player.
27// @Tags rankings 37// @Tags rankings
28// @Produce json 38// @Produce json
29// @Success 200 {object} models.Response{data=models.RankingsResponse} 39// @Success 200 {object} models.Response{data=RankingsResponse}
30// @Failure 400 {object} models.Response 40// @Failure 400 {object} models.Response
31// @Router /rankings [get] 41// @Router /rankings [get]
32func Rankings(c *gin.Context) { 42func Rankings(c *gin.Context) {
@@ -116,7 +126,7 @@ func Rankings(c *gin.Context) {
116 c.JSON(http.StatusOK, models.Response{ 126 c.JSON(http.StatusOK, models.Response{
117 Success: true, 127 Success: true,
118 Message: "Successfully retrieved rankings.", 128 Message: "Successfully retrieved rankings.",
119 Data: models.RankingsResponse{ 129 Data: RankingsResponse{
120 RankingsSP: spRankings, 130 RankingsSP: spRankings,
121 RankingsMP: mpRankings, 131 RankingsMP: mpRankings,
122 }, 132 },
@@ -129,14 +139,14 @@ func Rankings(c *gin.Context) {
129// @Tags search 139// @Tags search
130// @Produce json 140// @Produce json
131// @Param q query string false "Search user or map name." 141// @Param q query string false "Search user or map name."
132// @Success 200 {object} models.Response{data=models.SearchResponse} 142// @Success 200 {object} models.Response{data=SearchResponse}
133// @Failure 400 {object} models.Response 143// @Failure 400 {object} models.Response
134// @Router /search [get] 144// @Router /search [get]
135func SearchWithQuery(c *gin.Context) { 145func SearchWithQuery(c *gin.Context) {
136 query := c.Query("q") 146 query := c.Query("q")
137 query = strings.ToLower(query) 147 query = strings.ToLower(query)
138 log.Println(query) 148 log.Println(query)
139 var response models.SearchResponse 149 var response SearchResponse
140 // Cache all maps for faster response 150 // Cache all maps for faster response
141 var maps = []models.MapShort{ 151 var maps = []models.MapShort{
142 {ID: 1, Name: "Container Ride"}, 152 {ID: 1, Name: "Container Ride"},
diff --git a/backend/controllers/loginController.go b/backend/controllers/loginController.go
index e907b22..76bf51f 100644
--- a/backend/controllers/loginController.go
+++ b/backend/controllers/loginController.go
@@ -15,13 +15,17 @@ import (
15 "github.com/solovev/steam_go" 15 "github.com/solovev/steam_go"
16) 16)
17 17
18type LoginResponse struct {
19 Token string `json:"token"`
20}
21
18// Login 22// Login
19// 23//
20// @Description Get (redirect) login page for Steam auth. 24// @Description Get (redirect) login page for Steam auth.
21// @Tags login 25// @Tags login
22// @Accept json 26// @Accept json
23// @Produce json 27// @Produce json
24// @Success 200 {object} models.Response{data=models.LoginResponse} 28// @Success 200 {object} models.Response{data=LoginResponse}
25// @Failure 400 {object} models.Response 29// @Failure 400 {object} models.Response
26// @Router /login [get] 30// @Router /login [get]
27func Login(c *gin.Context) { 31func Login(c *gin.Context) {
@@ -85,7 +89,7 @@ func Login(c *gin.Context) {
85 // c.JSON(http.StatusOK, models.Response{ 89 // c.JSON(http.StatusOK, models.Response{
86 // Success: true, 90 // Success: true,
87 // Message: "Successfully generated token.", 91 // Message: "Successfully generated token.",
88 // Data: models.LoginResponse{ 92 // Data: LoginResponse{
89 // Token: tokenString, 93 // Token: tokenString,
90 // }, 94 // },
91 // }) 95 // })
@@ -99,7 +103,7 @@ func Login(c *gin.Context) {
99// @Tags auth 103// @Tags auth
100// @Produce json 104// @Produce json
101// 105//
102// @Success 200 {object} models.Response{data=models.LoginResponse} 106// @Success 200 {object} models.Response{data=LoginResponse}
103// @Failure 404 {object} models.Response 107// @Failure 404 {object} models.Response
104// @Router /token [get] 108// @Router /token [get]
105func GetCookie(c *gin.Context) { 109func GetCookie(c *gin.Context) {
@@ -111,7 +115,7 @@ func GetCookie(c *gin.Context) {
111 c.JSON(http.StatusOK, models.Response{ 115 c.JSON(http.StatusOK, models.Response{
112 Success: true, 116 Success: true,
113 Message: "Token cookie successfully retrieved.", 117 Message: "Token cookie successfully retrieved.",
114 Data: models.LoginResponse{ 118 Data: LoginResponse{
115 Token: cookie, 119 Token: cookie,
116 }, 120 },
117 }) 121 })
@@ -123,7 +127,7 @@ func GetCookie(c *gin.Context) {
123// @Tags auth 127// @Tags auth
124// @Produce json 128// @Produce json
125// 129//
126// @Success 200 {object} models.Response{data=models.LoginResponse} 130// @Success 200 {object} models.Response{data=LoginResponse}
127// @Failure 404 {object} models.Response 131// @Failure 404 {object} models.Response
128// @Router /token [delete] 132// @Router /token [delete]
129func DeleteCookie(c *gin.Context) { 133func DeleteCookie(c *gin.Context) {
@@ -136,7 +140,7 @@ func DeleteCookie(c *gin.Context) {
136 c.JSON(http.StatusOK, models.Response{ 140 c.JSON(http.StatusOK, models.Response{
137 Success: true, 141 Success: true,
138 Message: "Token cookie successfully deleted.", 142 Message: "Token cookie successfully deleted.",
139 Data: models.LoginResponse{ 143 Data: LoginResponse{
140 Token: cookie, 144 Token: cookie,
141 }, 145 },
142 }) 146 })
diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go
index ebd65dd..0a324d6 100644
--- a/backend/controllers/mapController.go
+++ b/backend/controllers/mapController.go
@@ -9,18 +9,33 @@ import (
9 "github.com/pektezol/leastportalshub/backend/models" 9 "github.com/pektezol/leastportalshub/backend/models"
10) 10)
11 11
12type MapSummaryResponse struct {
13 Map models.Map `json:"map"`
14 Summary models.MapSummary `json:"summary"`
15}
16
17type ChaptersResponse struct {
18 Game models.Game `json:"game"`
19 Chapters []models.Chapter `json:"chapters"`
20}
21
22type ChapterMapsResponse struct {
23 Chapter models.Chapter `json:"chapter"`
24 Maps []models.MapShort `json:"maps"`
25}
26
12// GET Map Summary 27// GET Map Summary
13// 28//
14// @Description Get map summary with specified id. 29// @Description Get map summary with specified id.
15// @Tags maps 30// @Tags maps
16// @Produce json 31// @Produce json
17// @Param id path int true "Map ID" 32// @Param id path int true "Map ID"
18// @Success 200 {object} models.Response{data=models.MapSummaryResponse} 33// @Success 200 {object} models.Response{data=MapSummaryResponse}
19// @Failure 400 {object} models.Response 34// @Failure 400 {object} models.Response
20// @Router /maps/{id}/summary [get] 35// @Router /maps/{id}/summary [get]
21func FetchMapSummary(c *gin.Context) { 36func FetchMapSummary(c *gin.Context) {
22 id := c.Param("id") 37 id := c.Param("id")
23 response := models.MapSummaryResponse{Map: models.Map{}, Summary: models.MapSummary{Routes: []models.MapRoute{}}} 38 response := MapSummaryResponse{Map: models.Map{}, Summary: models.MapSummary{Routes: []models.MapRoute{}}}
24 intID, err := strconv.Atoi(id) 39 intID, err := strconv.Atoi(id)
25 if err != nil { 40 if err != nil {
26 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 41 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -220,7 +235,7 @@ func FetchGames(c *gin.Context) {
220// @Tags games & chapters 235// @Tags games & chapters
221// @Produce json 236// @Produce json
222// @Param id path int true "Game ID" 237// @Param id path int true "Game ID"
223// @Success 200 {object} models.Response{data=models.ChaptersResponse} 238// @Success 200 {object} models.Response{data=ChaptersResponse}
224// @Failure 400 {object} models.Response 239// @Failure 400 {object} models.Response
225// @Router /games/{id} [get] 240// @Router /games/{id} [get]
226func FetchChapters(c *gin.Context) { 241func FetchChapters(c *gin.Context) {
@@ -230,7 +245,7 @@ func FetchChapters(c *gin.Context) {
230 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 245 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
231 return 246 return
232 } 247 }
233 var response models.ChaptersResponse 248 var response ChaptersResponse
234 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) 249 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)
235 if err != nil { 250 if err != nil {
236 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 251 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -262,7 +277,7 @@ func FetchChapters(c *gin.Context) {
262// @Tags games & chapters 277// @Tags games & chapters
263// @Produce json 278// @Produce json
264// @Param id path int true "Chapter ID" 279// @Param id path int true "Chapter ID"
265// @Success 200 {object} models.Response{data=models.ChapterMapsResponse} 280// @Success 200 {object} models.Response{data=ChapterMapsResponse}
266// @Failure 400 {object} models.Response 281// @Failure 400 {object} models.Response
267// @Router /chapters/{id} [get] 282// @Router /chapters/{id} [get]
268func FetchChapterMaps(c *gin.Context) { 283func FetchChapterMaps(c *gin.Context) {
@@ -272,7 +287,7 @@ func FetchChapterMaps(c *gin.Context) {
272 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 287 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
273 return 288 return
274 } 289 }
275 var response models.ChapterMapsResponse 290 var response ChapterMapsResponse
276 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) 291 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)
277 if err != nil { 292 if err != nil {
278 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 293 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go
index e2add1f..7ce5cb4 100644
--- a/backend/controllers/modController.go
+++ b/backend/controllers/modController.go
@@ -3,21 +3,48 @@ package controllers
3import ( 3import (
4 "net/http" 4 "net/http"
5 "strconv" 5 "strconv"
6 "time"
6 7
7 "github.com/gin-gonic/gin" 8 "github.com/gin-gonic/gin"
8 "github.com/pektezol/leastportalshub/backend/database" 9 "github.com/pektezol/leastportalshub/backend/database"
9 "github.com/pektezol/leastportalshub/backend/models" 10 "github.com/pektezol/leastportalshub/backend/models"
10) 11)
11 12
13type CreateMapSummaryRequest struct {
14 CategoryID int `json:"category_id" binding:"required"`
15 Description string `json:"description" binding:"required"`
16 Showcase string `json:"showcase"`
17 UserName string `json:"user_name" binding:"required"`
18 ScoreCount *int `json:"score_count" binding:"required"`
19 RecordDate time.Time `json:"record_date" binding:"required"`
20}
21
22type EditMapSummaryRequest struct {
23 RouteID int `json:"route_id" binding:"required"`
24 Description string `json:"description" binding:"required"`
25 Showcase string `json:"showcase"`
26 UserName string `json:"user_name" binding:"required"`
27 ScoreCount *int `json:"score_count" binding:"required"`
28 RecordDate time.Time `json:"record_date" binding:"required"`
29}
30
31type DeleteMapSummaryRequest struct {
32 RouteID int `json:"route_id" binding:"required"`
33}
34
35type EditMapImageRequest struct {
36 Image string `json:"image" binding:"required"`
37}
38
12// POST Map Summary 39// POST Map Summary
13// 40//
14// @Description Create map summary with specified map id. 41// @Description Create map summary with specified map id.
15// @Tags maps 42// @Tags maps
16// @Produce json 43// @Produce json
17// @Param Authorization header string true "JWT Token" 44// @Param Authorization header string true "JWT Token"
18// @Param id path int true "Map ID" 45// @Param id path int true "Map ID"
19// @Param request body models.CreateMapSummaryRequest true "Body" 46// @Param request body CreateMapSummaryRequest true "Body"
20// @Success 200 {object} models.Response{data=models.CreateMapSummaryRequest} 47// @Success 200 {object} models.Response{data=CreateMapSummaryRequest}
21// @Failure 400 {object} models.Response 48// @Failure 400 {object} models.Response
22// @Router /maps/{id}/summary [post] 49// @Router /maps/{id}/summary [post]
23func CreateMapSummary(c *gin.Context) { 50func CreateMapSummary(c *gin.Context) {
@@ -44,7 +71,7 @@ func CreateMapSummary(c *gin.Context) {
44 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 71 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
45 return 72 return
46 } 73 }
47 var request models.CreateMapSummaryRequest 74 var request CreateMapSummaryRequest
48 if err := c.BindJSON(&request); err != nil { 75 if err := c.BindJSON(&request); err != nil {
49 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 76 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
50 return 77 return
@@ -100,10 +127,10 @@ func CreateMapSummary(c *gin.Context) {
100// @Description Edit map summary with specified map id. 127// @Description Edit map summary with specified map id.
101// @Tags maps 128// @Tags maps
102// @Produce json 129// @Produce json
103// @Param Authorization header string true "JWT Token" 130// @Param Authorization header string true "JWT Token"
104// @Param id path int true "Map ID" 131// @Param id path int true "Map ID"
105// @Param request body models.EditMapSummaryRequest true "Body" 132// @Param request body EditMapSummaryRequest true "Body"
106// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} 133// @Success 200 {object} models.Response{data=EditMapSummaryRequest}
107// @Failure 400 {object} models.Response 134// @Failure 400 {object} models.Response
108// @Router /maps/{id}/summary [put] 135// @Router /maps/{id}/summary [put]
109func EditMapSummary(c *gin.Context) { 136func EditMapSummary(c *gin.Context) {
@@ -130,7 +157,7 @@ func EditMapSummary(c *gin.Context) {
130 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 157 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
131 return 158 return
132 } 159 }
133 var request models.EditMapSummaryRequest 160 var request EditMapSummaryRequest
134 if err := c.BindJSON(&request); err != nil { 161 if err := c.BindJSON(&request); err != nil {
135 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 162 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
136 return 163 return
@@ -186,10 +213,10 @@ func EditMapSummary(c *gin.Context) {
186// @Description Delete map summary with specified map id. 213// @Description Delete map summary with specified map id.
187// @Tags maps 214// @Tags maps
188// @Produce json 215// @Produce json
189// @Param Authorization header string true "JWT Token" 216// @Param Authorization header string true "JWT Token"
190// @Param id path int true "Map ID" 217// @Param id path int true "Map ID"
191// @Param request body models.DeleteMapSummaryRequest true "Body" 218// @Param request body DeleteMapSummaryRequest true "Body"
192// @Success 200 {object} models.Response{data=models.DeleteMapSummaryRequest} 219// @Success 200 {object} models.Response{data=DeleteMapSummaryRequest}
193// @Failure 400 {object} models.Response 220// @Failure 400 {object} models.Response
194// @Router /maps/{id}/summary [delete] 221// @Router /maps/{id}/summary [delete]
195func DeleteMapSummary(c *gin.Context) { 222func DeleteMapSummary(c *gin.Context) {
@@ -216,7 +243,7 @@ func DeleteMapSummary(c *gin.Context) {
216 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 243 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
217 return 244 return
218 } 245 }
219 var request models.DeleteMapSummaryRequest 246 var request DeleteMapSummaryRequest
220 if err := c.BindJSON(&request); err != nil { 247 if err := c.BindJSON(&request); err != nil {
221 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 248 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
222 return 249 return
@@ -276,10 +303,10 @@ func DeleteMapSummary(c *gin.Context) {
276// @Description Edit map image with specified map id. 303// @Description Edit map image with specified map id.
277// @Tags maps 304// @Tags maps
278// @Produce json 305// @Produce json
279// @Param Authorization header string true "JWT Token" 306// @Param Authorization header string true "JWT Token"
280// @Param id path int true "Map ID" 307// @Param id path int true "Map ID"
281// @Param request body models.EditMapImageRequest true "Body" 308// @Param request body EditMapImageRequest true "Body"
282// @Success 200 {object} models.Response{data=models.EditMapImageRequest} 309// @Success 200 {object} models.Response{data=EditMapImageRequest}
283// @Failure 400 {object} models.Response 310// @Failure 400 {object} models.Response
284// @Router /maps/{id}/image [put] 311// @Router /maps/{id}/image [put]
285func EditMapImage(c *gin.Context) { 312func EditMapImage(c *gin.Context) {
@@ -306,7 +333,7 @@ func EditMapImage(c *gin.Context) {
306 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 333 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
307 return 334 return
308 } 335 }
309 var request models.EditMapImageRequest 336 var request EditMapImageRequest
310 if err := c.BindJSON(&request); err != nil { 337 if err := c.BindJSON(&request); err != nil {
311 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 338 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
312 return 339 return
diff --git a/backend/controllers/recordController.go b/backend/controllers/recordController.go
index 951be41..d141fc3 100644
--- a/backend/controllers/recordController.go
+++ b/backend/controllers/recordController.go
@@ -19,6 +19,18 @@ import (
19 "google.golang.org/api/drive/v3" 19 "google.golang.org/api/drive/v3"
20) 20)
21 21
22type RecordRequest struct {
23 HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"`
24 PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"`
25 IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange"`
26 PartnerID string `json:"partner_id" form:"partner_id"`
27}
28
29type RecordResponse struct {
30 ScoreCount int `json:"score_count"`
31 ScoreTime int `json:"score_time"`
32}
33
22// POST Record 34// POST Record
23// 35//
24// @Description Post record with demo of a specific map. 36// @Description Post record with demo of a specific map.
@@ -31,7 +43,7 @@ import (
31// @Param partner_demo formData file false "Partner Demo" 43// @Param partner_demo formData file false "Partner Demo"
32// @Param is_partner_orange formData boolean false "Is Partner Orange" 44// @Param is_partner_orange formData boolean false "Is Partner Orange"
33// @Param partner_id formData string false "Partner ID" 45// @Param partner_id formData string false "Partner ID"
34// @Success 200 {object} models.Response{data=models.RecordResponse} 46// @Success 200 {object} models.Response{data=RecordResponse}
35// @Failure 400 {object} models.Response 47// @Failure 400 {object} models.Response
36// @Failure 401 {object} models.Response 48// @Failure 401 {object} models.Response
37// @Router /maps/{id}/record [post] 49// @Router /maps/{id}/record [post]
@@ -61,7 +73,7 @@ func CreateRecordWithDemo(c *gin.Context) {
61 isCoop = true 73 isCoop = true
62 } 74 }
63 // Get record request 75 // Get record request
64 var record models.RecordRequest 76 var record RecordRequest
65 if err := c.ShouldBind(&record); err != nil { 77 if err := c.ShouldBind(&record); err != nil {
66 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 78 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
67 return 79 return
@@ -183,7 +195,7 @@ func CreateRecordWithDemo(c *gin.Context) {
183 c.JSON(http.StatusOK, models.Response{ 195 c.JSON(http.StatusOK, models.Response{
184 Success: true, 196 Success: true,
185 Message: "Successfully created record.", 197 Message: "Successfully created record.",
186 Data: models.RecordResponse{ScoreCount: hostDemoScoreCount, ScoreTime: hostDemoScoreTime}, 198 Data: RecordResponse{ScoreCount: hostDemoScoreCount, ScoreTime: hostDemoScoreTime},
187 }) 199 })
188} 200}
189 201
@@ -253,6 +265,7 @@ func serviceAccount() *http.Client {
253 return client 265 return client
254} 266}
255 267
268// Create Gdrive file
256func createFile(service *drive.Service, name string, mimeType string, content io.Reader, parentId string) (*drive.File, error) { 269func createFile(service *drive.Service, name string, mimeType string, content io.Reader, parentId string) (*drive.File, error) {
257 f := &drive.File{ 270 f := &drive.File{
258 MimeType: mimeType, 271 MimeType: mimeType,
@@ -269,6 +282,7 @@ func createFile(service *drive.Service, name string, mimeType string, content io
269 return file, nil 282 return file, nil
270} 283}
271 284
285// Delete Gdrive file
272func deleteFile(service *drive.Service, fileId string) { 286func deleteFile(service *drive.Service, fileId string) {
273 service.Files.Delete(fileId) 287 service.Files.Delete(fileId)
274} 288}
diff --git a/backend/controllers/userController.go b/backend/controllers/userController.go
index 6aa77fc..0dae155 100644
--- a/backend/controllers/userController.go
+++ b/backend/controllers/userController.go
@@ -11,6 +11,21 @@ import (
11 "github.com/pektezol/leastportalshub/backend/models" 11 "github.com/pektezol/leastportalshub/backend/models"
12) 12)
13 13
14type ProfileResponse struct {
15 Profile bool `json:"profile"`
16 SteamID string `json:"steam_id"`
17 UserName string `json:"user_name"`
18 AvatarLink string `json:"avatar_link"`
19 CountryCode string `json:"country_code"`
20 ScoresSP []ScoreResponse `json:"scores_sp"`
21 ScoresMP []ScoreResponse `json:"scores_mp"`
22}
23
24type ScoreResponse struct {
25 MapID int `json:"map_id"`
26 Records any `json:"records"`
27}
28
14// GET Profile 29// GET Profile
15// 30//
16// @Description Get profile page of session user. 31// @Description Get profile page of session user.
@@ -18,7 +33,7 @@ import (
18// @Accept json 33// @Accept json
19// @Produce json 34// @Produce json
20// @Param Authorization header string true "JWT Token" 35// @Param Authorization header string true "JWT Token"
21// @Success 200 {object} models.Response{data=models.ProfileResponse} 36// @Success 200 {object} models.Response{data=ProfileResponse}
22// @Failure 400 {object} models.Response 37// @Failure 400 {object} models.Response
23// @Failure 401 {object} models.Response 38// @Failure 401 {object} models.Response
24// @Router /profile [get] 39// @Router /profile [get]
@@ -30,7 +45,7 @@ func Profile(c *gin.Context) {
30 return 45 return
31 } 46 }
32 // Retrieve singleplayer records 47 // Retrieve singleplayer records
33 var scoresSP []models.ScoreResponse 48 var scoresSP []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` 49 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) 50 rows, err := database.DB.Query(sql, user.(models.User).SteamID)
36 if err != nil { 51 if err != nil {
@@ -50,13 +65,13 @@ func Profile(c *gin.Context) {
50 // New map 65 // New map
51 recordsSP = []models.RecordSP{} 66 recordsSP = []models.RecordSP{}
52 recordsSP = append(recordsSP, record) 67 recordsSP = append(recordsSP, record)
53 scoresSP = append(scoresSP, models.ScoreResponse{ 68 scoresSP = append(scoresSP, ScoreResponse{
54 MapID: mapID, 69 MapID: mapID,
55 Records: recordsSP, 70 Records: recordsSP,
56 }) 71 })
57 } 72 }
58 // Retrieve multiplayer records 73 // Retrieve multiplayer records
59 var scoresMP []models.ScoreResponse 74 var scoresMP []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 75 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` 76 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) 77 rows, err = database.DB.Query(sql, user.(models.User).SteamID, user.(models.User).SteamID)
@@ -77,7 +92,7 @@ func Profile(c *gin.Context) {
77 // New map 92 // New map
78 recordsMP = []models.RecordMP{} 93 recordsMP = []models.RecordMP{}
79 recordsMP = append(recordsMP, record) 94 recordsMP = append(recordsMP, record)
80 scoresMP = append(scoresMP, models.ScoreResponse{ 95 scoresMP = append(scoresMP, ScoreResponse{
81 MapID: mapID, 96 MapID: mapID,
82 Records: recordsMP, 97 Records: recordsMP,
83 }) 98 })
@@ -85,7 +100,7 @@ func Profile(c *gin.Context) {
85 c.JSON(http.StatusOK, models.Response{ 100 c.JSON(http.StatusOK, models.Response{
86 Success: true, 101 Success: true,
87 Message: "Successfully retrieved user scores.", 102 Message: "Successfully retrieved user scores.",
88 Data: models.ProfileResponse{ 103 Data: ProfileResponse{
89 Profile: true, 104 Profile: true,
90 SteamID: user.(models.User).SteamID, 105 SteamID: user.(models.User).SteamID,
91 UserName: user.(models.User).UserName, 106 UserName: user.(models.User).UserName,
@@ -105,7 +120,7 @@ func Profile(c *gin.Context) {
105// @Accept json 120// @Accept json
106// @Produce json 121// @Produce json
107// @Param id path int true "User ID" 122// @Param id path int true "User ID"
108// @Success 200 {object} models.Response{data=models.ProfileResponse} 123// @Success 200 {object} models.Response{data=ProfileResponse}
109// @Failure 400 {object} models.Response 124// @Failure 400 {object} models.Response
110// @Failure 404 {object} models.Response 125// @Failure 404 {object} models.Response
111// @Router /users/{id} [get] 126// @Router /users/{id} [get]
@@ -132,7 +147,7 @@ func FetchUser(c *gin.Context) {
132 return 147 return
133 } 148 }
134 // Retrieve singleplayer records 149 // Retrieve singleplayer records
135 var scoresSP []models.ScoreResponse 150 var scoresSP []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` 151 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) 152 rows, err := database.DB.Query(sql, user.SteamID)
138 if err != nil { 153 if err != nil {
@@ -152,13 +167,13 @@ func FetchUser(c *gin.Context) {
152 // New map 167 // New map
153 recordsSP = []models.RecordSP{} 168 recordsSP = []models.RecordSP{}
154 recordsSP = append(recordsSP, record) 169 recordsSP = append(recordsSP, record)
155 scoresSP = append(scoresSP, models.ScoreResponse{ 170 scoresSP = append(scoresSP, ScoreResponse{
156 MapID: mapID, 171 MapID: mapID,
157 Records: recordsSP, 172 Records: recordsSP,
158 }) 173 })
159 } 174 }
160 // Retrieve multiplayer records 175 // Retrieve multiplayer records
161 var scoresMP []models.ScoreResponse 176 var scoresMP []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 177 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` 178 WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id`
164 rows, err = database.DB.Query(sql, user.SteamID, user.SteamID) 179 rows, err = database.DB.Query(sql, user.SteamID, user.SteamID)
@@ -179,7 +194,7 @@ func FetchUser(c *gin.Context) {
179 // New map 194 // New map
180 recordsMP = []models.RecordMP{} 195 recordsMP = []models.RecordMP{}
181 recordsMP = append(recordsMP, record) 196 recordsMP = append(recordsMP, record)
182 scoresMP = append(scoresMP, models.ScoreResponse{ 197 scoresMP = append(scoresMP, ScoreResponse{
183 MapID: mapID, 198 MapID: mapID,
184 Records: recordsMP, 199 Records: recordsMP,
185 }) 200 })
@@ -187,7 +202,7 @@ func FetchUser(c *gin.Context) {
187 c.JSON(http.StatusOK, models.Response{ 202 c.JSON(http.StatusOK, models.Response{
188 Success: true, 203 Success: true,
189 Message: "Successfully retrieved user scores.", 204 Message: "Successfully retrieved user scores.",
190 Data: models.ProfileResponse{ 205 Data: ProfileResponse{
191 Profile: true, 206 Profile: true,
192 SteamID: user.SteamID, 207 SteamID: user.SteamID,
193 UserName: user.UserName, 208 UserName: user.UserName,
@@ -207,7 +222,7 @@ func FetchUser(c *gin.Context) {
207// @Accept json 222// @Accept json
208// @Produce json 223// @Produce json
209// @Param Authorization header string true "JWT Token" 224// @Param Authorization header string true "JWT Token"
210// @Success 200 {object} models.Response{data=models.ProfileResponse} 225// @Success 200 {object} models.Response{data=ProfileResponse}
211// @Failure 400 {object} models.Response 226// @Failure 400 {object} models.Response
212// @Failure 401 {object} models.Response 227// @Failure 401 {object} models.Response
213// @Router /profile [post] 228// @Router /profile [post]
@@ -233,7 +248,7 @@ func UpdateUser(c *gin.Context) {
233 c.JSON(http.StatusOK, models.Response{ 248 c.JSON(http.StatusOK, models.Response{
234 Success: true, 249 Success: true,
235 Message: "Successfully updated user.", 250 Message: "Successfully updated user.",
236 Data: models.ProfileResponse{ 251 Data: ProfileResponse{
237 Profile: true, 252 Profile: true,
238 SteamID: user.(models.User).SteamID, 253 SteamID: user.(models.User).SteamID,
239 UserName: profile.PersonaName, 254 UserName: profile.PersonaName,
diff --git a/backend/models/models.go b/backend/models/models.go
index 1231cb1..e21ba6a 100644
--- a/backend/models/models.go
+++ b/backend/models/models.go
@@ -4,6 +4,20 @@ import (
4 "time" 4 "time"
5) 5)
6 6
7type Response struct {
8 Success bool `json:"success"`
9 Message string `json:"message"`
10 Data any `json:"data"`
11}
12
13func ErrorResponse(message string) Response {
14 return Response{
15 Success: false,
16 Message: message,
17 Data: nil,
18 }
19}
20
7type User struct { 21type User struct {
8 SteamID string `json:"steam_id"` 22 SteamID string `json:"steam_id"`
9 UserName string `json:"user_name"` 23 UserName string `json:"user_name"`
diff --git a/backend/models/requests.go b/backend/models/requests.go
deleted file mode 100644
index 0113597..0000000
--- a/backend/models/requests.go
+++ /dev/null
@@ -1,39 +0,0 @@
1package models
2
3import (
4 "mime/multipart"
5 "time"
6)
7
8type CreateMapSummaryRequest struct {
9 CategoryID int `json:"category_id" binding:"required"`
10 Description string `json:"description" binding:"required"`
11 Showcase string `json:"showcase"`
12 UserName string `json:"user_name" binding:"required"`
13 ScoreCount *int `json:"score_count" binding:"required"`
14 RecordDate time.Time `json:"record_date" binding:"required"`
15}
16
17type EditMapSummaryRequest struct {
18 RouteID int `json:"route_id" binding:"required"`
19 Description string `json:"description" binding:"required"`
20 Showcase string `json:"showcase"`
21 UserName string `json:"user_name" binding:"required"`
22 ScoreCount *int `json:"score_count" binding:"required"`
23 RecordDate time.Time `json:"record_date" binding:"required"`
24}
25
26type DeleteMapSummaryRequest struct {
27 RouteID int `json:"route_id" binding:"required"`
28}
29
30type EditMapImageRequest struct {
31 Image string `json:"image" binding:"required"`
32}
33
34type RecordRequest struct {
35 HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"`
36 PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"`
37 IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange"`
38 PartnerID string `json:"partner_id" form:"partner_id"`
39}
diff --git a/backend/models/responses.go b/backend/models/responses.go
deleted file mode 100644
index 459911c..0000000
--- a/backend/models/responses.go
+++ /dev/null
@@ -1,64 +0,0 @@
1package models
2
3type Response struct {
4 Success bool `json:"success"`
5 Message string `json:"message"`
6 Data any `json:"data"`
7}
8
9type LoginResponse struct {
10 Token string `json:"token"`
11}
12
13type RankingsResponse struct {
14 RankingsSP []UserRanking `json:"rankings_sp"`
15 RankingsMP []UserRanking `json:"rankings_mp"`
16}
17
18type ProfileResponse struct {
19 Profile bool `json:"profile"`
20 SteamID string `json:"steam_id"`
21 UserName string `json:"user_name"`
22 AvatarLink string `json:"avatar_link"`
23 CountryCode string `json:"country_code"`
24 ScoresSP []ScoreResponse `json:"scores_sp"`
25 ScoresMP []ScoreResponse `json:"scores_mp"`
26}
27
28type ScoreResponse struct {
29 MapID int `json:"map_id"`
30 Records any `json:"records"`
31}
32
33type MapSummaryResponse struct {
34 Map Map `json:"map"`
35 Summary MapSummary `json:"summary"`
36}
37
38type SearchResponse struct {
39 Players []UserShort `json:"players"`
40 Maps []MapShort `json:"maps"`
41}
42
43type ChaptersResponse struct {
44 Game Game `json:"game"`
45 Chapters []Chapter `json:"chapters"`
46}
47
48type ChapterMapsResponse struct {
49 Chapter Chapter `json:"chapter"`
50 Maps []MapShort `json:"maps"`
51}
52
53type RecordResponse struct {
54 ScoreCount int `json:"score_count"`
55 ScoreTime int `json:"score_time"`
56}
57
58func ErrorResponse(message string) Response {
59 return Response{
60 Success: false,
61 Message: message,
62 Data: nil,
63 }
64}