๐Ÿ†

league-api

REST API for billiards league management

A fully documented REST API for managing a billiards league โ€” players, matches, standings, and win/loss records. Built to showcase C#/.NET backend engineering, REST API design, Entity Framework, PostgreSQL integration, and containerized deployment.

View on GitHub
32 scenariosยทSpecFlow/Gherkin

The Problem

Most billiards league management is done in spreadsheets or basic apps that don't enforce the domain rules that make league play meaningful โ€” handicap races, active player management, computed standings.

The Solution

A domain-driven REST API that validates billiards-specific business rules at the API level. Winner's score must equal their race. Loser's score must be below their race. Forfeits auto-set the winner's score. Standings are computed on the fly from match results โ€” never stored.

Screenshots

Swagger UI showing all endpoints

Full API surface documented via Swagger โ€” Matches, Players, and Standings controllers

POST /api/Matches response

Recording a match with domain validation โ€” winner score, race length, and game type enforced

GET /api/Standings response

Computed standings returned on the fly โ€” win percentage, streak, and rack efficiency

Tech Stack

C# / ASP.NET Core

Primary language from 7+ years at Net Health

Entity Framework Core

ORM for clean database interaction without raw SQL

PostgreSQL

Production-grade database in Docker container

Docker

Single command deployment with docker-compose up

Swagger / OpenAPI

Auto-generated API documentation

Key Engineering Decisions

โ–ธ

Standings computed on the fly rather than stored โ€” always accurate, better for testing

โ–ธ

Soft delete for players (IsActive flag) because league players go inactive and return

โ–ธ

Hard delete for matches โ€” an incorrectly recorded match should simply not exist

โ–ธ

DeleteBehavior.Restrict on all three Player foreign keys to prevent cascade delete conflicts

โ–ธ

Email normalized to lowercase on save โ€” consistent data storage over runtime comparisons

Related Project

break-and-verify