Worst Friends Dashboard
I wanted to mess around with a few things in Google Cloud Platform to help understand how Cloud Run works.
My friends and I have a little world cup sweepstakes, so I built a dashboard to help us keep track of some stats.
I was accused by some of 'probably using some fancy software' to do our group team selection draw. Au contraire, that part was all manual. Bowls, hats, and names on paper were used to draw 4 teams each for 12 friends.
But to track the stats over more than 100 games, let's go fancy.
I thought I would also try out Claude Code, so much hype around it, even if this is a simple project to benchmark against.
Weird Stats
So for our competition, we will have three winners. The person whose team wins the men's soccerball World Cup 2026 will win first prize.
The second prize goes to the person whose team is the dirtiest. We calculate this using a weighted score:
- Yellow card: 1 point
- Red card: 2 points
- Free kick conceded: 0.5 points
- Penalty conceded: 3 points
A special third prize goes to the person with the worst team overall statistically. The ranking for this is determined by:
- Fewest points
- Most goals conceded (tie-breaker)
- Most shots conceded (secondary tie-breaker)
So with four teams each, the dirtiest and worst friends will be fun to track.
I also added some inspirational quotes under each fixture. I originally planned to add some friendship rivalry quotes/statistics there, but there were too many permutations for a 48-team tournament!

The Deliberately Boring Stack
This could be a simple static web page, but I chose to build a Spring Boot API project using Java.
Mainly because I speak Java, so if Claude did something crazy, I could spot it.
The stack includes:
- Backend: Java and Spring Boot.
- Frontend: Plain HTML/CSS/JavaScript with no external frameworks. It polls the backend every 60 seconds to update the stats.
- Data Source: API-Football v3.
I wanted to create something that could be reused for other similar competitions in the future. So files like friends.json, groups.json, and quotes.json can be updated without modifying the code.
To avoid hitting rate limits on API-Football, I added a simple caching mechanism. In fairness, with the small amount of data being fetched, caching isn't strictly necessary. But this is a bit of a craic driven development project.
So finished fixtures are written to a fixture-cache.json file. Once a match is over, its stats are locked in and never re-fetched, which reduces the number of API calls and provides a way to verify the persistent storage setup.
Cloud Run
The application is hosted on Google Cloud Run. The main reason again being craic driven, I just wanted to try it out.
The revision management system is cool.
During one update, there was an issue where a new revision failed to start because of a Cloud Storage bucket name typo. Cloud Run's health checks detected the failure and automatically kept the previous revision running, ensuring zero downtime for users.
God forbid one of the twelve people this app is made for ends up noticing that the dashboard is acting up. I could never live it down.
The fixture cache is stored in a Cloud Storage bucket which is mounted directly to the container, allowing the state to persist across revisions.
Claude Review
I used the Claude Code Desktop interface to help build this project. It was fine.
I was happy with the majority of the Java code it produced, and I let it go wild in the JavaScript/HTML parts as I wouldn't know where to start really.
I've previously had issues when using gemini cli in my day job, with hallucinations and outrageous lies often interfering. But at least for this small project, no issues there with Claude.
One thing it turned out to be really useful for was explaining the GCP side of things and helping with gcloud commands to deploy the app.
I would say that was more useful than any of the code generation. Which was the whole point of the project. Hurrah!
Claude Chat hallucinations
Unfortunately, the outrageous lies were left to the regular Claude chat, not the code interface. I asked it to find a fixture .ics file I could import to my calendar. Instead, it tried to gaslight me in to thinking Ireland somehow had a chance.

Best Friends Next?
The project is designed to be easily forkable. You can swap in your own participants, teams, and quotes by editing the JSON configuration files. Ready for Brazil 2027!
The source code is available here: repo
The live dashboard, at least for the duration of the 2026 World Cup, can be found here
- ← Previous
Learning To Touch Type - Part 4