Skip to content

Latest commit

 

History

226 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NutriScan

Live: nutritional-tracker-delta.vercel.app

Demo build: VITE_DEMO=1 npm run build (or npm run dev) in frontend/ runs the whole app on synthetic in-memory data: no backend, no account, no AI calls, no network requests. Useful for a quick look or screenshots.

About

NutriScan turns a photo of any nutrition label into tracked macros in seconds. Snap the label, and AI vision reads the calories, protein, carbs, fat and fibre for you. No barcode database, no manual typing, no guesswork with foods that aren't in an app's catalog.

From there it works like a full nutrition tracker: log foods against personal daily goals, save favourites into folders, build meal templates that log an entire breakfast in one tap, review weekly trends, and chat with an AI assistant that already knows your log, your goals and your last seven days. Meal reminders and goal notifications arrive as real push notifications at times you choose.

It ships as an installable PWA: add it to your home screen on iOS or Android and it looks, launches and notifies like a native app, with light and dark mode and user-controlled updates. Under the hood it is a React frontend and a FastAPI backend on serverless Postgres, with row-level security isolating every user's data at the database layer.


How to Use

1. Sign in. Google OAuth (with account picker) or an emailed 6-digit code. No password needed.

2. Scan. Go to the Scan tab and upload a photo of any nutrition label. The AI extracts all macro data instantly. Up to 10 images at once, and each account gets 10 free scans per day.

3. Log. From scan results or your Library, tap Log to add a food to today's tracker.

4. Track. The Tracker tab shows today's macro totals (calories, protein, carbs, fat, fibre) against your personal goals with progress bars. Use the calendar to view any past day.

5. Library. Save scanned foods to named folders for quick re-logging without scanning again. Build Meal Templates by multi-selecting foods, then log a full set (e.g. "Breakfast") to the tracker in one tap.

6. Trends. Daily breakdown of the last 7 days with per-macro columns and average summary cards.

7. AI Assistant. Its own tab: a chat that knows today's food log, remaining macros, and 7-day averages. Multi-turn, context-aware, with server-side safety guardrails.

8. Notifications. Enable them in Settings. Goal-reached and scan-limit alerts are automatic; meal reminders and a Sunday weekly summary are opt-in, each at a time you pick (like 9:00 AM or 11:00 AM).

9. Settings. Notification controls, contact links, dark/light mode from the top bar, and full account deletion.

10. Install as PWA. iOS: Share, then Add to Home Screen. Android: browser install prompt. When a new version is available, a banner shows exactly what's new and you choose when to apply it.


Stack

Layer Tech Notes
Frontend React Vite React 19, Vite, CSS custom properties, light/dark themes
PWA PWA vite-plugin-pwa, Workbox injectManifest, version-synced changelog, user-controlled updates
UI Material Symbols Material Symbols Outlined, Manrope font
Backend FastAPI Python FastAPI, Uvicorn, psycopg2
AI Vision Gemini Gemini 2.5 Flash (primary), 2.0 Flash (fallback)
AI Chat Groq Groq, multi-turn, context-aware, layered safety guardrails
Database Neon Neon serverless PostgreSQL, connection pool, row-level security per user
Auth Supabase Google OAuth + email OTP codes, ES256 JWTs verified server-side via JWKS
Push pywebpush VAPID keys, Web Push API, per-user notification preferences and reminder times
Deploy Vercel Render Vercel (frontend), Render (backend)

Architecture

NutriScan/
├── backend/
│   ├── main.py              FastAPI app: all routes, JWT auth, DB pool, AI calls,
│   │                        reminder scheduler, notification prefs, RLS binding,
│   │                        image upload gate (format sniff, pixel cap, re-encode),
│   │                        model-output schema check, scan burst caps,
│   │                        abuse guards (per-IP flood/probe blocks, delete-spree
│   │                        account freeze), ops alerts to ntfy, optional Sentry
│   ├── tests/               unittest suite for the upload gate and output schema
│   │                        (crafted bytes per rejection path; NUTRI_LIVE=1 adds
│   │                        a live prompt-injection probe)
│   ├── rls_policies.sql     Row-level security policies (per-user data isolation)
│   ├── recycle_bin.sql      BEFORE DELETE triggers: every deleted row kept 30 days,
│   │                        readable only by the DB owner (restore-by-email)
│   └── requirements.txt
│
└── frontend/
    ├── public/
    │   ├── favicon.svg      Adaptive icon (light/dark via prefers-color-scheme)
    │   ├── changelog.v2.json  Versioned release notes shown by the update banner
    │   ├── icon-{192,512}.png
    │   ├── robots.txt · llms.txt · .well-known/security.txt
    │   └── nutriscan-card-v8.png  OG / link-preview image
    ├── src/
    │   ├── lib/
    │   │   ├── api.js       Supabase client, apiFetch (auth-aware), retry, runAnalysis
    │   │   ├── confirm.js   Promise-based confirm() backed by ConfirmDialog
    │   │   ├── push.js      Web-push subscribe/unsubscribe helpers
    │   │   └── nutrition.js Parse/normalize macros, image pipeline (resize, grayscale)
    │   ├── components/
    │   │   ├── ChatAssistant.jsx     AI chat screen: Groq, multi-turn, context-aware
    │   │   ├── AddToLogModal.jsx     Log a food (serving / by-weight / manual modes)
    │   │   ├── EditLogModal.jsx      Edit an existing log entry
    │   │   ├── SaveToFolderModal.jsx Save a scan result to a library folder
    │   │   ├── ConfirmDialog.jsx     In-app confirm/alert modal (replaces window.confirm)
    │   │   ├── ImageCropper.jsx      Canvas crop UI, touch + mouse, corner handles
    │   │   ├── NutrientGrid.jsx      Nutrient table with custom serving calculator
    │   │   ├── DatePicker.jsx        Calendar dropdown with tracked-day dots
    │   │   ├── MacroBar.jsx          Single macro progress bar
    │   │   ├── LoginScreen.jsx       Google OAuth + email OTP code entry
    │   │   └── Icon.jsx              Material Symbols wrapper (aria-hidden) + CSS spinner
    │   ├── tabs/
    │   │   ├── ScanTab.jsx      Upload, crop queue, Gemini analysis, results
    │   │   ├── LibraryTab.jsx   Folders, items, meal templates with multi-select
    │   │   ├── TrackerTab.jsx   Daily log, macro goal bars, date rollover handling
    │   │   ├── TrendsTab.jsx    7-day macro breakdown, raw SVG, no chart library
    │   │   └── SettingsTab.jsx  Notification prefs + times, contact, delete account
    │   ├── App.jsx          Auth gate, tab shell, theme toggle, update banner
    │   ├── main.jsx         Service worker registration + update detection
    │   ├── sw.js            Workbox precache, push handler, navigation fallback
    │   ├── version.js       Build's changelog version (drives the update notes)
    │   └── styles.jsx       CSS custom properties, light + dark palettes
    └── index.html

Database (Neon PostgreSQL, 11 user tables under row-level security + 1 owner-only)

users · api_usage · image_records · folders · folder_items · daily_log
user_goals · meal_templates · meal_template_items · push_subscriptions · notification_prefs
recycle_bin (trigger-fed copy of every deleted row, 30-day retention, no app-role access)

Contributing / security: see CONTRIBUTING.md and SECURITY.md.


Author

Built by Kaushik N · LinkedIn

About

Nutrition label photos become validated macro rows: every upload sniffed, pixel-capped and re-encoded, model output schema-checked, per-user RLS, abuse blocked at a middleware, deletes recoverable 30 days. FastAPI, Neon, Gemini, Sentry.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages