SmartFoodSave is an AI-assisted platform for reducing food waste in school meal operations. It combines data collection, machine learning prediction, semantic meal normalization, nutrition-aware menu logic, and donation-point discovery into one full-stack system.
This repository contains:
- A FastAPI backend for authentication, data storage, prediction, scheduling, and integrations
- A React web dashboard for school staff
- An Expo React Native mobile app
- A separate React documentation site
YH4F Submission Note:
- Full Technical Report: docs/PROJECT_DOCUMENTATION.md
- Mobile App APK Delivery: Due to repository size constraints, the mobile APK is available via Google Drive: Download APK
Food waste in schools is driven by uncertainty in attendance, variation in menu popularity, and limited decision-support for meal preparation. SmartFoodSave addresses this by collecting structured cafeteria data, predicting expected leftovers, checking nutritional and scheduling issues, and helping schools identify nearby donation points for surplus food.
The current system combines four technical layers:
- Operational data collection from schools
- Machine learning prediction of leftovers
- Semantic and rule-based menu reasoning
- Redistribution support through donation discovery
FoodWasteAI/
|- backend/ FastAPI API + ML logic
|- site/ Main React dashboard
|- myApp/ Expo mobile app (React Native + TypeScript)
|- docs/ Documentation website + technical report
|- serviceAccountKey.json
|- README.md
Dashboard (site) ----->
|
Mobile (myApp) ------> FastAPI backend (backend/app.py) -----> Firebase Auth + Firestore
| |
Docs (docs) ----------> Static/documentation frontend +--> ML prediction engine
+--> SentenceTransformer
+--> OpenAI services
+--> Donation lookup logic
- FastAPI + Uvicorn
- Firebase Admin SDK
- Firestore
- scikit-learn + pandas + numpy
- sentence-transformers
- OpenAI API
- httpx
- React
- Vite
- Tailwind CSS
- Firebase Web SDK
- Expo
- React Native + TypeScript
- Expo Router
The repository currently includes two CSV datasets.
File: backend/engine/data.csv
- Rows:
30 - Columns:
date,day_of_week,menu_item,prepared_portions,served_portions,leftovers,attendance - Mean leftovers:
22.7 - Overall waste rate:
20.826%
Per-menu summary:
| Menu item | Samples | Avg leftovers | Avg waste rate |
|---|---|---|---|
| Pasta | 6 | 27.5 | 22.917% |
| Pizza | 5 | 27.2 | 20.923% |
| Chicken Wrap | 5 | 22.0 | 20.000% |
| Rice Bowl | 5 | 20.8 | 20.800% |
| Salad | 5 | 20.0 | 22.222% |
| Sandwich | 4 | 16.5 | 16.500% |
File: backend/engine/improved_data.csv
- Rows:
730 - Columns:
date,day_of_week,menu_item,attendance,prepared_portions,served,leftovers - Mean attendance:
108.599 - Mean prepared portions:
124.095 - Mean leftovers:
2.736 - Standard deviation of leftovers:
2.377 - Overall waste rate:
2.204%
Per-menu summary:
| Menu item | Samples | Avg leftovers | Std leftovers | Avg waste rate |
|---|---|---|---|---|
| Vegetarian | 149 | 4.799 | 2.787 | 3.754% |
| Fish | 144 | 3.840 | 2.196 | 3.030% |
| Pasta | 152 | 2.125 | 1.653 | 1.751% |
| Pizza | 130 | 1.562 | 1.233 | 1.217% |
| Chicken | 155 | 1.310 | 1.421 | 1.015% |
File: backend/engine/train.py
- Model:
RandomForestRegressor - Trees:
200 - Train/test split:
80/20 - Random state:
42 - Current measured metric:
Mean Absolute Error = 1.2125
Training features:
day_of_weekprepared_portionsattendancehistorical_avg_leftovers- one-hot encoded menu categories
Target variable:
leftovers
File: backend/engine/predict.py
- Model:
sentence-transformers/all-MiniLM-L6-v2 - Purpose: semantic meal/category matching through embeddings and cosine similarity
The backend also uses OpenAI models when configured:
gpt-4o-minifor structured prediction fallback and explanationgpt-4.1for donation-point discoverygpt-4.1-minifor donation-point enrichment
Current measured value:
where
The runtime endpoint applies a multiplicative contextual factor:
and clips the final value to:
Nearby donation points are ranked with the Haversine distance formula:
with
The backend collects real school operational data through Firebase Firestore.
Main collections:
userssettingsdaily_logsschool_schedulesschool_mealsotp
Collected school-level variables include:
- School name
- School type
- Student count
- Portion size
- Gender distribution
- Location
- Daily menu items
- Attendance
- Prepared portions
- Served portions
- Leftovers
These are used during live prediction, although the committed training dataset in the repository is still synthetic.
This should be stated clearly in a university-style submission:
- The current trained regression model is evaluated on synthetic data.
- The nutrition layer is heuristic and intentionally approximate.
- The demographic adjustment factors are rule-based, not learned from field data.
- The current training script reports only MAE.
- The app collects real data, but there is no automated retraining pipeline yet.
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python app.pycd site
npm install
npm run devcd myApp
npm install
npm run startThen open with Expo Go or run:
npm run android
npm run ios
npm run webcd docs
npm install
npm run devCreate backend/.env manually:
PORT=5000
FIREBASE_SERVICE_ACCOUNT_PATH=/absolute/path/to/serviceAccountKey.json
FIREBASE_SERVICE_ACCOUNT={"type":"service_account",...}
FIREBASE_API_KEY=your_firebase_web_api_key
OPENAI_API_KEY=your_openai_key
GOOGLE_MAPS_API_KEY=your_google_maps_key
RESEND_API_KEY=your_resend_key
SMTP_USER=optional_legacy_value
SMTP_PASS=optional_legacy_valueUse myApp/.env.example as reference.
Public endpoints:
GET /healthPOST /api/contactPOST /api/auth/send-otpPOST /api/auth/verify-otp
Authenticated endpoints:
GET /api/settingsPOST /api/settingsGET /api/data/daily-logsPOST /api/data/daily-logsGET /api/schedulePOST /api/scheduleGET /api/meals/dictionaryPOST /api/meals/dictionaryGET /api/meals/tagsPOST /api/meals/tagsPOST /api/meals/normalizePOST /api/meals/combineGET /api/donations/nearbyPOST /api/predict
MIT