Case study · Web & product
Makan Go Where: the meetup spot that's fair to everyone
Never argue about where to meet again. A host shares a link, friends drop their location, and a fairness score ranks nearby food spots so everyone's travel time comes out roughly equal.
01The problem
Picking where a group eats is a genuinely annoying coordination problem. Someone suggests a place near themselves, everyone else quietly does the maths on how far they'd have to travel, and the "decision" drifts for twenty messages. The real question isn't "what's central" on a map — central by distance can still mean one friend takes an hour on transit while another walks five minutes. The fair question is about travel time, per person, and no one wants to compute that by hand.
02Constraints
- Zero join friction. Friends must be able to join from a link with nothing more than a name — no signup, no install.
- Live and multi-user. As people join and drop their locations, the whole group's ranking has to update in real time.
- Real travel times, watched cost. Fairness depends on actual door-to-door times from a maps provider, which are metered API calls — so the app has to be economical about how many it makes.
- Ship it properly. This is a modern production stack with real test coverage, not a weekend hack.
03Approach
A host starts a session and shares an invite link. Friends join through Supabase anonymous auth — just a name — and drop their location and travel mode. The app finds nearby restaurants via Google Places, gets each person's travel time via the Distance Matrix, and ranks results with a fairness score of 0.6·spread + 0.4·mean: weight the spread of times heavily so the winner is the option where nobody is badly disadvantaged, then break ties on the average. Supabase Realtime pushes updates so every member sees the ranking move as the group forms. A second "meet at the MRT" mode finds the fairest transit station for the group and shows food around it — a distinctly Singaporean way to meet.
04Architecture
Next.js client
Host + guests. Join by link, drop location & travel mode.
Supabase
Anonymous auth, Postgres, Realtime sync across the group.
Google Maps
Places for candidates, Distance Matrix for per-person times.
Fairness scorer
0.6·spread + 0.4·mean. Ranks spots or MRT stations live.
05One hard decision & the trade-off
Define fairness as 0.6·spread + 0.4·mean — weighting how unequal the travel times are more than how long they are on average.
The intuitive default is to minimise total or average travel time, but that quietly rewards options that are great for the cluster and brutal for the one person on the edge of the group — exactly the outcome that starts arguments. Prioritising the spread means the app defends the worst-off member first, which is what people actually mean by "fair". The trade-off is that the mathematically most convenient spot doesn't always win, and the weights are a judgement call rather than a proof; I tuned them to match how a considerate human would choose, and kept the mean term so ties don't resolve into somewhere absurdly far for everyone.
06Outcome
The foundation shipped on a feature branch with 66 tests passing: sessions, anonymous join, live ranking and the fairness engine all work end to end. It's an honest work-in-progress — the station-hero UI, full realtime E2E and expanded station data are still on the list — but the core idea, that the fair meetup spot is a solvable problem and not a group-chat argument, is real and running.
Tech
- Next.js 16 (App Router)
- React 19
- Supabase (Postgres · Realtime · anon auth)
- Google Maps Platform
- Tailwind v4
- Vitest
07FAQ
How is the "fair" meetup spot actually calculated?
For each candidate restaurant the app pulls every person's travel time via the Google Distance Matrix, then scores the option as 0.6 times the spread of those times plus 0.4 times the mean. Weighting the spread more heavily means the winner is the place where nobody gets stuck with a much longer trip than everyone else — fairness first, convenience second.
Do my friends need to sign up to join?
No. Joining uses Supabase anonymous auth — a friend opens the invite link, enters just a name, and drops their location and travel mode. There is no account, no password and no app install, which is the whole point: the friction of organising the meetup should be near zero.
What is the "meet at the MRT" mode?
Instead of ranking restaurants directly, this mode finds the transit station that is fairest for the whole group to reach, then shows the food around it. It's a deliberately Singaporean take — most groups here meet at an MRT station first and eat second.
Need an internal tool that runs without IT approval?
Let's talk. If there's a coordination problem your team keeps solving by hand, it can usually be turned into software.
Get in touch