Skip to content
MROOT

FIVEM COMMUNITY / CONTENT MANAGEMENT

Southside
Records.

A label website
the staff can run.

A FiveM record-label website with staff-managed content and best-effort activity logging.

southsiderecords.org
ORIGINAL THUMBNAIL · 262 × 162
THE WORK BEHIND THE ROSTER

Artists.
Releases.
Events.

STAFF-MANAGED CONTENT
Original thumbnail + an illustrative record and content sleeve. Not a fabricated admin screenshot.
Documented project~2 min read
My contribution
Public site, admin CMS
& deployment
Context
FiveM community project
2025 build / June 2026 account
Built with
React · Vite · shadcn/ui
Supabase · Cloudflare Worker

01 / THE BUILDThe site does not end at the public page

Southside has two kinds of users. Visitors want to find an artist, open a release, or see an upcoming event. Staff need to maintain those records, manage photos, and read enquiries.

I built the public site and the admin CMS around those jobs. The artist roster, releases, streaming links, and events are the visible part. Behind them is a multi-panel console for managing the content.

02 / THE BUILDGive each kind of content a place

The documented console has eight panels: artists, releases, events, photos, team, messages, logs, and map. They share a data layer rather than each page inventing its own way to talk to Supabase.

The public experience includes links to Spotify, Apple Music, YouTube Music, and SoundCloud on releases. Those are outbound listening links—not a claim that this project hosts or distributes the music.

EXPLORE THE CONTENT SYSTEM

Eight panels. Different jobs.

01–08

The public roster

Artists

Staff manage the artist records presented in the public roster.

CONTENT SCOPE / NOT AN ADMIN SCREENSHOT
Read every panel description
Artists
Staff manage the artist records presented in the public roster.
Releases
Release records connect the public catalog to Spotify, Apple Music, YouTube Music, and SoundCloud. These are outbound links.
Events
The site presents events; a dedicated admin panel manages this content.
Photos
Uploads live in Supabase Storage. Matching image URLs can be routed through the image Worker.
Team
A team panel is included in the documented admin scope. The source does not spell out a more detailed workflow.
Messages
The back office includes contact-enquiry management. No messaging integration beyond the documented scope is assumed.
Logs
The data layer attempts to record changes. Logging is best-effort; a failed log write does not undo a successful content change.
Map
A map panel appears in the original eight-panel inventory. Its detailed behavior is not described in the available account.
Select a panel to see its documented role. These are areas of the CMS, not eight invented database relationships.

03 / THE BUILDA saved change and a saved log are different things

The service layer attempts to record create, update, and delete activity. That makes logging part of the content workflow rather than something each interface has to remember separately.

But the implementation has an important limit. In the published artist-creation example, the artist is saved first. The log is attempted afterward, and a logging error is caught separately. A successful content change can therefore have no matching log entry.

That is best-effort activity logging, not a complete audit-history guarantee. The demonstration below makes the difference visible.

LOCAL FAILURE EXPLORER

Saved content ≠ saved history.

01 / REQUEST

Create an artist

Staff submits a change.

02 / PRIMARY WRITE

Save the artist

Ready to illustrate.

03 / SEPARATE WRITE

Attempt the log

After a successful insert.

Try the failure path.

The artist is inserted first. The log is attempted in its own try / catch. Select an outcome to inspect what remains.

Read all three outcomes
Both writes succeed
The artist and activity row are saved. This illustrates one successful execution, not a guarantee for all changes.
The log write fails
The artist remains saved. The logging error is caught and written to the console. The function returns the artist without a corresponding audit row.
The content write fails
The insert error is thrown before the log attempt. The function does not reach the log write.
Simulation of the supplied code’s control flow. No artist, log, or database is changed. Best-effort logging is not a complete audit trail.

04 / THE BUILDUploads and image delivery take different routes

Photos are stored in Supabase Storage. A URL helper sends matching storage URLs through a Cloudflare Worker for cached delivery; URLs that do not match are returned unchanged.

This separates where an image is uploaded from how a visitor requests it. The source account does not include a measured speed comparison, so there is no performance percentage to attach to that choice.

IMAGE URL ROUTING

Storage and delivery are separate.

WHERE UPLOADS LIVE Supabase Storage
HELPER RETURNS Image Worker URL

A matching storage URL is rewritten to the Worker endpoint for cached delivery. This is not an upload through the Worker.

Other input cases

A nonmatching URL is returned unchanged. Empty input returns null. The source excerpt does not include the Worker’s cache configuration.

The helper’s documented branches. No image request is made, and no speed improvement is measured in this demonstration.

05 / THE BUILDWhat I would tighten up next

The original write-up identified three unfinished areas. There were no automated tests; the logging wrapper and image URL helper were the first candidates. Supabase row-level-security policies lived in the database rather than the repository. The entity-specific API objects also repeated enough structure to warrant a smaller shared abstraction.

Those are the next engineering tasks, not features being presented as already delivered. The useful part of this project is seeing the public site, staff workflow, storage, and logging together—including where the design still has limits.

Source, dates, and what this page verifies

This is an editorial rewrite of the supplied project and technical article, describing the account published June 28, 2026. Original dates, code excerpts, and unfinished work are retained. The production repository, permissions, costs, and historical measurements have not been re-audited.

Interactive figures are local explanations. They do not call an API, send input, create content, or demonstrate production test coverage. The cumulative reference is not deployed.

Open the published source ↗

Ready to build?

Give your team a clearer way to publish.

Start with the content your team needs to manage. We can scope the publishing controls, permissions, and activity history.

Plan a publishing workflow