Case Study · Team Scout

Finding the market, then building the thing.

Youth sports programs run on software written in 2014. I spent enough time with coaches and volunteer administrators to understand why they tolerate it — then built the alternative myself.

1 person

Product, architecture, build

Multi-tenant

Every org isolated at the database

Double-entry

Ledger accounting on every dollar

Web + native

Next.js and React Native

THE MARKET QUESTION CAME FIRST

The obvious read on youth sports software is that the incumbents are bad and someone should build a better one. That read is wrong, or at least incomplete — the incumbents are bad and they are entrenched, because the person choosing the software is a volunteer who inherited it and has eleven other jobs.

So the real question wasn't whether a better product could exist. It was: what would make a volunteer administrator, mid-season, decide to move? The answer turned out to be narrower than a feature list. It was the handful of moments where the old system actively costs them — a registration that takes forty minutes to configure, a treasurer who can't tell you who has paid, a website only one person can update.

That framing decided the product. Not “a platform for youth sports,” but a specific sequence of relief, with the first one cheap enough to try without a committee.

FOUR DECISIONS THAT SHAPED IT

Each of these is a business decision that happens to be expressed in schema.

01

Row-level security instead of application filtering

The usual approach

Multi-tenant platforms usually keep organizations apart in application code — every query carries a filter, and one forgotten WHERE clause leaks one club's roster to another.

What I did instead

Isolation is enforced in Postgres itself. Row-level security policies mean the database refuses to return another organization's rows regardless of what the application asks for. A bug becomes an error instead of a breach.

Why it mattered

The data is minors' names, addresses and guardians. That's not a place to rely on remembering a filter.

02

A normalized schema, not a JSON blob

The usual approach

The fast way to ship a registration form is to store submissions as JSON. It works immediately and it's unusable within a year — you can't report on it, can't constrain it, and the same field ends up spelled three ways.

What I did instead

Every entity gets real tables, real foreign keys, real constraints. Registrations, participants, guardians, forms, payments and ledger entries are separate and related. One fact lives in exactly one place.

Why it mattered

The reporting a club actually needs — who has paid, who is cleared, what a season cost — is trivial against a normalized schema and nearly impossible against a blob.

03

Double-entry accounting on every transaction

The usual approach

Most youth-sports platforms track a payment as a row with a status. When a refund is partial, or a scholarship covers half a fee, or a fundraiser splits across two teams, that model quietly stops reconciling.

What I did instead

Every movement of money writes a balanced pair of ledger entries. The books have to balance because the schema won't let them do anything else, and any figure can be traced to the transactions that produced it.

Why it mattered

Volunteer treasurers hand off every year. A system that reconciles to the bank is the difference between a clean handoff and a forensic exercise.

04

Stripe Connect, so the money is never mine

The usual approach

Routing club funds through a platform account is simpler to build and creates a custodial relationship nobody wants — regulatory exposure for the platform, and a trust problem for the club.

What I did instead

Each organization has its own connected account. Funds settle directly to the club. The platform facilitates and never holds.

Why it mattered

It removes an entire category of risk and it's the honest answer when a treasurer asks where their money sits.

Why this is the portfolio piece

Every one of those decisions is a business judgement that only looks like a technical one.

Row-level security because the data is children's. Double-entry because volunteer treasurers hand off every year. Connected accounts because a club shouldn't have to trust a platform with its float. Someone who only writes code would need to be told all of that. Someone who only writes strategy couldn't act on it. That gap is the thing I sell.

Team Scout is live and running.

Built in Kansas City for programs everywhere. If you have a system that needs the same treatment, that's the work I do.