Work

My favorite work starts with a messy, manual process and ends with a system people actually use. Each example covers the problem, what I built, and what it changes. The Select examples also say what makes them hold up, and a badge shows their stage. Some run every week, and some are still being built. I’d rather tell you exactly where something is than round it up.

At Select Soccer Club

A data foundation for a platform with no API

Partly automated

Unlocking registration data so reporting and internal tools share one source of truth.

The problem
As Select grew, more reports and internal tools needed the same registration data. The club’s registration platform has no API or MCP connection, so player, roster, and subscription data came from manual exports, and each new report started from its own download.
What I built
A pipeline that moves scheduled exports into cloud storage and feeds an Airtable base, which serves as Select’s data layer. Records match on stable IDs, so each update lands on the right player and nothing is duplicated or lost.
What it changes
Reports, dashboards, and internal apps can build on one trusted source, instead of each one starting from another downloaded spreadsheet.
Built to hold up
Records match on stable IDs and are only ever updated or created, never deleted, so one bad export can’t wipe out good data. Every step runs on a schedule, so the data doesn’t depend on someone remembering to download it.

ToolsGoogle Cloud Run · Cloud Scheduler · Cloud Storage · Google Drive · Airtable · Zapier

A lead-to-enrollment funnel

Partly automated

Every interested family gets a prompt response and a clear path to registering.

The problem
Families find Select through several channels. As interest grew, the club needed one consistent way to qualify every inquiry, route it to the right person, log the conversation, and follow up, especially in peak season, when volume is highest and a quick response matters most.
What I built
A documented lead-to-enrollment workflow in HubSpot: intake from every channel, a qualification layer, routing by region, and follow-up sequences triggered by each prospect’s digital signals. Before building anything, I mapped how inquiries actually arrived and wrote the business case for the CRM.
What it changes
No inquiry depends on someone remembering to follow up. Every prospect gets a prompt first response, then timely touchpoints based on what they’ve shown interest in.
Built to hold up
The whole workflow is documented, from first inquiry to enrolled, so anyone can see how an inquiry moves and who owns each step. Routing is set by region, so adding a person or a region means updating a rule, not rebuilding the funnel.

ToolsHubSpot · Zapier

From schedule PDFs to payroll-ready shifts

Live

Schedules in any format become accurate shifts in a fraction of the time.

The problem
Select’s hourly staff schedules arrive in every format: screenshots, PDFs, and spreadsheets. Entering them into the scheduling platform by hand took real time each season, and any retyping error could carry through to payroll.
What I built
A repeatable process that turns a schedule in any format into a shift import, building accurate shifts from the rules for each type of job. Before payroll, a report flags differences between scheduled and worked hours so they get fixed first.
What it changes
Schedule entry takes a small fraction of the time it used to, and mismatches surface before payroll instead of after it.
Built to hold up
The rules live in one place (setup time, game lengths by age group, how each job type becomes a shift), so a new season means changing a rule, not retyping a schedule. An overlap check and a shared vocabulary for regions and programs keep every import consistent, and the pre-payroll report catches anything that slips through.

ToolsConnecteam · Google Sheets · Python · Claude

A weekend game-report system

Live

Directors know what happened at every game, and what needs a follow-up.

The problem
With Select teams playing across several leagues every weekend, directors needed one consistent way to hear from coaches: what happened, whether results were entered, and which concerns needed a follow-up.
What I built
A weekly sync that builds one list of fixtures from every league Select plays in. Coaches pick their game from a simple form and file one report. Directors get a prioritized follow-up queue, with serious incidents at the top, and can nudge everyone who hasn’t filed with one click.
What it changes
Instead of chasing updates, a director starts the week with a short list of what needs attention, so issues get handled sooner.
Built to hold up
A game keeps its report even when it’s rescheduled, and the sync refuses to run if a league’s data suddenly shrinks. Reports are only ever added, never overwritten, and it runs on Google Sheets because that’s where staff already work.

ToolsGoogle Sheets · Apps Script · Zapier · ClickUp

A dashboard that can show its math

In development

Year-over-year registration pacing that can explain every number it shows.

The problem
Select’s leadership uses a registration pacing dashboard to see whether the club is ahead of or behind last year. My first version answered that at a glance, but it couldn’t explain its own numbers, and a pacing number is only useful if people trust it.
What I built
A rebuild that compares rostered players by program, region, gender, and age group against the same date last year, with a parallel spreadsheet model that shows the work. Closed seasons are archived, so a refresh never erases history.
What it changes
When a number looks off, anyone can trace it back to the rows behind it, and last season’s history survives every refresh.
Built to hold up
Every number ties back to a parallel spreadsheet model that shows the work. Closed seasons are archived, so a refresh never erases the history the comparison depends on, and a new season starts by uploading the latest export.

Read the story behind the rebuild →

Earlier, in software

Marketing automation · TrainingPeaks

A 500,000-contact migration

Tripled email-channel revenue in six months, against a twelve-month goal.

The project
I led the selection and implementation of a new marketing automation platform, including migrating 500,000 contacts with hundreds of data points each.
What it took
Integrations with several existing systems, and close work with marketing, sales, development, and the executive team.
The result
A behavioral and demographic lifecycle program on the new platform tripled email-channel revenue within six months. The goal had been twelve.
Lifecycle growth · Rafflecopter

Personas, lifecycle stages, and the KPIs between them

+32% average revenue per user and +30% lifetime value in one year.

The approach
Defined customer personas and lifecycle stages, then set the KPIs, success factors, and tactics for each stage, with a measurement framework to see progress.
What I built
Onboarding and lifecycle programs, plus the company’s business KPI dashboard.
The result
A 32% increase in average revenue per user and a 30% increase in lifetime value within a year.