Music Discovery
Clubstro: From Recorded Audio to Music Charts
I built Clubstro’s backend and extended its existing frontend to turn recorded audio into music charts people can explore by location and genre. My work connected audio recognition, venue play records, and chart queries, then added queued device uploads and the tools operators need to correct track data and investigate recordings that could not be recognised.
- Role
- Backend and Frontend Engineering
- My Work
- Audio-recognition integration, relational play data, chart queries, queued device processing, and discovery and administration workflows.
Keeping the Place Alongside the Song
Recognising a song was the first step. To make the recording useful in Clubstro, I also needed to retain its connection to a track, a place, and a time. That context lets people explore music through location and genre filters.
I built the backend around that connection between recordings, tracks, and places. On the frontend, I extended the existing application with the API integration, filters, uploads, and administration screens that made those records usable. I also worked on event discovery alongside the music charts.
- Identify the AudioSubmit an uploaded clip for recognition and read the track information.
- Record the PlayResolve the music and its metadata, then associate the play with its location and time.
- Build the ChartPrepare the music data for the chart and its filters.
Giving Each Recording a Consistent Path
I integrated an audio-recognition service and translated its responses into typed objects for tracks, artists, albums, and genres. That gave the rest of the application a consistent structure to work with, instead of passing provider responses through every database operation.
I kept related recording writes together in a database transaction and shared the recording workflow across upload paths. That gave changes one place to live. I also processed bulk writes in bounded batches, keeping the work and temporary memory used by each insert manageable.
Cover art is useful, but a failed artwork lookup should not undo a recognised play. I deferred that enrichment until after the operator’s response and caught its failures separately. The track and its plays are already stored by then.
Making the Chart Count What It Should
Filtering music by related metadata can introduce duplicate rows into a query. I separated filtering from aggregation so a relationship used to select records would not accidentally multiply the data being counted. The filter needed to narrow the results while keeping the underlying records represented correctly.
I organised the chart queries into clear stages for selecting, aggregating, and returning results. This made it easier to reason about the query as location and genre filters changed, and to keep the database work tied to what the interface needed.
I added composite indexes for the play and location lookups, then loaded related artists, genres, albums, and addresses in batches after ranking. This avoids fetching the same kinds of metadata separately for every result.
Time filtering needed its own care. I worked through reporting periods and the transitions between them, so a change of period would apply the intended rules consistently. Keeping that logic together made it easier to reason about dates alongside the other chart filters.
Handling Device Uploads and Retries
I added an upload API for venue capture devices and moved recognition into background processing. The API could acknowledge a stored upload while the slower work continued. I also accounted for delayed uploads when connecting a recording to its capture time.
I used database constraints and concurrency checks to handle repeated uploads and competing workers. Accepting a clip and processing it are separate responsibilities; each needed a clear record of its progress.
I kept recorded, unrecognised, and failed outcomes distinct so operators could see what happened to a clip, and added retries for processing failures. An acknowledged upload is not a completed recognition result. Interrupted work can still need investigation, so I made its status visible to operators.
Making Corrections Practical
Recognition results sometimes need editing. I built correction workflows that preserve useful track metadata when an external lookup is incomplete. An operator can still make the correction without losing information already attached to the track.
I also worked on scoped corrections and duplicate-track merging. Those actions affect different sets of records, so I kept their responsibilities distinct and used transactions for related changes. The aim was to let operators maintain the catalogue without losing the history attached to it.
I built device registration, credential management, and status screens with access controls appropriate to each workflow. Recent processing results gave operators a starting point for investigating a quiet or failing device.
Connecting the Data to the Interface
I carried chart and event selections in URL search parameters and included filters in the interface’s cache keys. That lets the interface request and cache results for the location and category someone is actually viewing. Device updates refresh the affected list and detail views after a change.
For event discovery, I added cursor pagination with a stable ordering. The interface collects successive pages through Load More and resets the list when the location or period changes. Alongside the chart filters and operator forms, this connected the backend work to the controls people use to explore and maintain the data.
Outcome
I connected audio uploads, recognition, stored plays, and filtered charts across the backend and interface. Operators can correct music records, manage device access, and inspect clip outcomes through the application. Shared recording workflows connect uploads to the music data people browse.