Customer Support Ticketing System
The problem.
Every support tool I've used treats realtime as the source of truth. It isn't. The source of truth is the database — the API is the contract — and realtime is the layer that keeps clients in sync between requests. When those get confused, the queue starts lying to people.
I built this end-to-end: JWT-authenticated REST APIs for tickets, replies, and history. Postgres tables shaped around audit tracking so nothing gets rewritten. Socket.IO overlaid on top of REST for live status changes — but the API is always what actually persists.
The whole stack ships in Docker Compose with seed data that mimics a real queue, so the demo isn't a shell. There are customers, agents, admins, tickets in every state, and a permission model that behaves like a support desk actually behaves.
“The database is the source of truth. Realtime keeps clients honest between requests.”

Building the backend for this taught me how much frontend framework noise I'd been carrying — how many decisions I was making by convention instead of by need. When you own the whole stack, the app gets smaller. Fewer moving parts, clearer seams.