Golf Match Scoreboard
No Active Match
Create a match using the Match Admin
Match Admin
Use the inputs below to setup the match
Overview
Created this custom project to help track a large golf event between two teams, and sub matchups between the two teams.
This project is mainly composed of three main components:
- API Routes (create match, update score, update hole)
- Valkey for storing active match data
- Sockets for sending real time match updates to clients
Use the dropdowns below to learn even more!
API Routes
There are four API Routes used in this application for creating or updating the match.
/match [GET]: fetch the current match data (if there is one)/match [POST]: create/update the entire current match (used by Match Admin popover)/score [POST]: update a sub match score (used by +1 buttons)/hole [POST]: update a sub match hole (used by hole buttons)
I also heavily utilize some features of pydantic models for tracking the overall score of the match. Instead of handling the logic of adding up the diff between the sub matches, I have the main match score be a calculation of the sub matches via my pydantic models. I also use the same technique for determining the diff between each sub match. You can view that here.
You can also view the API Routes for this Golf Match with my Scalar Docs
Valkey
Since I don't care about keeping the matches long term, I end up storing the active matches as key/value pairs in my valkey database. API Routes and socket events check for an existance of a match key to see if an active match is in progress; and if so we send it back to the clients via socket emits and then the client renders the page. The match key is scoped to an iso formatted date string and is configured to store for 12 hours after the last update. Meaning I only want to keep a match for the current day and then we throw away the match.
Socket
I decided early on in this project that I wanted updates to be pushed
real time to all clients viewing the match. This helps remove the issue
of keeping the state in sync between clients. On initial web socket
connection, we push the active match to that client if one exists and
the match is rendered on the page. On any POST API Routes
we update the match in valkey and emit the match to all connected web
socket clients so they get real time updates on score/hole changes.
One thing I wanted to do (and probably will come back to) is to adjust the socket emits to only push changes instead of the entire match. This would allow us to setup animations on score/hole changes via CSS. But sending and rendering the entire match simplified the logic. Especially when you have to consider rendering updates to the Match Admin popover.
Match Admin
I wanted to have a simple way to create the match teams/names/colors, and also a way to adjust scores if someone accidentally pushed a button when they didn't mean to do so.
This is where I came up with the Match Admin popover. It allows a user
to edit everything about the match and force a refresh to all connected
clients when they submit the POST request.