Portfolio Project

The League Platform

The Operating System for Sports Clubs

A production-grade, multi-tenant SaaS platform that replaces the spreadsheets, WhatsApp groups, and disconnected tools that sports clubs rely on today. One platform for every sport, every club operation — members, payments, sessions, competitions, live scoring, facilities, equipment, communications, and analytics.

Built as a Modular Monolith with .NET 10, Angular 21, SQL Server, Redis, Docker, and SignalR. 16 independent domain modules, each with Clean Architecture layers, communicating through integration events. Includes a full SaaS business model with tiered subscriptions, Stripe Connect, feature gating, and dunning.

View on GitHub

Platform at a Glance

16

Modules

100+

Endpoints

32+

Pages

35

Correctness Proofs

8

Sports

30

Integration Events

The League — User dashboard showing club overview, upcoming fixtures, recent results, and activity feed

Competitions, Matches & Leaderboards

The competitions module handles league tables, fixtures, match management, and live scoring. Season configuration allows administrators to set up competition rules, point systems, and schedules. Players see their personal stats, league standings, and match history from their own dashboard.

The League — Match management with fixtures, results, and scoring interface

Match management: fixtures, results, and scoring

The League — League leaderboard showing standings, points, wins, draws, and losses

League leaderboard with standings and points table

The League — Player personal statistics including matches played, runs scored, and performance metrics

Player personal stats: matches, performance, and history

The League — Personal leaderboard comparison showing how you rank against other players

Personal leaderboard: how you rank against others

Season & Team Management

Administrators configure seasons with start/end dates, competition rules, and registration settings. Teams are managed with player rosters, captains, and match assignments. Members are tracked with full profiles, attendance history, and membership status.

The League — Season management with competition setup, dates, and registration configuration

Season management and setup

The League — Team management showing rosters, captains, and player assignments

Team rosters and management

The League — Member management with profiles, membership status, and attendance tracking

Member profiles and tracking

Administration, Roles & Permissions

The platform provides fine-grained control over who can do what. 5 roles (SuperAdmin, ClubManager, Member, Coach, Staff) with granular permissions per module. User management, role assignment, season settings, and platform configuration are all accessible through a clean admin interface.

The League — User management console with search, role filter, and account status

User management with search, filtering, and status control

The League — Permission management showing granular module-level access control

Granular permission management per role and module

The League — Role management with role creation and permission assignment

Role management and assignment

The League — Admin settings page for platform-wide configuration

Platform configuration settings

The League — Season settings with competition rules, point systems, and schedule configuration

Season rules and competition settings

Member Self-Service Portal

Members manage their own profiles, view personal stats, track match history, and access club information without needing administrator help. The portal is designed to reduce administrative overhead while giving members full visibility into their club activity.

The League — Member self-service profile page with personal details, stats, and club information

Member self-service profile with personal details and club information

Modular Monolith Architecture

Not microservices. Not a big ball of mud. A Modular Monolith — 16 independent modules that deploy as one but develop as many. Each module owns its domain, data access, and API. They communicate through integration events, not direct references. Zero circular dependencies enforced by NetArchTest architecture tests. Extract to microservices when you need to — without rewriting anything.

🔐

Identity

🏢

Clubs

👥

Members

💳

Memberships

📅

Sessions

🎉

Events

🏆

Competitions

💰

Payments

🏟️

Facilities

🎾

Equipment

📚

Programs

📧

Communications

📊

Analytics

🛒

Shop

📁

Documents

💎

Subscriptions

Complete SaaS Business Model

This is not just a technical exercise — it models a real SaaS business. Multi-tenancy with shared database and EF Core global query filters, tiered subscriptions with feature gating, platform transaction fees on every payment via Stripe Connect, automated dunning for failed payments, and usage-based limits per tier.

Free

£0/mo

50 members, 1GB storage

Starter

£29/mo

200 members, 10GB, SMS

Pro

£79/mo

Unlimited, analytics, API

Enterprise

£199/mo

White-label, custom domain

Live Scoring & Multi-Sport Support

Real-time match scoring powered by SignalR. Public scoreboards accessible without login. Sport-specific scoring formats for cricket (runs/wickets/overs), football (goals), hockey, rugby, tennis, swimming, athletics, and golf. PWA installable on any device with offline attendance marking and background sync.

🏏Cricket

Runs, Wickets, Overs

Football

Goals, Cards, Assists

🏑Hockey

Goals, Penalty Corners

🏉Rugby

Tries, Conversions, Penalties

🎾Tennis

Sets, Games, Points

🏊Swimming

Times, Distances

🏃Athletics

Times, Distances

Golf

Strokes, Holes

Technology Stack

Backend

.NET 10ASP.NET CoreC# 13MediatR 12FluentValidationEF Core 10SQL Server 2022Redis 7SignalRHangfirePolly 8Serilog

Frontend

Angular 21TypeScript 5.9Tailwind CSS v4DaisyUI 5Angular SignalsSSRPWAChart.jsVitest + Playwright

Architecture

Modular MonolithCQRSIntegration EventsMulti-TenancySeparate DbContextsPipeline BehavioursDomain Events

DevOps & Testing

DockerGitHub ActionsxUnitFsCheckNetArchTestTestContainersAzure Key VaultApplication Insights

35 Correctness Properties

Every critical business rule is encoded as a formal property using FsCheck property-based testing. These are not simple unit tests — they prove that invariants hold for all valid inputs, not just specific examples.

Tenant data isolation — queries never return cross-tenant data
Session capacity — bookings never exceed capacity
League standings — points = 3×wins + 1×draws
Invoice lifecycle — only valid state transitions permitted
Member balance — always equals sum(credits) - sum(debits)
Round-robin fixtures — exactly N×(N-1)/2 matches generated
Proration calculation — mathematically correct to 2dp

What This Demonstrates About My Engineering

Modular Monolith with 16 bounded contexts
Multi-tenancy at the data layer (EF Core filters)
Complete SaaS business model with feature gating
Real-time features with SignalR and PWA
Property-based testing for formal correctness proofs
Architecture tests enforcing module boundaries
Docker containerisation and CI/CD pipelines
Integration event bus for module communication
Resilience patterns (Polly circuit breakers, retry)
Building SaaS products, not just technical demos

Interested in this level of engineering?

I am available immediately for senior developer, technical lead, and contract opportunities across the UK.