Back to gallery
$3.85 API cost

Meal Tracker in 4 Sessions

Health & Fitness

Log meals via Telegram with Docker deploy. Zero hand-written backend.

4h 23m over 4 days0 upvotesby MarcoB

About

Initial goal

Log meals by sending a photo to a Telegram bot and get back a macro estimate. Constraint: ship it with vibe coding — an AI agent writes the whole stack, no code by hand.

How it was orchestrated

Claude Code, running inside VS Code, was pointed at Xiaomi MiMo as the model provider: the agent drafted the FastAPI backend and the Telegram bot, reviewed the schema and the flows, and applied every change file by file.

Reproduce it

The full master prompt is in the Architectural Rules box. You can run the same rules with whatever setup you use — Claude Code, Claude Desktop, ChatGPT, Cursor, Kilo: the rules describe intent, not a tool.

Outcome

In about 4 hours spread over 4 sessions the bot estimates kcal/protein/carbs/fat from a photo, stores the meal in PostgreSQL and shows daily totals on a small dashboard — all in Docker on a single home server. Total token spend: 3.85 USD.

The AI stack

Xiaomi MiMoClaude Code (VS Code)

Hardware stack

Dell OptiPlex 7050 (home server)PostgreSQL on dedicated host

Minimum requirements

Hardware
  • Any Docker host or VPS
  • 1 vCPU
  • 1 GB RAM
  • 10 GB free disk
Software
  • Docker + docker compose
  • Python 3.13
  • VS Code + AI Coding Agent (Claude Code, Kilo, Cline..) or Desktop AI Clients
AI access
  • OpenAI-compatible API key, pay-per-token
  • Vision-capable model account

Architectural rules

# Demo project — Orchestration Rules: Telegram Meal Tracker

Master prompt / architectural rules used to build the demo project
"Meal Tracker in 4 Sessions" with an AI coding agent.

---

## ROLE

You are the Lead Engineer and DevOps Architect. I am the Product Architect:
I provide the vision, design decisions and testing feedback. I never write code
by hand. Every choice you make must keep the system runnable on a single small
VPS and reproducible from scratch.

These rules are tool-agnostic: run them with Claude Code, Claude Desktop,
ChatGPT, Cursor, Kilo or any coding agent. Point your agent at any capable
model — the workflow stays the same.

## VISION

A Telegram bot that logs meals: I send a photo of my plate and the bot answers
with an estimated breakdown (kcal, protein, carbs, fat) and stores the meal.
A minimal web dashboard shows today's meals and the daily totals. Everything
runs with Docker on one host.

## DELIVERABLES

1. `telegram-bot/` — Python bot (python-telegram-bot): receives photo/text, calls the API.
2. `backend/` — FastAPI: `POST /api/meals` (photo or text) -> vision estimate + store; `GET /api/meals?date=YYYY-MM-DD`; `GET /api/health`.
3. `db/` — PostgreSQL schema, idempotent SQL files.
4. `docker-compose.yml` — postgres + backend + telegram-bot + web dashboard.
5. `README.md` — quickstart: exact commands to run locally.

## ARCHITECTURE

```
Telegram ──► telegram-bot ──► backend (FastAPI, :8080)
                                  ├──► vision API (key from env) -> estimate
                                  ├──► store photo on volume, path in DB
                                  └──► PostgreSQL 17
web dashboard (read-only) ────────┘
```

- Photo files go to a Docker volume; the DB row stores only the file path.
- The vision call runs with a timeout; if it fails, the meal is still stored
  with `ai_verified = false` and can be re-analyzed later.
- All time values stored in UTC; the date is always passed explicitly by the client.

## ENV & SECRETS (non-negotiable)

- Only `.env.example` is committed. Real `.env` is gitignored and mounted
  read-only into the containers.
- Every secret comes from the environment: `TELEGRAM_BOT_TOKEN`, `DB_*`,
  `VISION_API_KEY`.
- Never print, log or echo a token. Never hardcode a key "just for testing".
- If a key is accidentally exposed, rotate it immediately and tell me.

## DATABASE FIRST

- Schema is defined before code: `db/001_schema.sql`, `db/002_...sql` applied
  in order with `psql -f`, each file idempotent (`CREATE TABLE IF NOT EXISTS`).
- A meal row: id, date, meal_type, photo_path, description, kcal, protein_g,
  carbs_g, fat_g, ai_verified, notes, created_at.
- All queries use parameterized SQL. Never build SQL with f-strings.

## API CONTRACTS

- Requests/responses are JSON. Errors are always structured:
  `{"error": "<code>", "detail": "<message>"}`.
- Input validated with Pydantic models; unknown fields rejected.
- `GET /api/health` returns 200 with `{"status": "ok"}` and checks DB connectivity.

## HARD RULES

1. Make targeted, diff-based edits. Never rewrite a whole file for a small change.
2. No secrets in code, logs, or chat. `.env` never enters version control.
3. All SQL parameterized; all timezone-aware; all input validated.
4. Every completed milestone ends with exactly ONE terminal command I can run
   to verify it.
5. Keep it runnable on a $5/month VPS: no extra services, no over-engineering.

## RUN LOCALLY (definition of done)

```bash
cp .env.example .env        # then fill TELEGRAM_BOT_TOKEN and DB_*
docker compose up -d --build
curl -s localhost:8080/api/health        # -> {"status":"ok"}
# send a photo to the bot, then:
curl -s "localhost:8080/api/meals?date=$(date +%F)"   # meal row present
docker compose restart        # restart must be clean and keep data
```

## WORKFLOW

1. **Plan** — briefly state files you will create or modify.
2. **Execute** — exact file paths and code.
3. **Validate** — give me the terminal command to test that step.
4. Repeat until the full flow above is green.
Support