Case study 02 / Mobile and backend delivery
Pre-release · TestFlight beta
Food Checker
From label photo to an accountable result.
Food Checker is an iOS ingredient-scanning project built across the full delivery path: camera workflow, OCR, configurable ingredient rules, a hardened FastAPI service, Supabase-backed account and data flows, automated AWS releases, and private monitoring.
Beta software. OCR and ingredient matching may be incomplete or inaccurate. Food Checker is informational only and does not replace product labels or professional advice.
- Mobile client
- Expo / React Native
- Analysis API
- FastAPI + Tesseract OCR
- Data and auth
- Supabase / PostgreSQL
- Delivery
- GitHub Actions + ECR + SSM
- Infrastructure
- Terraform + Ansible
01 / Mobile workflow
Scan, review, correct the input.
The mobile client is the entry point, but not the whole system. It collects a label, presents structured results, and gives users control over the rules applied to each scan.
02 / Analysis pipeline
A bounded path from image to result.
Each stage is explicit so failures can be validated, logged, and explained instead of collapsing into a generic scan error.
- 01Label photoCamera or library input
- 02Validate + preprocessType, size, cleanup
- 03Tesseract OCRExtract ingredient text
- 04Normalize + apply rulesUser-selected concerns
- 05Structured resultRisk, summary, matches
03 / System boundaries
Public use, controlled delivery, private observation.
The architecture separates what the app needs publicly from what operators need privately, while keeping deployment access reviewable and short-lived.
Application path
- 01Expo / React NativeiOS client
- 02Caddy HTTPSPublic reverse proxy
- 03FastAPILocalhost container
- 04SupabaseAuth and PostgreSQL
Release path
- 01GitHub ActionsChecks + image build
- 02AWS OIDCShort-lived auth
- 03Amazon ECRVersioned image
- 04AWS SSMRun Command deploy
- 05EC2 ComposePull, restart, verify
Observability path
- 01FastAPI metricsRequest and service signals
- 02PrometheusPrivate collection
- 03GrafanaPrivate tunnel access
04 / API and release hardening
Trust behavior, not a green process light.
- 01
Traceable requests
X-Request-ID, method, path, status, and duration make API failures easier to follow without exposing sensitive internals.
- 02
Safer uploads
MIME checks, size limits, temporary-file cleanup, OCR timeout handling, and clear unreadable-label errors bound the scan path.
- 03
Closed raw API access
FastAPI binds to 127.0.0.1:8000. Public traffic reaches it through Caddy and HTTPS; the raw port is not exposed.
- 04
Credential-light delivery
GitHub Actions uses AWS OIDC and SSM rather than long-lived cloud keys or SSH as the default deploy path.
- 05
Behavioral deploy check
Releases verify both
/healthand a knownPOST /analyzerequest before the workflow treats deployment as successful. - 06
Capacity discovered through monitoring
Disk pressure led to cleanup, shorter Prometheus retention, and expansion of the root volume from 8 GiB to 20 GiB.
05 / Operational evidence
Private monitoring, public explanation.
Grafana itself remains off the public internet. This snapshot documents the signals used to understand service state, request behavior, target health, and host capacity.
06 / Release confidence
Checks at each delivery boundary.
- Backend CI
- FastAPI import and pytest across analyzer, auth, OCR, upload, and API smoke behavior.
- Mobile CI
npm ci, Expo public config validation, TypeScript typecheck, and lint.- Runtime image
- Production dependencies stay separate from test tooling before the image is pushed to ECR.
- Post-deploy
- Health plus a synthetic ingredient-analysis request verify the deployed behavior.
Technical index
Food Checker technology
Expo · React Native · iOS · TypeScript · FastAPI · Tesseract OCR · Pillow · Supabase · PostgreSQL · Docker · ECR · Terraform · Ansible · GitHub Actions OIDC · AWS SSM · EC2 · Caddy · Prometheus · Grafana