Skip to content

mpokumt/playermarketstats

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Player Market Stats

A full-stack TypeScript application for managing and analyzing basketball player prop markets, backed by a MySQL database and exposed via a REST API.

πŸ“Œ Overview

Player Market Stats is a monorepo containing:

  • A Node.js + Express backend (TypeScript)
  • A React + Vite frontend (TypeScript)
  • A MySQL database (Dockerized)

The system models player statistics markets (e.g., points, assists, rebounds) and provides filtering, querying, and suspension controls for betting-style market lines.

πŸš€ Features

  • πŸ€ Player prop market management
  • πŸ“Š Advanced filtering (position, stat type, suspension status, search)
  • πŸ”„ Manual suspension toggling for markets
  • πŸ“ˆ Alternate lines with odds
  • πŸ—„οΈ Strong relational schema (MySQL)
  • 🐳 Dockerized database setup
  • ⚑ Full TypeScript stack
  • πŸ§ͺ Unit & integration testing (Jest)

πŸ—οΈ Project Structure

playermarketstats/
β”‚
β”œβ”€β”€ client/                     # React frontend (Vite + TS)
β”‚   β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ package.json
β”‚
β”œβ”€β”€ server/                     # Express backend (TypeScript)
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ index.ts           # Server entry point
β”‚   β”‚   β”œβ”€β”€ routes/            # Express route handlers
β”‚   β”‚   β”œβ”€β”€ services/          # Business logic (MarketService)
β”‚   β”‚   β”œβ”€β”€ scripts/           # migrate.ts, seed.ts
β”‚   β”œβ”€β”€ dist/                  # Compiled output
β”‚   β”œβ”€β”€ package.json
β”‚
β”œβ”€β”€ docker-compose.yml         # MySQL container config
β”œβ”€β”€ init.sql                   # Database schema + seed data
β”‚
β”œβ”€β”€ package.json               # Root scripts
└── README.md

πŸ› οΈ Technologies Used

Backend

  • Node.js
  • TypeScript
  • Express
  • MySQL (mysql2)

Frontend

  • React 18
  • TypeScript
  • Vite
  • Axios
  • React Router

Database

  • MySQL (Dockerized)

Testing

  • Jest

πŸ—„οΈ Database Schema

🧠 Entity Relationship Diagram (ERD)

players (1) ────────< (∞) markets >──────── (1) stat_types
    β”‚                     β”‚
    β”‚                     └──────────────< alternates (∞)
    β”‚
    └────────────────────< alternates (∞)

Relationships

  • A player has many markets
  • A stat_type applies to many players
  • A market is uniquely identified by (player_id, stat_type_id)
  • A player has many alternate lines
  • Alternates extend the primary market with odds

Core Tables

players

  • Player metadata (team, position, etc.)

stat_types

  • points, assists, rebounds, steals

markets

  • Primary betting line
  • Includes suspension flags
  • Unique per (player_id, stat_type_id)

alternates

  • Alternate lines with:

    • under_odds
    • over_odds
    • push_odds

πŸ“Š How Player Market Data is Computed

Flow

  1. Seed Data

    • Players and stat types initialized
  2. Market Creation

    • One base line per player/stat type
  3. Filtering Layer

    • Markets filtered by:

      • Position
      • Stat type
      • Suspension status
      • Text search
  4. Suspension Logic

    • market_suspended β†’ automatic
    • manual_suspension β†’ override flag
  5. Aggregation

    • Markets joined with player + stat metadata
    • Returned as MarketWithDetails

πŸ”Œ API Endpoints

Base URL: /api/markets

GET /api/markets/filterOptions

Returns available filter values derived from market data.

Response

{
  "success": true,
  "data": {
    "positions": ["G", "F", "C"],
    "statTypes": ["points", "assists"],
    "suspensionStatuses": ["suspended", "active"]
  }
}

GET /api/markets

Fetch markets with filtering.

Query Parameters

Param Type Description
position string Filter by player position
statType string Filter by stat type
suspensionStatus string "active" or "suspended"
search string Search player name

Example

/api/markets?position=G&statType=points&search=lebron

Response

{
  "success": true,
  "data": [...],
  "count": 25
}

PUT /api/markets/:id/suspension

Update manual suspension status.

Body

{
  "suspended": true
}

Notes

  • Calls: marketService.updateManualSuspension
  • Currently marked as candidate task / partially implemented
  • Returns 501 if not implemented

βš™οΈ Installation

git clone https://github.com/mpokumt/playermarketstats.git
cd playermarketstats
npm run setup

▢️ Running the Project

Full stack (recommended)

npm run dev

Individual services

cd server && npm run dev
cd client && npm run dev

πŸ—οΈ Database Operations

npm run migrate
npm run seed

🐳 Docker

npm run docker:up
npm run docker:down
npm run docker:verify

The app will be available at:


πŸ”Œ Architecture Overview

[ React Client ] ---> [ Express API ] ---> [ MySQL ]
         β”‚                    β”‚
         β”‚                    └── MarketService (business logic)
         └── Axios requests

πŸ§ͺ Testing

npm test

Server:

cd server && npm run test

Client:

cd client && npm run test

πŸ“¬ Contact

Open an issue on GitHub for questions or suggestions.


Troubleshooting

Port Requirements:

  • Ports 3000, 3001, and 3306 must be available
  • If you have MySQL running locally, stop it first: brew services stop mysql (macOS) or stop the MySQL service (Windows)

Docker Issues

  • "Docker not found": Ensure Docker Desktop is installed and running
  • "Port 3306 already in use": Stop local MySQL:
    • macOS: brew services stop mysql
    • Windows: Stop MySQL service in Services app
    • Linux: sudo systemctl stop mysql
  • "Cannot connect to Docker daemon": Start Docker Desktop application
  • Container fails to start: Try npm run docker:down then npm run docker:up

Database Issues

  • "Connection refused": MySQL container is still initializing (setup script waits automatically up to 30 seconds)
  • "Seeding failed": Ensure props.json and alternates.json exist in database/ folder
  • "Migration failed": Try npm run docker:down && npm run docker:up to reset database

Port Conflicts

  • Frontend (3000) conflict: Change port in client/vite.config.ts
  • Backend (3001) conflict: Set PORT=3002 in .env file
  • MySQL (3306) conflict: Update DB_PORT in .env and docker-compose.yml

General Issues

  • "Module not found": Run npm run install:all to install dependencies
  • TypeScript errors: Check Node.js version (must be 16+)
  • Blank page: Check browser console and network tab for errors
  • API not working: Verify backend is running at http://localhost:3001/health

Still Having Issues?

  1. Try a clean restart: npm run docker:down && npm run setup && npm start
  2. Check all prerequisites are installed and running
  3. Verify no other services are using ports 3000, 3001, 3306

About

Full-stack TypeScript app for managing basketball prop markets with real-time filtering, MySQL persistence, and Express APIs

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors