ZHAW
MSLS_V5_15 · Developing Software as a Product · FS26

Food Diary

AI-powered meal logging: clean code from day one

React Native FastAPI Supabase LogMeal AI Railway
Built with AI from commit one

My AI teammates

Perplexity
Perplexity
The Researcher
  • Research
  • API documentation
  • No code generation
Anthropic Claude
Claude
The Architect
  • Planning
  • Architecture
  • Issue design
GitHub Copilot
GitHub Copilot
The Builder
  • Implementation
  • Code generation
  • Reviewed on every PR
What it does

Goal

📷
Photo logging
Photograph food → AI identifies → calories logged automatically
✏️
Manual logging
Search ingredients → select amounts → save to diary
📅
Daily diary
Entries grouped by date with total daily calorie tracking
Why a new project?

A different starting point

TYPICAL APPROACH
  • Existing messy project
  • Retrofit clean practices
  • Before → after story
THIS PROJECT
  • Empty repository
  • Every practice from commit one
  • No before, only after
Day zero

Before writing any code

01 · Tech stack
  • React Native + Expo
  • FastAPI (async, typed)
  • Supabase (auth + db + storage)
  • Railway (deployment)
02 · Architecture
  • Proxy pattern
  • API key stays server-side
  • Mobile never calls AI directly
  • Clean separation of concerns
03 · Workflow
  • main = protected release branch
  • dev = integration branch
  • PR-only · Copilot review required
  • [log:slug] on every commit
Architecture decision

Chosen design: secure API proxy

Mobile app
React Native + Expo
->
Backend API
FastAPI routers + middleware
->
External services
LogMeal + Supabase
Factual design choices
  • Backend exposes /auth, /diary, /profile, /logmeal routers
  • Mobile never calls LogMeal directly
  • API keys stay server-side in backend environment
  • Supabase handles auth, Postgres data, and image storage
Why this architecture
  • Security: no third-party secrets in mobile app
  • Control: backend can enforce validation and error mapping
  • Flexibility: swap LogMeal integration without app-side changes
  • Operations: one CI path for lint, tests, and deployment
Git workflow in practice

Branch strategy with PR merges

Git branch and merge graph
main
Protected release branch. Merge target after validation.
dev
Integration branch. Work lands here through pull requests.
test / review
Short-lived working branches. PRs are reviewed and merged into dev, then main.
Enforced flow
Issue branch → PR → CI checks → review → merge
Project structure

From scaffold to full project

Day 0 3 folders · 3 files
FOOD-DIARY [GITHUB]
▶  backend
▶  docs
▶  mobile
    .gitignore
    AI_USAGE.md
    README.md
Now 7 folders · 13 files
FOOD-DIARY [GITHUB]
▶  .githooks
▶  .github
▶  .vscode
▶  backend
▶  demos
▶  docs
▶  mobile
.gitignore
AI_USAGE.md
CHANGELOG.md
codecov.yml
CONTRIBUTING.md
DEV_LOG.md
LICENSE
LIMITATIONS.md
package-lock.json
PRODUCT.md
PROJECT_STATE.md
README.md
setup.sh
from Day 0 new folders scripts / changelog documentation config / lock
What was applied

Engineering practices

Repository hygiene
README · LICENSE · Issues · branch protection
Git workflow
main/dev branches · PR per issue · commit convention
Clean code
Modular · type-safe · zero debug statements
IDE setup
.vscode/ · ESLint · Prettier · Ruff · launch configs
Testing
pytest · Jest · business logic covered
Profiling
cProfile → flamegraph → decision documented
CI / CD
Lint · test · coverage · deploy on every PR
Virtual envs
Dockerfile · devcontainer · pyproject.toml · lockfile
Testing strategy

Coverage split by code area

Backend
40.0%
209 / 523 lines covered
Frontend
7.4%
59 / 798 lines covered
Whole code
20.3%
268 / 1321 lines covered
Coverage source (local reports)
Backend: backend/coverage.xml
Frontend: mobile/coverage/lcov.info
Combined value is weighted by total covered lines.
Performance profiling: POST /logmeal/segment

Call stack breakdown

100 %
app.routers.logmeal.segment
3,547 ms
95 %
httpx.AsyncClient.send [LogMeal API call]
3,375 ms
87 %
ssl.SSLSocket.read ← HOTSPOT
3,091 ms
Network I/O wait · LogMeal ML inference time · not Python CPU
8 %
StorageFileAPI.upload [Supabase]
291 ms
5 %
FastAPI + Python application logic
165 ms
Key finding
The 87% hotspot is network I/O, not Python code. The LogMeal API's food-recognition model processes the image server-side. Python execution (including Supabase upload) represents only 5% of total latency.
Profiling result

Why only LogMeal was profiled

87%
LogMeal API
ssl.SSLSocket.read
~3,091 ms
8%
Supabase Storage
non-blocking
~291 ms
5%
Python code
FastAPI + logic
~165 ms
Why profile LogMeal?
87% of wall time blocked in ML inference on external servers. Decision: external bottleneck cannot be optimised from application code. Mitigations in place: 30s timeout, 429 proxying.
Why not profile others?
Postgres: not a bottleneck at current data scale. Storage: non-blocking, async. Python code: 5% of total, yields ≤165 ms max, not worth optimising.
CI/CD evidence from GitHub Actions

All required checks are green

Push checks passed
Push checks: Backend, Mobile, AI usage check, deployment
Pull request checks passed
Pull request checks: Backend, Mobile, AI usage gate
Backend lint and test job details
Backend job: Ruff lint, format check, pytest, CodeCov upload
Mobile lint and test job details
Mobile job: ESLint, Prettier check, Jest with coverage, CodeCov upload
AI usage disclosure check details
Policy job: Verify AI_USAGE.md entry exists for each commit
Continuous integration and deployment

What runs on every pull request

CI: passing Coverage: ~20% AI usage: enforced
Standard pipeline
  • → Ruff lint + format check
  • → ESLint + Prettier check
  • → pytest with CodeCov upload
  • → Jest with CodeCov upload
  • → EAS Build → Android APK
  • → Railway deploy on merge to main
AI enforcement
  • → Pre-commit hook reads message
  • → Extracts [log:slug] token
  • → Checks AI_USAGE.md for entry
  • → Rejects commit if missing
  • → GitHub Actions repeats on PR
  • → PR blocked without valid entry
Non-standard contribution

AI accountability: enforced technically

Every commit carries a log token
feat(#13) [log:copilot]: photo log screen
fix(#11) [log:manual]: bbox scale formula
docs(#33) [log:claude]: CONTRIBUTING.md
Hook rejects any commit without [log:slug]
Three tools, three purposes
Perplexity
Research · API documentation · no code generation
Claude (Anthropic)
Planning · architecture · issue design
GitHub Copilot
Implementation · code generation · reviewed on every PR
State at end

What was delivered

34
issues closed
100%
CI checks passing
~20%
unit test coverage
v1.0.0-beta
GitHub release + APK
✓ Working Android APK (EAS Build)
✓ README + Architecture doc
✓ Deployed FastAPI backend (Railway)
✓ User manual + Profiling report
✓ Full CI/CD pipeline
✓ CHANGELOG + CONTRIBUTING.md
✓ GitHub Release with APK attached
✓ All five user flows functional
Mobile app demo

Core user flows

Login screen
Auth
Diary screen
Diary
Profile screen
Profile
Manual log screen
Manual log
Photo log screen
Photo log
Photo segmentation result
AI segmentation
Questions
Architecture · Codebase · Profiling · AI usage · CI/CD
GitHub repo CodeCov Architecture doc Flamegraph SVG