How League Report got built
League Report is a custom platform for the leagues Austin runs. This reads a build that did two jobs at once: stand up a new site, and rescue a decade of data from a service going dark.
The leagues had lived for years on leaguelineup.com, an external service that announced it was shutting down. The software here is brand new, but it inherited a decade of schedules, rosters, and brackets that had to be pulled out before the lights went off.
The route, plotted
Eight waypoints across three months, a build and a data rescue at the same time. Hover any marker to read the direction that set it.
Build and rescue at once
The longest session was mostly a data rescue. Leagues were crawled from the old service into a local database, then imported in batches, with the agent given standing permission to fix what it found:
Let's start the import. If you see anything broken or being missed, feel free to adjust and improve.
That permission mattered, because a decade of real-world data is messy. Duplicate and malformed records surfaced constantly:
The URLs should be unique. We somehow got 2 /league/lcseniorsoftball/. The one is malformed. Can you fix?
One hundred and three screenshots changed hands over the project, most of them pointing at a team card, a bracket, or a broken import that needed a human eye.
What came next
Three months, ninety-two days of build and migration. A real project, not a sprint.
Start against a deadline. The old platform is shutting down. Build a custom WordPress replacement.
Build the league surfaces. Schedules, teams, standings, brackets.
Rescue the data. leaguelineup.com is going offline. Crawl and preserve everything possible.
Import in batches. Test on five leagues, then widen. Fix parse bugs and duplicate URLs as they appear.
Deploy to the real sites. Ship the plugin to softballreport.org and the senior leagues over SSH.
Keep it accurate. More leagues come across; stewardship continues.
What to borrow
A build that is also a migration rewards a particular kind of direction.
"The platform is going away" set scope, priority, and urgency in a single sentence. External pressure clarifies.
Half the work was importing and repairing data from a dying service. Treat the migration as a first-class feature, not cleanup.
"If you see anything broken or being missed, feel free to adjust and improve." That keeps a long batch moving without a round-trip per row.
560 headings over three months. Rutter records the marathon, not just the demo.
If you built this again
Knowing that half the work was a data rescue, here is how you would start a similar build. Copy a prompt and adapt it.
Names the deadline and the surfaces, and makes the migration first-class up front.
Grants standing permission and warns about dirty data, saving the debugging detours.
Bakes in the incremental deploys and the resumable-state habit.
This recap is the output of an editor pass over the project's agent transcripts. A deterministic extract (command-center flow --editor) pulls the direction, the agent trace, and the embedded screenshots from the most representative session. A single model pass captions each image and writes the narrative.
Every quoted heading is verbatim, typos and all. Landmark captions were recovered from images embedded in the transcript, then summarized. The originals are never reproduced or shared.