Private-repo case study

From kitchen photos to a product people can keep using.

My Four Sous Chefs turns everyday kitchen inputs into recipes and meal plans. This walkthrough focuses on how the product handles messy image input, model calls, accounts, subscriptions, usage, and failure, not just the generated result.

My Four Sous Chefs app showing image upload and AI chef selection

I built the product end to end, from the family-facing flow to the service boundaries and controls behind it.

My Four Sous Chefs ingredient input screen with image upload and AI chef options
Product surface Ingredient capture and chef selection keep the experience centered on the decision that matters: what to make for dinner.
Scope

Product architecture, front end, API, persistence, billing, model workflow, and production controls.

End-to-end flow

Messy input, generated results, saved recipes, plans, account state, and entitlements all belong to one product experience.

Working standard

Cost, abuse prevention, fallbacks, logs, and automated tests were product requirements from the start.

01

Capture messy kitchen context

Users can bring photos, pantry lists, shopping-list context, and preferences. The interface keeps the task familiar: show what you have, choose a direction, and decide what to cook.

02

Turn inputs into usable data

Image preprocessing, OCR, vision-assisted extraction, structured parsing, and normalization convert imperfect inputs into ingredients the rest of the product can trust.

03

Generate recipes people can act on

Model calls stay behind API boundaries with typed responses, fallback handling, token-budget awareness, and UI states for slow or partial results.

04

Keep results useful after generation

Saved recipes, meal plans, usage records, account state, and entitlements make the app useful beyond a single request.

TypeScript product system

My Four Sous Chefs is organized as a TypeScript monorepo: React and Vite for web, Expo and React Native for mobile, Express for the API, shared domain packages, and Supabase-backed persistence for user and product state.

The split keeps the product fast to iterate while protecting the boundaries that matter: model calls, billing events, identity, quotas, and saved user data.

Web
React 19, Vite
Mobile
Expo, React Native
API
Express, TypeScript
Data
Supabase, PostgreSQL
External
Claude, Stripe, Turnstile
  • TypeScript
  • React 19
  • Vite
  • React Native
  • Expo
  • Express
  • Supabase
  • PostgreSQL
  • Stripe
  • Claude
  • Sharp
  • Tesseract OCR
  • Vitest
  • Playwright
  • Cloudflare Turnstile
Cost

Meter before expensive work starts

Identity-aware limits, daily and monthly token budgets, request metering, and reservation-style accounting control usage before provider calls are made.

Abuse

Treat model endpoints as protected resources

Cloudflare Turnstile, authenticated usage records, and quota-aware API paths reduce abuse without making the family-facing flow feel hostile.

Reliability

Design for partial success

Structured logging, observable request outcomes, rollback handling, and automated coverage around critical flows keep failures understandable and recoverable.

Boundary

Keep model calls server-side

Provider keys, cost controls, prompt assembly, and structured parsing stay behind server boundaries. The client owns interaction quality; the API owns trust, metering, and external calls.

Data

Persist useful product state

Recipes, plans, account state, and usage records are first-class data. This makes the product useful after the first generation and gives production controls durable state to enforce.

Delivery

Choose familiar deployable parts

I kept the deployment pieces familiar so effort could go into input quality, generation, billing, and reliability.

The visible experience is a React product. Behind it are the less visible concerns that decide whether a model-backed feature can stay useful: messy inputs, variable outputs, provider costs, subscription state, operational feedback, and user trust.

The repository is private, so this page focuses on decisions I can show clearly: system boundaries, data flow, billing, usage controls, and failure handling.