Skip to case study
Parth AkholkarLet's talk
02Travel recommendation2026Live

MoodMap

MoodMap asks travellers why they want to travel, how they feel and who is coming, then ranks 843 real experiences in Thailand, Vietnam and Bhutan and turns the ones they pick into a day-by-day plan they can download as a PDF.

Client
Chal Kabira (travel company)
Role
Led the 5-person capstone (v1), then sole designer and developer
Stack
React + TypeScript · Express + Postgres · Vercel
MoodMap product interface
843experiences mapped by hand
66%expert-picked activities in our top 10, vs 33% for random picks
130automated tests

Snapshot

MoodMap asks travellers why they want to travel and how they feel, then picks real experiences for them in Thailand, Vietnam or Bhutan and turns the ones they choose into a day-by-day plan. It is built for Chal Kabira, a travel company whose team supplied the experience catalogue and the expert routes used to test it.

It started as MoodMatch, my capstone at Ahmedabad University, where I led a team of five and we matched people to 227 experiences in India and Thailand. Since then I have rebuilt it on my own: a new catalogue, a new matching engine, a chat option and a trip planner. Live at moodmapp.vercel.app.

Problem

Most travel sites start with the place: pick a country, then scroll a long list of things to do. That works if you already know what you want. It doesn't help someone who knows how they feel ("tired, I need quiet") but not which of a few hundred experiences would give them that.

Chal Kabira had a large catalogue and a team that plans trips by hand. They wanted a way to understand a traveller first and show only what fits, so a planner could pick up from there.

Two things made this harder than a filter:

  • Feelings are vague. A matcher can't act on "something relaxing but not boring" without a structured way to ask.
  • The catalogue had to be trusted first. The source spreadsheet had headings and booking checklists typed in as experiences, and tags that were plainly wrong, like bungee jumping tagged as wellness. Matching on those tags would have given confident, wrong answers.

Approach

Two ways in

The home page offers a short chat or a step-by-step quiz. Both lead to the same matcher.

  • The quiz starts with the practical questions: who is coming, where, which month, how many days, what they would love to do. Then 23 quick questions in three chapters: how they feel now and want to feel after, 12 statements that measure the five standard personality traits, and how much each of seven travel purposes matters to them.
  • The chat lets people type freely ("me and my wife, a quiet week in December"). It pulls out the facts it can, asks only for what is missing, then covers the same ground through short choices.

Mapping the catalogue by hand

I went through all 851 rows of the supplied catalogue one by one instead of trusting the source tags. Each experience got a main, second and third purpose, its setting and how demanding it is, flags like nightlife or not suitable for young children, and the interests it really serves. Headings and checklists came out. The final catalogue has 843 experiences: 479 in Thailand, 271 in Vietnam and 93 in Bhutan, each with a photo.

Scoring

Each experience is scored on how well its purposes line up with what the traveller said matters. Its main purpose counts three times, its second twice, its third once. Then the trip itself adjusts the list:

  • Matches for the traveller's interests or preferred setting move up.
  • Anything that breaks what they told us is pushed out: another country, seafood for a vegetarian, nightlife when children are coming, a steep climb for someone who wants an easy pace.

Finally the list is spread out so it isn't ten versions of the same temple visit. People see about four experiences per trip day.

The result

First a travel style card, for example "The Curious Maker", which people can share or download. Then their matched experiences, each with a photo, place and short reason. They tap "Add to trip" on the ones they like, and "Build my trip" turns the picks into a real plan: where they land and fly home from, which towns they sleep in, how long each drive takes, what happens each morning, afternoon and evening, and which picks didn't fit and why. The plan downloads as a PDF to share with family or send to a trip planner.

Decisions that mattered

  • Testing against the experts. To check whether mood and personality improved the ranking, I built a test from 61 trip routes written by Chal Kabira's own planners. Ranking on purpose plus the trip rules found the experts' named activities in the top ten 66% of the time, against 33% for ten random picks. Adding mood or personality didn't move that beyond noise. It is a sanity check rather than proof, since I mapped the catalogue too, so those answers are still asked and stored, and still power the travel style card, but they stay out of the ranking until real traveller ratings show they help.
  • Refusing a misleading accuracy number. On the earlier version's data, random picks already scored about 74% on "rated 4 or 5 out of 5". A target like "90% accurate" on that measure would have meant very little, so the honest comparison is our picks against hidden random ones.
  • Never mixing quiz versions. Every saved session records which version of the questions it answered, and a wording change counts as a new version, so results are never pooled across them. Weight tuning is locked until 150 clean sessions exist.
  • Plans people can actually follow. The first planner put one experience on each day. The rebuilt one starts and ends at a real airport, keeps nearby towns as day trips instead of extra hotel moves, switches to a domestic flight when the road would take more than six hours, and always says what didn't fit.
  • Keeping the AI in its lane. In the chat, a language model only reads facts from what people type, like a month or who is coming. It never chooses or invents experiences, and every fact it reads must appear in the traveller's own words. Every recommendation comes from the same fixed scoring.

Tech

  • React and TypeScript with Vite, hand-written CSS on design tokens, PDF generated in the browser
  • Node.js and Express; the matching engine is plain TypeScript with reference tests that fail if scoring changes by accident
  • PostgreSQL on Neon through Drizzle ORM for sessions, feedback and contact requests
  • An optional language model (Groq) that only reads trip facts from chat messages
  • Vercel, 130 automated tests, and an admin console for reviewing sessions, catalogue tags and scoring changes