Back to projects
Case Study · 2026 · Design and engineering, end to end
Santul
Meals, workouts and weight, kept in balance.

Overview
Overview
A daily tracker for food, workouts and weight, made for how people in India actually eat. It is personal from the first screen: you tell it your diet, your allergies and your goal, and every grade, warning and target after that is worked out for you rather than for an average person.
The problem
Why this exists
Most trackers assume packaged Western food weighed in grams. Indian meals are cooked at home and served by the katori, so logging them means guessing. And a calorie count alone does not say whether a food is a good idea for this person, with this diet and these allergies.
Constraints
Constraints
- Logging a meal has to take seconds, or it never becomes a habit
- It is used one-handed on a phone, so the main action always sits within thumb reach
- A grade with no explanation is just a verdict. Every one has to say why
- Nothing here is medical advice, and the app has to keep saying so
Architecture
How it's built
- A Next.js app on Vercel, written in TypeScript with Tailwind and shadcn/ui. Sign-in is Google only
- Everything you log (meals, workouts, weight, your profile) lives in a Postgres database on Neon
- The food catalogue is seeded from three open datasets: INDB for Indian dishes, USDA FNDDS, and Open Food Facts India for packaged food. A barcode that is not in it is looked up live on Open Food Facts
- Photo scans are read by Google Gemini. The photos themselves are never saved: a successful scan keeps one small image, 480 px wide, in a private Cloudflare R2 bucket, and deleting the scan or the account deletes it
Tradeoffs
Tradeoffs
- Workouts are shown beside the food and never added back to the calorie target. Eating back exercise is the easiest way to undo a deficit
- Five grades, A to E, instead of a score out of 100. A number that precise would claim more than the data can support
- Scanning a barcode is always free; reading a photo is limited each month. The free path had to be good enough that most people never notice the limit
- One way to sign in, with Google. No passwords to create or forget
Lessons
Lessons learned
- The slow production site was geography, not code. The functions ran in the United States and the database in Singapore, so every query crossed an ocean. Counting queries per page was worth doing, but measuring where the time went came first.
- A check that only passes on your own machine is not a check. One test kept failing in CI, unnoticed, because it relied on an environment variable being unset, which it never is there.
- Errors that are swallowed turn into mysteries. Sign-out quietly stopped working after a domain change because the failure was ignored and the user was sent back into the app.