Add world record support
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
75
docs/docs.go
75
docs/docs.go
@@ -282,6 +282,81 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/time/worldrecord": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get a list of world records sorted by most recent first",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"times"
|
||||
],
|
||||
"summary": "Get world records",
|
||||
"parameters": [
|
||||
{
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
"type": "integer",
|
||||
"default": 10,
|
||||
"description": "Page size (max 100)",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"minimum": 1,
|
||||
"type": "integer",
|
||||
"default": 1,
|
||||
"description": "Page number",
|
||||
"name": "page_number",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "game_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "map_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "mode_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "style_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "user_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/PagedResponse-Time"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "General error response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/time/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
||||
@@ -275,6 +275,81 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/time/worldrecord": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get a list of world records sorted by most recent first",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"times"
|
||||
],
|
||||
"summary": "Get world records",
|
||||
"parameters": [
|
||||
{
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
"type": "integer",
|
||||
"default": 10,
|
||||
"description": "Page size (max 100)",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"minimum": 1,
|
||||
"type": "integer",
|
||||
"default": 1,
|
||||
"description": "Page number",
|
||||
"name": "page_number",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "game_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "map_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "mode_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "style_id",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "user_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/PagedResponse-Time"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "General error response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/time/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
||||
@@ -372,6 +372,54 @@ paths:
|
||||
summary: Get time by ID
|
||||
tags:
|
||||
- times
|
||||
/time/worldrecord:
|
||||
get:
|
||||
description: Get a list of world records sorted by most recent first
|
||||
parameters:
|
||||
- default: 10
|
||||
description: Page size (max 100)
|
||||
in: query
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
name: page_size
|
||||
type: integer
|
||||
- default: 1
|
||||
description: Page number
|
||||
in: query
|
||||
minimum: 1
|
||||
name: page_number
|
||||
type: integer
|
||||
- in: query
|
||||
name: game_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: map_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: mode_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: style_id
|
||||
type: integer
|
||||
- in: query
|
||||
name: user_id
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/PagedResponse-Time'
|
||||
default:
|
||||
description: General error response
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get world records
|
||||
tags:
|
||||
- times
|
||||
/user:
|
||||
get:
|
||||
description: Get a list of users
|
||||
|
||||
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.24.0
|
||||
|
||||
require (
|
||||
git.itzana.me/StrafesNET/dev-service v0.0.0-20250622175817-762eaef1771e
|
||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250622145054-0c0eb0ba26c7
|
||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250624032225-d34f2a27787e
|
||||
github.com/gin-gonic/gin v1.10.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/swaggo/files v1.0.1
|
||||
|
||||
2
go.sum
2
go.sum
@@ -4,6 +4,8 @@ git.itzana.me/StrafesNET/dev-service v0.0.0-20250622175817-762eaef1771e h1:XItsI
|
||||
git.itzana.me/StrafesNET/dev-service v0.0.0-20250622175817-762eaef1771e/go.mod h1:F2M16jggvrfNCQLLxsVgNzwsgWZyev8jXcDCq1BMAnc=
|
||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250622145054-0c0eb0ba26c7 h1:k6Skqr00NOo9Do9Z5rxqzRSR+1BR/bY93+Lf86QlFV8=
|
||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250622145054-0c0eb0ba26c7/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
|
||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250624032225-d34f2a27787e h1:zU81WAvEKckjrooheDYMFMwuHrheIdnscXjS2Si6PmU=
|
||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250624032225-d34f2a27787e/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
|
||||
@@ -160,3 +160,79 @@ func (h *TimesHandler) List(ctx *gin.Context) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Get world records
|
||||
// @Description Get a list of world records sorted by most recent first
|
||||
// @Tags times
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param page_size query int false "Page size (max 100)" default(10) minimum(1) maximum(100)
|
||||
// @Param page_number query int false "Page number" default(1) minimum(1)
|
||||
// @Param filter query dto.TimeFilter false "Time filter parameters"
|
||||
// @Success 200 {object} dto.PagedResponse[dto.TimeData]
|
||||
// @Failure default {object} dto.Error "General error response"
|
||||
// @Router /time/worldrecord [get]
|
||||
func (h *TimesHandler) WrList(ctx *gin.Context) {
|
||||
// Extract and constrain pagination parameters
|
||||
query := struct {
|
||||
PageSize int `form:"page_size,default=10" binding:"min=1,max=100"`
|
||||
PageNumber int `form:"page_number,default=1" binding:"min=1"`
|
||||
}{}
|
||||
if err := ctx.ShouldBindQuery(&query); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, dto.Error{
|
||||
Error: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get list filter
|
||||
var filter dto.TimeFilter
|
||||
if err := ctx.ShouldBindQuery(&filter); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, dto.Error{
|
||||
Error: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call the gRPC service
|
||||
timeList, err := times.NewTimesServiceClient(h.dataClient).ListWr(ctx, ×.WrListRequest{
|
||||
Filter: ×.TimeFilter{
|
||||
UserID: filter.UserID,
|
||||
MapID: filter.MapID,
|
||||
ModeID: filter.ModeID,
|
||||
StyleID: filter.StyleID,
|
||||
GameID: filter.GameID,
|
||||
},
|
||||
Page: ×.Pagination{
|
||||
Size: int32(query.PageSize),
|
||||
Number: int32(query.PageNumber),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, dto.Error{
|
||||
Error: "Failed to list world records",
|
||||
})
|
||||
log.WithError(err).Error(
|
||||
"Failed to list world records",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Convert gRPC TimeResponse objects to dto.TimeData objects
|
||||
dtoTimes := make([]dto.TimeData, len(timeList.Times))
|
||||
for i, t := range timeList.Times {
|
||||
var time dto.TimeData
|
||||
dtoTimes[i] = *time.FromGRPC(t)
|
||||
}
|
||||
|
||||
// Return the paged response
|
||||
ctx.JSON(http.StatusOK, dto.PagedResponse[dto.TimeData]{
|
||||
Data: dtoTimes,
|
||||
Pagination: dto.Pagination{
|
||||
Page: query.PageNumber,
|
||||
PageSize: query.PageSize,
|
||||
TotalItems: int(timeList.Total),
|
||||
TotalPages: int(math.Ceil(float64(timeList.Total) / float64(query.PageSize))),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ func setupRoutes(cfg *RouterConfig) (*gin.Engine, error) {
|
||||
|
||||
// Times
|
||||
v1.GET("/time", timesHandler.List)
|
||||
v1.GET("/time/worldrecord", timesHandler.WrList)
|
||||
v1.GET("/time/:id", timesHandler.Get)
|
||||
|
||||
// Users
|
||||
|
||||
Reference in New Issue
Block a user