MakanLagi
Know why they stopped coming — before they stop for good.
Lab
Lab 4 — Customer Experience & Engagement.
The problem
A neighbourhood restaurant loses a regular and never finds out why. The diner doesn't complain and doesn't leave a review — they just quietly stop coming. By the time the owner notices the drop in takings, the reason is months old and unrecoverable.
Loyalty apps answer this with volume: the same 10% coupon blasted to everyone on the list. That trains customers to wait for discounts, costs margin on people who were coming anyway, and still never answers the only question that matters — why did this particular person stop?
Two things are missing:
- Nobody tells you why. Silence is the default. Complaining is awkward, and public review sites reward performance rather than useful detail.
- Nobody knows if the fix worked. "They came back once" is treated as success, when the real question is whether they came back and stayed.
Our solution
MakanLagi turns a restaurant's own order history into an early-warning system, and turns one line of diner feedback into evidence the kitchen can act on.
- It notices when a regular's personal rhythm breaks — not a fixed "30 days inactive" rule, but their own cadence.
- It works out why from what the diner actually said and photographed.
- It sends each person the message that fits their reason — a diner who complained about a dry dish hears "we've fixed it", not a generic coupon.
- Rewards are SPL tokens on Solana, owned by the diner, redeemable by burning the token on-chain — so redemption is verifiable and the reward travels between restaurants.
How it works
1 — Detect
Pure functions over the restaurant's own data:
baseline_cadence = average days between that diner's consecutive orders (needs ≥3 orders)
at_risk = days_since_last_order > 2 × baseline_cadence
silent_churn = opened the app inside the window AND ordered zero times in it
silent_churn is the one most systems miss: app-open events are tracked separately from
orders, so a diner browsing without buying is visible before they disappear.
2 — Understand
After a meal, the diner writes one line and can attach a photo. A single multimodal Gemini call reads text and image together and returns structured JSON: the issue category, the specific dish, tap-to-answer follow-up options written for that meal, a photo authenticity verdict, and a plain-English summary for the owner.
There is no keyword matching anywhere — follow-up options like "Lacked enough sauce" are generated per meal, not drawn from a fixed list.
3 — Grade the evidence
| Evidence | Reward | What the owner sees |
|---|---|---|
| Verified — photo + review | 15% | Highest confidence |
| Verified from review | 10% | They told us |
| Vague, or photo we can't trust | 0% | Inferred / No signal |
Vague feedback and unverifiable photos earn nothing — but the review is still recorded and still reaches the owner. Withholding a reward is not the same as silencing a complaint.
4 — Intervene
A lookup maps (reason × evidence) to one of five distinct interventions, each with its own copy: dish-fix reward, priority seating, value bundle, reorder nudge, neutral invite. One tap sends to a filtered group — and the UI shows the owner that the group will receive different messages, not one blast.
5 — Redeem on-chain
The diner taps Use Reward and gets a 6-digit code valid for 10 minutes. The
restaurant enters it at the counter, which burns the SPL token on devnet. There is no
redeemed = true column anywhere in the system.
6 — Measure what matters
Success is Sustained Return: is the diner back at their normal cadence 30 days after the win-back, within ±20% of baseline? Not "did they come back once".
Technologies and tools
| Layer | Tool |
|---|---|
| Framework | Next.js 15 (App Router), React 19, TypeScript |
| Styling / motion | Tailwind CSS v4, GSAP |
| AI | Google Gemini (gemini-3.6-flash, multimodal — text + image in one call) |
| Blockchain | Solana devnet, @solana/web3.js, @solana/spl-token |
| Data | JSON fixtures (production path would be Supabase) |
| Deployment | Vercel |
Target users
Primary — independent restaurant owners. Family-run kampung restaurants, kopitiams, single-outlet operators. People who know their regulars by face but have no way to notice one has quietly stopped coming, and no marketing budget to compete on discounts.
Secondary — diners. Anyone who has had a mediocre meal, said nothing, and simply never returned. They get a channel that takes ten seconds, plus rewards they actually own rather than points a merchant can devalue or expire.
Beneficiary — struggling neighbourhood restaurants. The Discover & Support pool gives quiet kitchens a bonus reward multiplier, pointing demand at the places that need it most rather than the ones that already market best.
What makes it unique
1. It answers why, not just who. Most retention tools output a list of lapsed customers. Ours attaches a reason, labels it Verified or Inferred, and shows the diner's own words — so an owner can tell "she told us the chicken was dry" apart from "we're guessing".
2. Silent churn. App opens are tracked separately from orders, catching the diner who is still browsing but no longer buying — visible before they lapse.
3. Evidence-graded rewards, verified by photo. The AI judges whether a photo is genuine and plausibly matches the order. Specific, verifiable complaints earn more; vague ones earn nothing. This raises the cost of farming rewards with noise.
4. Solana does something a database cannot. Redemption is the burn. There is no "used" flag to flip, so a restaurant cannot mark a reward used without the chain agreeing, cannot un-burn one to double-charge, and cannot quietly expire what it already gave. The dashboard's redemption status is a live chain query, and if the chain is unreachable the UI says so rather than falling back to our own records.
5. Loyalty that belongs to the diner. Because rewards live in a wallet rather than a merchant's customer table, a second restaurant recognises a diner it has no history with — loyalty is portable, not locked to one venue.
6. It measures whether the fix held. Sustained Return tracks cadence 30 days after a win-back, distinguishing a real recovery from someone who took the discount and left.
7. Restraint is enforced, not suggested. A diner who switches off nudges is removed from every campaign group with no override available to the restaurant — the opt-out is checked server-side, not just hidden in the UI.
Log in or sign up for Devpost to join the conversation.