The product
I broke this into three problems that had to be solved together: get the happy hour data right, build an interface people would genuinely want to search with, and make sure the whole thing could stay alive instead of going stale like everything before it.
NYCHappyHours.org now covers 1,000+ confirmed happy hours inside a 2,300-venue directory across all five boroughs—list and map views, live/upcoming status, last-call timing, location-aware sorting, saved spots, and venue-level deal details. None of it was designed once and shipped; it came out of dozens of iterations with real people using the site at every step.
Years-old Reddit threads from people who’d tried this before, small current blog lists, news posts, and the spots my friends and I had already been going to for years—reconciled into one structured dataset instead of another scattered list.
The data problem
The backbone was never one clean source—it was Reddit threads, blog roundups, news posts, and personal recommendations from years of actually going out in this city. The hard part was normalizing that into something a site could run on.
My first instinct was a Google Sheet: editable by anyone, no infrastructure. But happy hours don’t fit a spreadsheet cleanly—different hours, different food specials by day, different drink specials by day, across thousands of venues. The honest options were ~50 columns per venue or a handful of columns with a tightly structured string parsed later in PostgreSQL. I went with the latter—fewer columns, more parsing logic. The tradeoff: adding a venue by hand was fragile, one bad character and the schedule wouldn’t parse. Fixing that fragility is what the admin system below was actually for.
Building it to outlast the launch
A directory like this usually dies the same way: someone builds it, stops maintaining it, and it goes stale. I didn’t want to build version three of that same failure, so the system for keeping it current went in before I called it an MVP. Two Google Forms—one for issues and inaccuracies, one for suggestions and new venues—feed into a backend admin page built for actually acting on submissions, not just collecting them.
I could have handled updates in code and skipped a real admin interface—for most side projects that’s the pragmatic call. Here it would’ve defeated the point: a code-only backend turns every correction into an engineering ticket instead of something I, or eventually anyone I trust, can fix from a phone in under a minute. That admin layer is also what finally solved the fragile-entry problem from the data pipeline—it validates and structures new submissions before they touch the live dataset, so the site can grow without every entry needing my direct review of raw strings.
Product and reliability work
- Venue cards, map mode, and filters as the three core ways into the data—rebuilt repeatedly after watching real users get stuck.
- Redundant access points for the same information (location, price, cuisine): learned that a feature only “exists” if it’s visible where someone’s actually looking, not just present somewhere on the page.
- Mobile-first layout built for someone deciding where to go in the next twenty minutes, not browsing at a desk.
- A submission-and-correction loop (two intake forms + admin review) that keeps the dataset from drifting out of date.
TLDR
- A real gap in a saturated market, validated by actual usage—not assumed from a spreadsheet.
- A deliberate data-modeling tradeoff (structured strings over wide tables), made on purpose and fixed later instead of avoided.
- UI changes driven by watching people miss features that were already there, not by guessing what they’d want.
- Built so it doesn’t need me specifically to keep running.