Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

ScalaintermediatebackendAI generated

Realtime Scoreboard

Build a live scoreboard service in Scala: scorekeepers send score changes for matches (such as a goal or a point) over HTTP, and every browser watching a match gets the update instantly over a WebSocket. The latest state of every match is saved, so after a restart the service comes back with the correct scores, and viewers who connect late or reconnect first receive the current score, then the live updates. It's built with http4s and Cats Effect, using fs2 Topics to broadcast updates. You'll learn WebSockets in http4s, broadcasting with fs2, managing shared state safely with Ref, persistence and recovery, validating commands, and testing streaming code.

Estimate
~11.5h
Steps
6
Completed by
0
Proposed by
codeseed.app

Cats Effect · http4s

Project roadmap

  1. 01

    Define the API

    ~1.5h

    Write API.md: matches (id, teams, status scheduled, live or finished, and the score), commands sent by scorekeepers (start, add points for a team, correct a score and finish) with a version number to detect conflicting commands, the WebSocket at /matches/{id}/live that sends the current state then every update, and GET /matches. Done when: API.md defines every command, message and endpoint.

  2. 02

    Hold state and apply commands

    ~2h

    Model matches and commands as case classes with Circe codecs. Keep all matches in a Ref[IO, Map[...]] and write a pure function that applies a command to a match, rejecting invalid ones (adding points to a finished match, negative scores, or a stale version). Done when: unit tests of the command logic pass for valid and invalid commands.

  3. 03

    Broadcast over WebSockets

    ~2.5h

    Create an fs2 Topic per match (or one Topic filtered by match). Add POST /matches/{id}/commands, which applies the command, stores the new state and publishes it, protected with a scorekeeper token. Add the WebSocket route with http4s's WebSocketBuilder: on connect send the current state, then stream the Topic's updates, handling client disconnects cleanly. Done when: several browser tabs see score changes instantly.

  4. 04

    Save state and recover

    ~2h

    Save every accepted command and the latest match state to a database (PostgreSQL with Doobie, or SQLite), and load all matches at startup. Make repeated commands safe by rejecting duplicates by command id. Done when: restarting the service keeps every match's score, and viewers see the right score after reconnecting.

  5. 05

    Handle slow and dropped clients

    ~1.5h

    Limit each subscriber's buffer so a slow client can't use unlimited memory (dropping old updates, since only the latest score matters), send pings to detect dead connections, and write a small browser client that reconnects with increasing waits and shows the connection state. Done when: a slow or disconnected client never affects others, and the browser client reconnects by itself.

  6. 06

    Test it

    ~2h

    Write munit-cats-effect tests: the command logic, the HTTP command endpoint (valid, invalid, stale and unauthorized), subscribers receiving the current state then updates, recovery from the database, and dropping updates for a slow subscriber. Done when: sbt test passes.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~11.5h · 6 steps

Tech stack

Cats Effecthttp4s