mirror of
https://github.com/nprasad2077/NBA_Go.git
synced 2026-09-22 14:05:13 +00:00
advanced models/controllers/service docs update
This commit is contained in:
@@ -3,17 +3,31 @@ package controllers
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gorm.io/gorm"
|
||||
"github.com/nprasad2077/NBA_Go/services"
|
||||
|
||||
"github.com/nprasad2077/NBA_Go/models"
|
||||
"github.com/nprasad2077/NBA_Go/services"
|
||||
)
|
||||
|
||||
// AdvancedStatsResponse is the swagger response model for GetAllAdvancedPlayerStats
|
||||
// It wraps the returned player advanced stats and pagination metadata.
|
||||
type AdvancedStatsResponse struct {
|
||||
Data []models.PlayerAdvancedStat `json:"data"`
|
||||
Pagination struct {
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
Pages int64 `json:"pages"`
|
||||
} `json:"pagination"`
|
||||
}
|
||||
|
||||
// FetchPlayerAdvancedStats returns a handler that imports advanced stats for a season
|
||||
// Note: not exposed in Swagger docs, only internal use.
|
||||
func FetchPlayerAdvancedStats(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
season := c.QueryInt("season", 2025)
|
||||
isPlayoff := c.QueryBool("isPlayoff", false)
|
||||
|
||||
// Call service and assign err here
|
||||
err := services.FetchAndStorePlayerAdvancedStats(db, season)
|
||||
if err != nil {
|
||||
if err := services.FetchAndStorePlayerAdvancedStats(db, season, isPlayoff); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
@@ -21,12 +35,10 @@ func FetchPlayerAdvancedStats(db *gorm.DB) fiber.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// GetAllPlayerStats godoc
|
||||
// GetAllAdvancedPlayerStats godoc
|
||||
// @Security ApiKeyAuth
|
||||
// @Summary Get player stats
|
||||
// @Description Returns filtered and paginated player stats
|
||||
// @Summary Get player advanced stats
|
||||
// @Description Returns filtered and paginated player advanced stats
|
||||
// @Tags PlayerStats
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
@@ -35,9 +47,11 @@ func FetchPlayerAdvancedStats(db *gorm.DB) fiber.Handler {
|
||||
// @Param playerId query string false "Player ID (e.g., greenaj01)"
|
||||
// @Param page query int false "Page number" default(1)
|
||||
// @Param pageSize query int false "Page size" default(20)
|
||||
// @Param sortBy query string false "Field to sort by (e.g., per, games, winShares)"
|
||||
// @Param ascending query bool false "Sort ascending (default false)"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Param sortBy query string false "Field to sort by" default(winShares)
|
||||
// @Param ascending query bool false "Sort ascending" default(false)
|
||||
// @Param isPlayoff query bool false "Whether playoffs?"
|
||||
// @Success 200 {object} controllers.AdvancedStatsResponse
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /api/playeradvancedstats [get]
|
||||
func GetAllAdvancedPlayerStats(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
@@ -54,7 +68,7 @@ func GetAllAdvancedPlayerStats(db *gorm.DB) fiber.Handler {
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
// Sorting
|
||||
sortBy := c.Query("sortBy", "win_shares") // default field
|
||||
sortBy := c.Query("sortBy", "win_shares")
|
||||
ascending := c.QueryBool("ascending", false)
|
||||
order := sortBy + " DESC"
|
||||
if ascending {
|
||||
@@ -74,23 +88,28 @@ func GetAllAdvancedPlayerStats(db *gorm.DB) fiber.Handler {
|
||||
query = query.Where("player_id = ?", playerId)
|
||||
}
|
||||
|
||||
var total int64
|
||||
query.Count(&total) // get total count before pagination
|
||||
if c.Query("isPlayoff") != "" {
|
||||
isPlayoff := c.QueryBool("isPlayoff", false)
|
||||
query = query.Where("is_playoff = ?", isPlayoff)
|
||||
}
|
||||
|
||||
// Count total
|
||||
var total int64
|
||||
query.Count(&total)
|
||||
|
||||
// Fetch page
|
||||
err := query.Order(order).Limit(pageSize).Offset(offset).Find(&stats).Error
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
// Response with metadata
|
||||
return c.JSON(fiber.Map{
|
||||
"data": stats,
|
||||
"pagination": fiber.Map{
|
||||
"total": total,
|
||||
"page": page,
|
||||
"pageSize": pageSize,
|
||||
"pages": (total + int64(pageSize) - 1) / int64(pageSize),
|
||||
},
|
||||
})
|
||||
// Build response
|
||||
resp := AdvancedStatsResponse{Data: stats}
|
||||
resp.Pagination.Total = total
|
||||
resp.Pagination.Page = page
|
||||
resp.Pagination.PageSize = pageSize
|
||||
resp.Pagination.Pages = (total + int64(pageSize) - 1) / int64(pageSize)
|
||||
|
||||
return c.JSON(resp)
|
||||
}
|
||||
}
|
||||
+167
-5
@@ -22,7 +22,7 @@ const docTemplate = `{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Returns filtered and paginated player stats",
|
||||
"description": "Returns filtered and paginated player advanced stats",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -32,7 +32,7 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"PlayerStats"
|
||||
],
|
||||
"summary": "Get player stats",
|
||||
"summary": "Get player advanced stats",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
@@ -68,23 +68,39 @@ const docTemplate = `{
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Field to sort by (e.g., per, games, winShares)",
|
||||
"default": "winShares",
|
||||
"description": "Field to sort by",
|
||||
"name": "sortBy",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Sort ascending (default false)",
|
||||
"default": false,
|
||||
"description": "Sort ascending",
|
||||
"name": "ascending",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Whether playoffs?",
|
||||
"name": "isPlayoff",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.AdvancedStatsResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +197,152 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"controllers.AdvancedStatsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.PlayerAdvancedStat"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pages": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gorm.DeletedAt": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"time": {
|
||||
"type": "string"
|
||||
},
|
||||
"valid": {
|
||||
"description": "Valid is true if Time is not NULL",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.PlayerAdvancedStat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {
|
||||
"type": "integer"
|
||||
},
|
||||
"assistPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"blockPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"box": {
|
||||
"type": "number"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"defensiveBox": {
|
||||
"type": "number"
|
||||
},
|
||||
"defensiveRBPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"defensiveWS": {
|
||||
"type": "number"
|
||||
},
|
||||
"deletedAt": {
|
||||
"$ref": "#/definitions/gorm.DeletedAt"
|
||||
},
|
||||
"ftr": {
|
||||
"type": "number"
|
||||
},
|
||||
"games": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"isPlayoff": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"minutesPlayed": {
|
||||
"type": "integer"
|
||||
},
|
||||
"offensiveBox": {
|
||||
"type": "number"
|
||||
},
|
||||
"offensiveRBPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"offensiveWS": {
|
||||
"type": "number"
|
||||
},
|
||||
"per": {
|
||||
"type": "number"
|
||||
},
|
||||
"playerId": {
|
||||
"type": "string"
|
||||
},
|
||||
"playerName": {
|
||||
"type": "string"
|
||||
},
|
||||
"position": {
|
||||
"type": "string"
|
||||
},
|
||||
"season": {
|
||||
"type": "integer"
|
||||
},
|
||||
"stealPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"team": {
|
||||
"type": "string"
|
||||
},
|
||||
"threePAR": {
|
||||
"type": "number"
|
||||
},
|
||||
"totalRBPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"tsPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"turnoverPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"usagePercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"vorp": {
|
||||
"type": "number"
|
||||
},
|
||||
"winShares": {
|
||||
"type": "number"
|
||||
},
|
||||
"winSharesPer": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"ApiKeyAuth": {
|
||||
"type": "apiKey",
|
||||
|
||||
+167
-5
@@ -19,7 +19,7 @@
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Returns filtered and paginated player stats",
|
||||
"description": "Returns filtered and paginated player advanced stats",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -29,7 +29,7 @@
|
||||
"tags": [
|
||||
"PlayerStats"
|
||||
],
|
||||
"summary": "Get player stats",
|
||||
"summary": "Get player advanced stats",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
@@ -65,23 +65,39 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Field to sort by (e.g., per, games, winShares)",
|
||||
"default": "winShares",
|
||||
"description": "Field to sort by",
|
||||
"name": "sortBy",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Sort ascending (default false)",
|
||||
"default": false,
|
||||
"description": "Sort ascending",
|
||||
"name": "ascending",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Whether playoffs?",
|
||||
"name": "isPlayoff",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.AdvancedStatsResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,6 +194,152 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"controllers.AdvancedStatsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.PlayerAdvancedStat"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"pages": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gorm.DeletedAt": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"time": {
|
||||
"type": "string"
|
||||
},
|
||||
"valid": {
|
||||
"description": "Valid is true if Time is not NULL",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.PlayerAdvancedStat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {
|
||||
"type": "integer"
|
||||
},
|
||||
"assistPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"blockPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"box": {
|
||||
"type": "number"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"defensiveBox": {
|
||||
"type": "number"
|
||||
},
|
||||
"defensiveRBPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"defensiveWS": {
|
||||
"type": "number"
|
||||
},
|
||||
"deletedAt": {
|
||||
"$ref": "#/definitions/gorm.DeletedAt"
|
||||
},
|
||||
"ftr": {
|
||||
"type": "number"
|
||||
},
|
||||
"games": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"isPlayoff": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"minutesPlayed": {
|
||||
"type": "integer"
|
||||
},
|
||||
"offensiveBox": {
|
||||
"type": "number"
|
||||
},
|
||||
"offensiveRBPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"offensiveWS": {
|
||||
"type": "number"
|
||||
},
|
||||
"per": {
|
||||
"type": "number"
|
||||
},
|
||||
"playerId": {
|
||||
"type": "string"
|
||||
},
|
||||
"playerName": {
|
||||
"type": "string"
|
||||
},
|
||||
"position": {
|
||||
"type": "string"
|
||||
},
|
||||
"season": {
|
||||
"type": "integer"
|
||||
},
|
||||
"stealPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"team": {
|
||||
"type": "string"
|
||||
},
|
||||
"threePAR": {
|
||||
"type": "number"
|
||||
},
|
||||
"totalRBPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"tsPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"turnoverPercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
},
|
||||
"usagePercent": {
|
||||
"type": "number"
|
||||
},
|
||||
"vorp": {
|
||||
"type": "number"
|
||||
},
|
||||
"winShares": {
|
||||
"type": "number"
|
||||
},
|
||||
"winSharesPer": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"ApiKeyAuth": {
|
||||
"type": "apiKey",
|
||||
|
||||
+112
-5
@@ -1,4 +1,100 @@
|
||||
basePath: /
|
||||
definitions:
|
||||
controllers.AdvancedStatsResponse:
|
||||
properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/definitions/models.PlayerAdvancedStat'
|
||||
type: array
|
||||
pagination:
|
||||
properties:
|
||||
page:
|
||||
type: integer
|
||||
pageSize:
|
||||
type: integer
|
||||
pages:
|
||||
type: integer
|
||||
total:
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
gorm.DeletedAt:
|
||||
properties:
|
||||
time:
|
||||
type: string
|
||||
valid:
|
||||
description: Valid is true if Time is not NULL
|
||||
type: boolean
|
||||
type: object
|
||||
models.PlayerAdvancedStat:
|
||||
properties:
|
||||
age:
|
||||
type: integer
|
||||
assistPercent:
|
||||
type: number
|
||||
blockPercent:
|
||||
type: number
|
||||
box:
|
||||
type: number
|
||||
createdAt:
|
||||
type: string
|
||||
defensiveBox:
|
||||
type: number
|
||||
defensiveRBPercent:
|
||||
type: number
|
||||
defensiveWS:
|
||||
type: number
|
||||
deletedAt:
|
||||
$ref: '#/definitions/gorm.DeletedAt'
|
||||
ftr:
|
||||
type: number
|
||||
games:
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
isPlayoff:
|
||||
type: boolean
|
||||
minutesPlayed:
|
||||
type: integer
|
||||
offensiveBox:
|
||||
type: number
|
||||
offensiveRBPercent:
|
||||
type: number
|
||||
offensiveWS:
|
||||
type: number
|
||||
per:
|
||||
type: number
|
||||
playerId:
|
||||
type: string
|
||||
playerName:
|
||||
type: string
|
||||
position:
|
||||
type: string
|
||||
season:
|
||||
type: integer
|
||||
stealPercent:
|
||||
type: number
|
||||
team:
|
||||
type: string
|
||||
threePAR:
|
||||
type: number
|
||||
totalRBPercent:
|
||||
type: number
|
||||
tsPercent:
|
||||
type: number
|
||||
turnoverPercent:
|
||||
type: number
|
||||
updatedAt:
|
||||
type: string
|
||||
usagePercent:
|
||||
type: number
|
||||
vorp:
|
||||
type: number
|
||||
winShares:
|
||||
type: number
|
||||
winSharesPer:
|
||||
type: number
|
||||
type: object
|
||||
info:
|
||||
contact: {}
|
||||
description: Stats service with API-key auth
|
||||
@@ -9,7 +105,7 @@ paths:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Returns filtered and paginated player stats
|
||||
description: Returns filtered and paginated player advanced stats
|
||||
parameters:
|
||||
- description: Season (e.g., 2025)
|
||||
in: query
|
||||
@@ -33,25 +129,36 @@ paths:
|
||||
in: query
|
||||
name: pageSize
|
||||
type: integer
|
||||
- description: Field to sort by (e.g., per, games, winShares)
|
||||
- default: winShares
|
||||
description: Field to sort by
|
||||
in: query
|
||||
name: sortBy
|
||||
type: string
|
||||
- description: Sort ascending (default false)
|
||||
- default: false
|
||||
description: Sort ascending
|
||||
in: query
|
||||
name: ascending
|
||||
type: boolean
|
||||
- description: Whether playoffs?
|
||||
in: query
|
||||
name: isPlayoff
|
||||
type: boolean
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
additionalProperties: true
|
||||
$ref: '#/definitions/controllers.AdvancedStatsResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get player stats
|
||||
summary: Get player advanced stats
|
||||
tags:
|
||||
- PlayerStats
|
||||
/api/playertotals:
|
||||
|
||||
@@ -11,7 +11,18 @@ import (
|
||||
// importPlayerAdvanced fetches and stores advanced stats for seasons 2023–2025
|
||||
func importPlayerAdvanced(db *gorm.DB) {
|
||||
for season := 2023; season <= 2025; season++ {
|
||||
if err := services.FetchAndStorePlayerAdvancedStats(db, season); err != nil {
|
||||
if err := services.FetchAndStorePlayerAdvancedStats(db, season, false); err != nil {
|
||||
log.Printf("advanced import failed for %d: %v", season, err)
|
||||
}
|
||||
time.Sleep(1100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// importPlayerAdvancedPlayoffs fetches and stores advanced stats for playoffs seasons 2023–2025
|
||||
|
||||
func importPlayerAdvancedPlayoffs (db *gorm.DB) {
|
||||
for season := 2023; season <= 2024; season++ {
|
||||
if err := services.FetchAndStorePlayerAdvancedPlayoffsStats(db, season, true); err != nil {
|
||||
log.Printf("advanced import failed for %d: %v", season, err)
|
||||
}
|
||||
time.Sleep(1100 * time.Millisecond)
|
||||
|
||||
@@ -38,6 +38,8 @@ func main() {
|
||||
db := config.InitDB()
|
||||
importPlayerAdvanced(db)
|
||||
log.Println("🎉 Player Advanced Import completed successfully")
|
||||
importPlayerAdvancedPlayoffs(db)
|
||||
log.Println("🎉 Player Advanced Playoffs Import completed successfully")
|
||||
importPlayerTotals(db)
|
||||
log.Println("🎉 Player Totals Import completed successfully")
|
||||
importPlayerPlayoffs(db)
|
||||
|
||||
@@ -5,7 +5,7 @@ import "gorm.io/gorm"
|
||||
type PlayerAdvancedStat struct {
|
||||
gorm.Model
|
||||
ExternalID int `json:"id"`
|
||||
PlayerID string `gorm:"not null;uniqueIndex:idx_player_season_team" json:"playerId"`
|
||||
PlayerID string `gorm:"not null;index:idx_player_season_team,unique" json:"playerId"`
|
||||
PlayerName string `json:"playerName"`
|
||||
Position string `json:"position"`
|
||||
Age int `json:"age"`
|
||||
@@ -31,7 +31,7 @@ type PlayerAdvancedStat struct {
|
||||
DefensiveBox float64 `json:"defensiveBox"`
|
||||
Box float64 `json:"box"`
|
||||
VORP float64 `json:"vorp"`
|
||||
Team string `gorm:"not null;uniqueIndex:idx_player_season_team" json:"team"`
|
||||
Season int `gorm:"not null;uniqueIndex:idx_player_season_team" json:"season"`
|
||||
isPlayoff bool `gorm:"not null;default:false;uniqueIndex:idx_player_season_team" json:"isPlayoff"`
|
||||
Team string `gorm:"not null;index:idx_player_season_team,unique" json:"team"`
|
||||
Season int `gorm:"not null;index:idx_player_season_team,unique" json:"season"`
|
||||
IsPlayoff bool `gorm:"not null;default:false;index:idx_player_season_team,unique" json:"isPlayoff"`
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"github.com/nprasad2077/NBA_Go/models"
|
||||
"github.com/nprasad2077/NBA_Go/utils"
|
||||
"github.com/nprasad2077/NBA_Go/utils/metrics"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func FetchAndStorePlayerAdvancedPlayoffsStats(db *gorm.DB, season int, isPlayoff bool) error {
|
||||
metrics.DBOperationsTotal.WithLabelValues("fetch", "player_advanced").Inc()
|
||||
url := fmt.Sprintf("http://rest.nbaapi.com/api/PlayerDataAdvancedPlayoffs/query?season=%d&sortBy=PlayerName&ascending=true&pageNumber=1&pageSize=1000", season)
|
||||
|
||||
body, err := utils.GetJSON(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var stats []models.PlayerAdvancedStat
|
||||
if err := json.Unmarshal(body, &stats); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, stat := range stats {
|
||||
// Ensure the season is included from the query param
|
||||
stat.Season = season
|
||||
stat.IsPlayoff = isPlayoff
|
||||
|
||||
err := db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "player_id"}, {Name: "season"}, {Name: "team"}, {Name: "is_playoff"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{
|
||||
"external_id", "player_name", "position", "age", "games",
|
||||
"minutes_played", "per", "ts_percent", "three_par", "ftr",
|
||||
"offensive_rb_percent", "defensive_rb_percent", "total_rb_percent",
|
||||
"assist_percent", "steal_percent", "block_percent", "turnover_percent",
|
||||
"usage_percent", "offensive_ws", "defensive_ws", "win_shares",
|
||||
"win_shares_per", "offensive_box", "defensive_box", "box", "vorp",
|
||||
}),
|
||||
}).Create(&stat).Error
|
||||
|
||||
metrics.DBOperationsTotal.WithLabelValues("store", "player_advanced").Inc()
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to upsert stat for playerId %s (%s): %v", stat.PlayerID, stat.Team, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func FetchAndStorePlayerAdvancedStats(db *gorm.DB, season int) error {
|
||||
func FetchAndStorePlayerAdvancedStats(db *gorm.DB, season int, isPlayoff bool) error {
|
||||
metrics.DBOperationsTotal.WithLabelValues("fetch", "player_advanced").Inc()
|
||||
url := fmt.Sprintf("http://rest.nbaapi.com/api/PlayerDataAdvanced/query?season=%d&sortBy=Points&ascending=false&pageNumber=1&pageSize=1000", season)
|
||||
|
||||
@@ -28,9 +28,10 @@ func FetchAndStorePlayerAdvancedStats(db *gorm.DB, season int) error {
|
||||
for _, stat := range stats {
|
||||
// Ensure the season is included from the query param
|
||||
stat.Season = season
|
||||
stat.IsPlayoff = isPlayoff
|
||||
|
||||
err := db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "player_id"}, {Name: "season"}, {Name: "team"}},
|
||||
Columns: []clause.Column{{Name: "player_id"}, {Name: "season"}, {Name: "team"}, {Name: "is_playoff"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{
|
||||
"external_id", "player_name", "position", "age", "games",
|
||||
"minutes_played", "per", "ts_percent", "three_par", "ftr",
|
||||
|
||||
@@ -44,7 +44,7 @@ func FetchAndStorePlayerTotalPlayoffsStats(db *gorm.DB, season int, isPlayoff bo
|
||||
}).Create(&stat).Error
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to upsert PlayerTotalStat for playerId %s: %v", stat.PlayerID, err)
|
||||
log.Printf("Failed to upsert PlayerTotalPlayoffStat for playerId %s: %v", stat.PlayerID, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user