Case study
Kessler Street Records: Giving a Record Shop a Voice — and a Paper Trail for Every Decision
Role
Solo product designer, full‑stack developer & security auditor
Timeline
Jul–Aug 2026
Status
Live in production
Kessler Street Records is a full‑stack record shop: a public storefront with a live, database‑backed catalog, and a login‑protected admin panel behind it for running inventory. Built solo, end to end, including a self‑run security audit before calling it deploy‑ready.
The obvious problem to solve was technical — real image uploads, real authentication, a real admin back office.
The less obvious problem, and the one this case study focuses on, was making a database‑driven catalog feel like it was curated by a person with taste, not generated by a query. That’s a content and structure problem as much as an engineering one, and it runs through everything from how records are browsed to how a CHANGELOG explains what I chose not to fix.
Key design decisions
01
Taxonomy as voice
Records don’t browse by generic genre tags — they browse by mood: Sunday Morning, Basement Loud, Deep Cuts, Late Shift, plus a standing Staff Picks shelf. That’s the single content decision doing the most work in the whole project. A genre filter is a database query wearing a UI. A mood name is the first thing that tells a visitor someone with actual taste put this shop together — the taxonomy is the voice, before a single sentence of copy gets written.
02
Designing for the moment nothing matches
Search and sort run entirely client‑side against records already embedded in the page — no extra round trips — and every combination of mood filter, search term, and sort order has to resolve to something, including zero results. An empty state is one of the easiest UX writing moments to skip entirely; here it’s treated as a real state to design for, not an accident to tolerate.
03
Writing constraints so errors don’t have to happen
The admin upload flow states its rules up front — square, 1000–3000px per side, JPG/PNG/WebP, 5MB max — rather than letting someone find them out via a failed upload. That’s a small piece of copy, but it’s the difference between a system that explains itself and one that just rejects you. The validation backs it up: files are checked by actual header bytes, not the filename’s claimed type, and reprocessed server‑side into a fixed format regardless — so the stated rule and the enforced rule are never allowed to drift apart.
04
Documenting the “why,” including the “why not”
Every fix from this project’s security audit — two stored XSS issues, CSRF protection, session fixation, cookie hardening — is logged in CHANGELOG.md with the reasoning behind it. Just as deliberately, so are the two things I chose not to fix yet (a transitive audit finding in build tooling, not runtime code; an in‑memory session store that’s fine for a single instance). That’s the same instinct as a content style guide: the value isn’t just the current rule, it’s the recorded reasoning, so a future decision doesn’t accidentally reverse a past one without knowing why it existed.
05
Security as content integrity, not just a technical checkbox
The two stored XSS fixes both came down to the same root cause: user‑submitted content (a record’s title, artist, or mood) being trusted and interpolated as‑is into what every other visitor’s browser would render. Escaping that content before it reaches the page isn’t just a security fix — it’s protecting the storefront’s actual content layer from being hijacked into someone else’s message. Treating “what a user typed” and “what the page renders” as two different things to reconcile carefully is exactly the same discipline as editorial review, just enforced by helmet and an escapeHTML() helper instead of a human proofreader.
What I’d highlight for a hiring manager or client
Naming and structure as the actual product decision. The mood‑based taxonomy is a five‑minute‑sounding idea that does more for the shop’s identity than any paragraph of marketing copy would.
A documentation habit that mirrors content governance. Recording rationale for every fix — and every deliberate non‑fix — in a running changelog is the same discipline as maintaining a style guide: the reasoning has to survive past the moment the decision was made.
Rigor that transfers across domains. A self‑run audit that finds and fixes two real XSS vulnerabilities, then documents what was consciously left alone and why, shows the same care applied to security that I’d apply to a sentence.
Tech stack