Work / 01 of 06

Coach

iOS app · nutrition & training

Log Greek groceries, weigh in, and get calorie targets that adjust to your real results every Monday.

Visit Coach
Role
Solo: product, iOS app, back end and website
Years
2026
Status
Beta on TestFlight
Stack
SwiftUI · Supabase · Next.js
Coach on desktop and mobile

The brief

A nutrition and training app built around Greek groceries. Instead of fixed calorie targets, Coach moves them every week from the user's real weight trend.

What I built

  • A native SwiftUI app: food diary, barcode scanning, meal-photo macro estimates, daily check-ins, workouts with a live set logger, progress, friends and a home-screen widget.
  • A Supabase back end: Postgres with row-level security, nine Deno Edge Functions, and a pg_cron job that writes every user's weekly meal plan on Monday.
  • Two catalogues behind it, food-lib.gr and workout-lib.gr, reached only through Edge Functions so no API credential ships in the app.
  • RevenueCat subscriptions, and a bilingual marketing site with a working copy of the app on a 3D phone.

Decisions

  1. 01

    Targets that learn

    Each week the calorie and macro targets move with the average weight change, following Helms (2014), Barbalho (2020) and Morton (2018). Adjustments are capped at ±300 kcal with a 1,200 kcal floor, and an adaptive TDEE estimate is written back every week.

  2. 02

    A failed read is not an alert

    Network failures are classified: a failed read renders inline, and only a failed write raises a modal. The diary and favourites read through an on-disk cache so they work offline. Search is never cached, because a stale hit means logging the wrong macros.

  3. 03

    AI behind a meter

    Meal-photo and food-search AI runs in Edge Functions. The key never enters the app bundle, and calls are metered per user, per day and per tier on the server.

  4. 04

    Zero warnings, kept at zero

    The build went from 124 warnings to 0 in July 2026, most of them Swift 6 concurrency diagnostics. A clean test run has to stay silent before anything is pushed.