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.

Next.js 16 · React 19 · Supabase · Google Maps Status: WIP · 66 tests + build green

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

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

05One hard decision & the trade-off

The decision

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

66tests, build green
0signups to join a session
2modes: food spot or MRT

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

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