Skip to content

Introduction

Tina Diet is a Thai-first AI nutrition coach delivered through a LINE Official Account and an embedded LIFF (LINE Front-end Framework) app. End-users log food via natural-language chat or photos, track macros against goals computed from their profile, and ask nutrition questions with a 20/day quota on the premium tier.

This site is developer documentation — for the project owner and future collaborators. End-user help lives in the LIFF SupportPage.

High-level value

  • Log food the easy way — text (“ผัดกะเพราไก่ + ไข่ดาว”), photo (premium), or manual form. AI parses to kcal + macros, asks for clarification when ambiguous (“ข้าวอะไรคะ?”).
  • Personalized goals — BMR/TDEE via Mifflin-St Jeor from gender, age, height, weight, activity level, and goal type (lose / maintain / gain).
  • Coaching — proactive meal suggestions after each log + on-demand consultation Q&A (premium).
  • Daily + weekly summaries — push via LINE at 21:00 ICT (daily) and Monday 08:00 ICT (weekly).
  • Streak motivation — fire emoji badge after 2+ consecutive days.

Repo layout

The repository at github.com/einsze/tinadiet is a monorepo:

tinadiet/
├── projects/
│ ├── backend/ Express + better-sqlite3 + LINE SDK + OpenAI + Omise
│ ├── liff/ Vite + React + Tailwind, deployed to Cloudflare Workers
│ ├── docs/ Astro Starlight (this site)
│ └── ops/ Operational runbooks (markdown only, no deploy)
└── README.md

Each projects/<name>/ is independently buildable and deployable. They share git history but have separate package.json and dependency trees.

Technology summary

LayerChoiceNotes
Bot platformLINE Messaging API + LIFFThai market reality
Backend runtimeNode.js 22 LTS, ESMTypeScript with tsx for dev
Web frameworkExpress 4Pragmatic, well-understood
Databasebetter-sqlite3 + SQLite file on Railway volumeSync queries; lazy stmts pattern
ValidationZod 4All API inputs
SessionjsonwebtokenHS256 over SESSION_JWT_SECRET
AIOpenAI SDK v6 (gpt-4o-mini, gpt-4o)Strict JSON schema for parsers
PaymentsOmise REST (no SDK)Stripe code dormant
FrontendVite 5 + React 18 + Tailwind 3@line/liff v2
Routingreact-router-dom v6Multi-page LIFF
Iconslucide-reactMatch Rich Menu style
Cronnode-cronDaily summary, weekly summary, expire premium
Hosting (backend)Railway (Singapore, Hobby)Volume mounted at /data
Hosting (LIFF)Cloudflare Workers Static AssetsSPA fallback config
Hosting (docs)Cloudflare PagesAstro + Starlight
RegistrarCloudflare Registrartinadiet.com

Brand & UX invariants

These shape almost every product decision. Don’t break them without discussion:

  1. Thai-first content, English navigation chrome. User-facing text (Tina’s replies, coaching, food parsing) is in Thai with the polite female ค่ะ register. Navigation labels (Home / Premium / Profile / Support) and technical UI (Gender, Height, Save) stay in English.
  2. Female persona “Tina” — Tina speaks to users in first person, kind tone, never accusatory about food choices.
  3. Profile-gated onboarding. No AI features (food parsing, coaching, consultation) until the user completes the profile form and we can compute BMR/TDEE.
  4. Manual-renew payment model. Premium does NOT auto-charge. User pays PromptPay QR or TrueMoney each month. Stripe code is preserved but currently dormant.
  5. Premium expiry stacks. Paying when still premium adds days to the current expiry, not from “now” — no day is ever lost. See Payments overview.

Where to next