Web App Live

Cut Tracker

A multi-user fat-loss tracking web app that accepts meal descriptions in any language and converts them into precise macro breakdowns via AI, presenting daily energy balance in a profit-and-loss accounting format.

Python FastAPI DeepSeek V3 SQLite bcrypt Railway
Background

Why I Built This

I wanted a dead-simple way to know my calorie balance at any point in the day — not a full nutrition app, just a quick answer to "am I in a deficit today?"

My first approach was a dedicated calorie-tracking app. The workflow was: search for the food, find the right entry, log the gram weight, repeat for every ingredient. It worked, but the lookup friction was real — and exporting data in any usable format was painful enough that I stopped doing it.

I switched to a personal Excel sheet with hand-written formulas. That removed the export problem, but I still had to look up macro values for every food item, either through an AI chat or a nutrition database, then copy numbers into cells. Two tools, two windows, lots of switching.

The fix was obvious: collapse everything into one step. Describe the meal in whatever language you think in, let DeepSeek handle the lookup and calculation, store the result automatically, and surface it as a clean dashboard with a one-click CSV export. That's Cut Tracker.

Usage Examples

In Practice

Logging a meal

DeepSeek understands any language — log in English, Chinese, Japanese, or whatever comes naturally.

English input
two scrambled eggs cooked in butter, a slice of sourdough toast, and a medium latte with oat milk
↓ DeepSeek parses & returns structured JSON ↓
Eggs (2, scrambled, ~10g butter) — 220 kcal · P 14g · C 0g · F 17g
Sourdough toast (1 slice, ~40g) — 105 kcal · P 4g · C 20g · F 1g
Oat milk latte (medium, ~350ml) — 130 kcal · P 4g · C 19g · F 4g
─────────────────────────────────────────────────────────
Total — 455 kcal · P 22g · C 39g · F 22g
中文输入
一碗白米饭,红烧肉三块,炒青菜一份,豆腐汤一碗
↓ DeepSeek 解析并返回结构化 JSON ↓
白米饭 (1碗, ~200g) — 260 kcal · P 5g · C 57g · F 1g
红烧肉 (3块, ~120g) — 395 kcal · P 18g · C 8g · F 32g
炒青菜 (1份, ~150g) — 80 kcal · P 3g · C 6g · F 5g
豆腐汤 (1碗, ~250ml) — 65 kcal · P 6g · C 3g · F 3g
─────────────────────────────────────────────────
合计 — 800 kcal · P 32g · C 74g · F 41g

Logging exercise

You type
45 min weightlifting + 20 min brisk walk
↓ MET-based calculation ↓
Weightlifting (45 min) — ~270 kcal
Brisk walk (20 min) — ~110 kcal
──────────────────────────────────
Exercise total — ~380 kcal added to TDEE

End-of-day balance

Dashboard shows
Net Intake (after TEF) — 1,840 kcal
TDEE (BMR × NEAT + exer) — 2,310 kcal
──────────────────────────────────────
Net Energy Balance — −470 kcal ✓ deficit

When the cut is done, hit Export — every logged day comes out as a CSV with per-item macros, daily totals, and energy balance, ready for further analysis in Excel or wherever.

Architecture

System Overview

Cut Tracker is a server-rendered web application with a Python/FastAPI backend, a SQLite database, and an AI integration layer that calls the DeepSeek V3 API for natural language macro parsing. Authentication is session-token-based with bcrypt password hashing and strict user-scoped data isolation.

Request Flow
Browser (HTML/CSS/JS)
FastAPI Server
Backend Layers
Auth Middleware
session tokens · bcrypt
Route Handlers
food log · activity · weight · admin
SQLite DB
records.db
AI Layer
Food Log Route
DeepSeek V3 API
multilingual input → macros JSON
Macro Parser
validate · store · calculate
Core Logic

How It Works

1. Food Logging via AI

Users describe meals in free-form text in any language — English, Chinese, Japanese, or mixed. The input is sent to DeepSeek V3, which returns a structured JSON object with per-item breakdowns: calories, protein, carbohydrates, and fat — both as consumed and per 100g serving. The server validates and stores the result, associating it with the user's session.

API cost is approximately $0.0001 per log entry. At one log per day, annual cost is under $0.04.

2. Energy Accounting Model

The core of Cut Tracker is a P&L-style energy balance calculation performed fresh on each dashboard load. The model mirrors how an accountant tracks profit: gross income minus costs equals net position.

Gross Intake = total calories logged − TEF deduction = protein×25% + carbs×8% + fat×3% = Net Intake (available energy) BMR × NEAT multiplier = resting + daily activity expenditure + Exercise calories = MET × weight × duration = TDEE (total daily energy expenditure) Net Energy = Net Intake − TDEE negative = deficit (green) positive = surplus (red)

3. NEAT Activity Multipliers

Non-Exercise Activity Thermogenesis is captured through a daily activity level selector. Multipliers are applied to BMR to compute baseline expenditure before exercise is added:

1.10
Rest day

Sedentary — desk work, minimal movement

1.20
Light activity

Light walking, some standing throughout the day

1.35
Moderate activity

On feet regularly, moderate physical demands

1.50
Very active

Physical labour, high-step-count day

4. Request Lifecycle

01
Authentication

Session token extracted from cookie, looked up in DB. Request is rejected if token is absent, expired, or unrecognised.

02
Input handling

Form data is sanitised. Food descriptions are forwarded to DeepSeek V3 with a structured prompt enforcing JSON output.

03
Persistence

Parsed macro data, activity entries, and weight measurements are written to the user's isolated rows in SQLite.

04
Dashboard computation

On each page load, the full energy balance is recomputed from today's records and rendered. Historical charts aggregate 7-day and 30-day windows.

05
Export

One-click CSV generation serialises all of the user's records and returns them as a file download.

5. Multi-user & Admin

All data queries are scoped by user ID derived from the session token — no cross-user data leakage is possible through the standard routes. A hidden admin panel at /admin is protected by a separate secret key and provides account creation and deletion capabilities.

Deployment

Infrastructure

The application is deployed on Railway, connected directly to the GitHub repository for continuous deployment. The SQLite database file is persisted via a Railway volume mount. Environment variables manage the DeepSeek API key, admin secret, and session signing key — none are committed to the repository.

GitHub Repo
→ push triggers deploy →
Railway Container
Environment Variables
API keys · secrets
+
Persistent Volume
records.db
cut.john-huang.com