SaaS League Management Platform Production

The Pool League Manager

A league-operations platform for amateur pool leagues: season setup, scheduling, scoring, standings and playoffs in a web app that feels native on any phone, with nothing to download. With two-way text messaging, players can also get their schedule, standings and playoffs, and answer reminders, without opening the site at all.

Role
Founder, product owner and sole developer
Product type
Multi-tenant SaaS web app (no app-store download)
Platform
React + TypeScript SPA, ASP.NET Core 8 API, SQL Server
Status
Live and in weekly use

Overview

The Pool League Manager is a web platform for running amateur pool leagues. League administrators create leagues, build seasons, assign players to teams, generate schedules, enter match scores and run playoffs. Players use the same application, mostly from their phones, to see who and when they play, respond to attendance requests, and follow results, standings and their own statistics.

It is a web app, not an app-store app. On a phone it looks and feels like a native app, with a bottom tab bar, tap targets sized for thumbs and full-screen dialogs, but it runs in the phone's browser. Players can add it to their home screen like any app, with its own icon, and there is still nothing to download from the App Store or Google Play, no install to keep updated, and no barrier to a new player joining: a new player just taps the sign-up link in their invitation text. Every release reaches every player the moment it's deployed.

A distinguishing feature is two-way text messaging, which gives players a second way to take part. A player who prefers not to open the website doesn't have to. They can text SCHEDULE, STANDINGS or PLAYOFFS and get the current information back in a text, reply YES, NO or LATE to a match-night reminder, and accept a league invitation by replying to it. If a player belongs to more than one league, the system texts back to ask which one they mean. Every reply updates the league in real time, so the administrator sees attendance as players respond.

It is a multi-tenant platform built for any league operator. An operator creates an account, sets up a league, invites players and configures each season to match how that league actually plays. Leagues are fully separate from one another, with their own players, seasons, rules, messaging and SMS credits. It is in production and running live leagues every week, including leagues I play in and administer myself, so it is used and tested in real league nights.

The problem

A pool league is a small operation with many moving parts. Every season needs a schedule built around the venue's calendar and holidays. Teams or individual players have to be paired fairly across the season, scores and standings have to stay current week to week, and the season ends in playoffs whose format varies from league to league.

Leagues also differ in structure: two-player teams or individual competition, races to a set number of games or a fixed number of games per match, single or double round-robin. A tool that hard-codes one format doesn't fit most leagues. The other half of the job is communication. Players need to know when they play and who they play, and league operators need to know who is showing up. Some players will never download an app or remember a password, but every one of them reads text messages. The goal was a full web app for running and following the league, plus the option to take part entirely by text.

My role

I'm the product's sole designer and developer. I decide what the product does, design how it works, build every layer, and run it in production. I directed AI-assisted development with Claude Code and ChatGPT for implementation, debugging, refactoring and UX refinement, and kept ownership of the architecture and the review of every change.

  • Product strategy and roadmap
  • UX and workflow design
  • Application architecture
  • SQL Server database design
  • REST API development
  • React / TypeScript front end
  • Twilio SMS and email integration
  • Background jobs and reminders
  • Automated testing
  • AI-assisted development (Claude Code, ChatGPT)
  • Deployment and production support

Key capabilities

League and season administration

  • Leagues with venue, logo and play night
  • Seasons for team or individual competition
  • Player management and team assignments
  • Multi-step season-creation wizard with persistent configuration
  • Per-player dues/payment status tracking
  • Onboarding, invitations and league rules

Scheduling and competition

  • Round-robin and double round-robin schedule generation
  • Skipped dates for holidays and venue conflicts
  • Configurable match structures, such as race-to-N or a fixed number of games
  • Session-by-session matchups, with tap-to-score entry for administrators
  • Session and match status: completed, incomplete, up next, locked and postponed
  • Standings with game and match records
  • Session attendance responses, including "running late"

Two-way text messaging

  • Players can text SCHEDULE to get their upcoming schedule back by SMS
  • Players can text STANDINGS for current league standings
  • Players can text PLAYOFFS for the playoff bracket and results
  • Reply YES, NO or LATE to match-night reminders to update attendance
  • Accept league invitations by replying to the invite text
  • Automatic "which league?" follow-up for players in more than one league
  • Understands natural replies such as "yeah", "yep" and "nope"
  • STOP, START and HELP handled automatically

Playoffs

  • Playoff qualification from regular-season standings
  • Configurable number of playoff rounds
  • Seeded brackets with byes
  • Per-round match formats (for example, best two of three)
  • Automated playoff reminders

Messaging administration

  • Email and SMS invitations and league-wide messaging
  • SMS consent capture and opt-out handling
  • Full conversation history, inbound and outbound
  • Message delivery states
  • Per-league SMS credit balances
  • Scheduled match-night reminders

Player experience

  • Native-app look and feel on phones, running in the browser with nothing to install
  • Add to the home screen like any app, with its own icon
  • Mobile-first responsive interface, with full administration on desktop
  • League → season → session navigation with breadcrumbs
  • Team schedules, standings and playoff brackets
  • Career statistics across every league and season played
  • Built-in coin flip
  • Google sign-in or email and password

Technical architecture

  1. Front end

    A React single-page application written in TypeScript and built with Vite. Server state is managed with TanStack Query, forms are validated with React Hook Form, and the UI is assembled from accessible Radix UI primitives. Shared hero and card-style components keep desktop and mobile visually consistent.

    • React
    • TypeScript
    • Vite
    • TanStack Query
    • React Hook Form
    • Radix UI
    • Tailwind CSS
  2. API

    An ASP.NET Core 8 REST API exposes league, season, scheduling, scoring, playoff, messaging and account operations, documented with Swagger/OpenAPI.

    • C#
    • ASP.NET Core 8
    • REST
    • Swagger / OpenAPI
  3. Domain services

    Services and repositories hold the competition rules — schedule generation, standings, playoff qualification and seeding, reminders and SMS credit calculation — so that logic stays out of controllers and UI components.

    • Service layer
    • Repository pattern
    • Dependency injection
  4. Data

    A relational SQL Server schema models leagues, seasons, teams, players, sessions, matches, playoff rounds and message history. Data access uses Entity Framework Core plus Dapper for hand-tuned queries.

    • SQL Server
    • Entity Framework Core
    • Dapper
  5. Background processing

    Hangfire recurring jobs send match and playoff reminders and monitor client-side errors, with job history stored in SQL Server.

    • Hangfire
  6. Integrations

    Twilio handles outbound and inbound SMS. Inbound messages arrive by webhook and are routed to conversation handlers for consent, invitations, attendance, league selection and league-information requests, with opt-out handling built in. Transactional email goes through SendGrid or SMTP behind a common email-service interface.

    • Twilio
    • SendGrid
    • SMTP
  7. Authentication

    Email and password accounts with BCrypt password hashing, plus Google sign-in.

    • ASP.NET Core authentication
    • Google OAuth
    • BCrypt
  8. Quality and hosting

    Backend unit and integration tests use xUnit, Moq and the ASP.NET Core test host, and front-end tests run on Vitest. The application is deployed to Windows/IIS hosting with SQL Server.

    • xUnit
    • Moq
    • Vitest
    • IIS
    • Web Deploy

Interesting engineering challenges

Making season structure configurable instead of hard-coded

Leagues differ in almost every dimension that matters: team or individual play, how a match is decided, how many times opponents meet, which weeks are skipped, how many teams make the playoffs, and how each playoff round is played. The season builder captures these choices as data through a multi-step wizard whose progress persists between steps, so an administrator can build a complex season over several sittings. Scheduling, scoring and playoff logic all read from that configuration rather than assuming a single format.

Two-way SMS as a full alternative to the website

Two-way SMS is a conversation, not a broadcast. Inbound texts arrive through a Twilio webhook and are parsed into intents, accepting natural variations ("yeah", "yep", "sched") as well as exact keywords. The system tracks an active conversation per player, so a bare "YES" is read correctly as an invitation acceptance, a consent reply or a match-night attendance answer depending on what was last asked. Requests for schedules, standings and playoffs are answered from live league data and formatted to read well in a text. When a player belongs to more than one league, the system asks which one and remembers the answer to finish the original request.

Round-robin scheduling around real calendars

Generating a fair round-robin is a well-understood problem. Fitting one to a real league calendar takes more work. The scheduler derives session dates from the season's start date and play night, removes the dates an administrator marks as skipped, and assigns pairings so every team meets every other team the required number of times, once or twice depending on the format. The result is then carried through to the end of the season and into playoffs.

SMS that respects consent

Text messaging is the most effective way to reach league players, and it is also the most regulated. The platform records consent, honors opt-outs, processes inbound replies, tracks message delivery states, and meters usage against per-league SMS credit balances. Players stay in control of what they receive, and league operators can see what was actually delivered.

An app experience without an app store

Asking a bar full of league players to install an app is a losing battle, so the product is a responsive web app that behaves like a native one on a phone. Players get a bottom tab bar, thumb-sized tap targets, mobile-specific replacements for dialogs, and screens that work in a dimly lit bar. Administrators get dense desktop tools for setup and corrections from the same codebase. Shared components and design tokens keep both consistent, and because there is nothing to install, every update reaches every player as soon as it ships, with no app-store review and no outdated versions in the field.

Screenshots

Select any screenshot to view it full size.

Technologies

Front end
  • React
  • TypeScript
  • Vite
  • TanStack Query
  • Radix UI
  • Tailwind CSS
Back end
  • C#
  • ASP.NET Core 8
  • REST APIs
  • Swagger / OpenAPI
  • Hangfire
Data
  • SQL Server
  • Entity Framework Core
  • Dapper
Integrations
  • Twilio SMS
  • SendGrid
  • SMTP
  • Google OAuth
Testing
  • xUnit
  • Moq
  • Vitest
AI-assisted development
  • Claude Code
  • ChatGPT

Outcome and current status

Production Live and in weekly use

In production at thepoolleaguemanager.com and open to any league operator, running live weekly leagues end to end: scheduling, scoring, standings, playoffs and player messaging.

Development continues against a prioritized enhancement backlog that covers onboarding, player statistics, ratings and handicaps, notifications, and reporting.

View Live Product (opens in a new tab)

Hiring for a senior .NET, full-stack or technical product role?

I'd be glad to talk about what you're building and how I can help.