This commit is contained in:
2026-05-29 00:46:12 -05:00
parent b7af98557c
commit dc4dc4eac4
9 changed files with 1790 additions and 42 deletions
Vendored
BIN
View File
Binary file not shown.
+7
View File
@@ -34,3 +34,10 @@ docs/restore_dump_remote.md
./docs/restore_dump_remote.md ./docs/restore_dump_remote.md
docs/notes/conversation_1.md docs/notes/conversation_1.md
docs/notes/conversation_2.md docs/notes/conversation_2.md
docs/kiro.md
docs/cloudflare.json
docs/notes
docs/postman
+12 -11
View File
@@ -45,7 +45,7 @@ A high-performance NBA statistics REST API built with Go (Fiber), PostgreSQL, an
## API Endpoints ## API Endpoints
| Method | Path | Description | | Method | Path | Description |
|--------|------|-------------| | ------ | -------------------------- | --------------------------------------------------------- |
| GET | `/api/games` | Game data with box scores, line scores, team/player stats | | GET | `/api/games` | Game data with box scores, line scores, team/player stats |
| GET | `/api/playeradvancedstats` | Advanced stats (PER, WS, VORP, BPM, etc.) | | GET | `/api/playeradvancedstats` | Advanced stats (PER, WS, VORP, BPM, etc.) |
| GET | `/api/playertotals` | Season totals (points, rebounds, assists, etc.) | | GET | `/api/playertotals` | Season totals (points, rebounds, assists, etc.) |
@@ -57,7 +57,7 @@ A high-performance NBA statistics REST API built with Go (Fiber), PostgreSQL, an
### Query Parameters (all data endpoints) ### Query Parameters (all data endpoints)
| Parameter | Type | Description | | Parameter | Type | Description |
|-----------|------|-------------| | ----------- | ------ | -------------------------------------------- |
| `page` | int | Page number (default: 1) | | `page` | int | Page number (default: 1) |
| `pageSize` | int | Results per page (default: 20) | | `pageSize` | int | Results per page (default: 20) |
| `sortBy` | string | Field to sort by (varies per endpoint) | | `sortBy` | string | Field to sort by (varies per endpoint) |
@@ -70,7 +70,7 @@ A high-performance NBA statistics REST API built with Go (Fiber), PostgreSQL, an
#### Games-specific parameters #### Games-specific parameters
| Parameter | Type | Description | | Parameter | Type | Description |
|-----------|------|-------------| | --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `date` | string | Filter by date (YYYY-MM-DD) | | `date` | string | Filter by date (YYYY-MM-DD) |
| `gameId` | string | Filter by specific game ID | | `gameId` | string | Filter by specific game ID |
| `include` | string | Comma-separated associations to preload: `lineScores`, `playerGameBasicStats`, `playerGameAdvStats`, `teamGameBasicStats`, `teamGameAdvStats` | | `include` | string | Comma-separated associations to preload: `lineScores`, `playerGameBasicStats`, `playerGameAdvStats`, `teamGameBasicStats`, `teamGameAdvStats` |
@@ -150,13 +150,13 @@ make up
Services will be available at: Services will be available at:
| Service | URL | | Service | URL |
|---------|-----| | ----------------------- | --------------------------------------- |
| API (via NGINX) | http://localhost:8081 | | API (via NGINX) | <http://localhost:8081> |
| Prometheus | http://localhost:9090 | | Prometheus | <http://localhost:9090> |
| Grafana | http://localhost:3001 (admin/testing) | | Grafana | <http://localhost:3001> (admin/testing) |
| API instance 1 (direct) | http://localhost:5001 | | API instance 1 (direct) | <http://localhost:5001> |
| API instance 2 (direct) | http://localhost:5002 | | API instance 2 (direct) | <http://localhost:5002> |
| API instance 3 (direct) | http://localhost:5003 | | API instance 3 (direct) | <http://localhost:5003> |
### Importing Data ### Importing Data
@@ -167,6 +167,7 @@ docker-compose -f docker-compose.local.yml run --rm db-init
``` ```
This runs `main.go` with the `import-data` argument, which: This runs `main.go` with the `import-data` argument, which:
1. Runs all GORM AutoMigrate operations 1. Runs all GORM AutoMigrate operations
2. Scrapes Basketball Reference for player advanced stats, totals, game schedules, and box scores 2. Scrapes Basketball Reference for player advanced stats, totals, game schedules, and box scores
3. Upserts all data into PostgreSQL 3. Upserts all data into PostgreSQL
@@ -239,7 +240,7 @@ go run loadtest.go -n 100 -c 10 -url "http://localhost:8080/api/playeradvancedst
## Tech Stack ## Tech Stack
| Component | Technology | | Component | Technology |
|-----------|-----------| | ---------------- | ----------------------- |
| Language | Go 1.23+ | | Language | Go 1.23+ |
| Framework | Fiber v2 | | Framework | Fiber v2 |
| ORM | GORM | | ORM | GORM |
+3
View File
@@ -240,6 +240,9 @@ func GetGames(db *gorm.DB) fiber.Handler {
page := c.QueryInt("page", 1) page := c.QueryInt("page", 1)
pageSize := c.QueryInt("pageSize", 20) pageSize := c.QueryInt("pageSize", 20)
if pageSize > 50 {
pageSize = 50
}
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
var games []models.Game var games []models.Game
@@ -150,6 +150,9 @@ func GetAllAdvancedPlayerStats(db *gorm.DB) fiber.Handler {
// --- PAGINATION --- // --- PAGINATION ---
page := c.QueryInt("page", 1) page := c.QueryInt("page", 1)
pageSize := c.QueryInt("pageSize", 20) pageSize := c.QueryInt("pageSize", 20)
if pageSize > 50 {
pageSize = 50
}
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
// --- SORTING --- // --- SORTING ---
+3
View File
@@ -150,6 +150,9 @@ func GetPlayerTotalStats(db *gorm.DB) fiber.Handler {
team := c.Query("team") team := c.Query("team")
page := c.QueryInt("page", 1) page := c.QueryInt("page", 1)
pageSize := c.QueryInt("pageSize", 20) pageSize := c.QueryInt("pageSize", 20)
if pageSize > 50 {
pageSize = 50
}
// --- SORTING --- // --- SORTING ---
sortByParam := c.Query("sortBy", "points") sortByParam := c.Query("sortBy", "points")
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
+66
View File
@@ -0,0 +1,66 @@
cat > /data/nba-go-config/nginx/nginx.conf << 'EOF'
user nginx;
events {
worker_connections 1024;
}
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=100m inactive=5m;
map $http_referer $blocked_referer {
default 0;
"~*nbasalarymodel\.xyz" 1;
"~*kacpertheater\.github\.io" 1;
}
upstream go_backend {
server api1:5000;
server api2:5000;
server api3:5000;
}
server {
listen 8080;
access_log /dev/stdout;
error_log /dev/stderr;
if ($blocked_referer) {
return 403;
}
location /api/ {
proxy_cache api_cache;
proxy_cache_valid 200 30s;
proxy_cache_key "$request_uri";
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://go_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://go_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
EOF
docker exec 4c3368863bdc nginx -s reload