Last Updated: May 2026
Project Status: Integrated and Unified
Current Version: 1.0.0
- Project Overview
- Architecture
- Technology Stack
- Directory Structure
- Backend Components
- Frontend Components
- API Documentation
- Setup & Installation
- Running the Project
- System Features
- Data Flow & Workflows
- Database Schema
- Development Guide
- Troubleshooting
- Performance Considerations
NutriPal is a comprehensive AI-powered fitness and nutrition management platform that integrates multiple services into a unified ecosystem:
- Nutrition Tracking: Capture food via camera, automatically extract nutritional data using AI vision
- Smart Meal Planning: Generate personalized 7-day meal plans based on user goals and dietary preferences
- Workout Management: Create, track, and manage exercise routines with AI-powered recommendations
- Real-time Pose Correction: Computer vision-based form feedback during exercises
- Analytics & Progress: Visualize fitness and nutrition metrics over time
✅ Unified authentication system across all services
✅ Seamless integration of AI services (vision, planning, pose detection)
✅ Real-time communication for live feedback
✅ Cross-platform support (Android, iOS, Web, Windows)
✅ Microservices architecture for scalability and reliability
NutriPal follows a Client-Server Architecture with Microservices for AI workloads:
┌─────────────────────────────────────────────────────────────────┐
│ Flutter Mobile/Web App │
│ (Dart - Provider Pattern) │
└─────────────────┬───────────────────────────────────────────────┘
│
│ REST API + WebSocket
▼
┌─────────────────────────────────────────────────────────────────┐
│ Node.js Express Core API (:4000) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Auth │ Nutrition │ Workouts │ Profile │ Health Checks │ │
│ └────────┬──────────────────────────────────────────────┬─┘ │
│ │ │ │
│ ┌────────▼────────────────────────────────────────┬─────▼──┐ │
│ │ MongoDB Atlas / Local Instance │ Logger │ │
│ └──────────────────────────────────────────────────────────┘ │
└────┬──────────────────────────────────────────────────────────┬─┘
│ HTTP HTTP │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Python AI Planner │◄──────────────────► │ Python Pose Corrector│
│ (:8000, FastAPI) │ Service Calls │ (:8001, FastAPI) │
│ │ │ │
│ • Random Forest │ │ • MediaPipe │
│ • Predictions │ │ • Joint Tracking │
│ • Personalization │ │ • Angle Calculation │
└──────────────────────┘ └──────────────────────┘
▲ ▲
│ │
venv-ai/ venv-pose/
- Separation of Concerns: Each microservice handles one primary responsibility
- Unified Authentication: All services validate JWT tokens from Node.js
- Scalability: Python services can be deployed independently
- Fault Tolerance: Fallback systems for external APIs (Gemini → OpenRouter)
- Real-time Communication: WebSocket support for live pose feedback
| Technology | Purpose | Version |
|---|---|---|
| Flutter (Dart) | Cross-platform UI framework | 3.9.2+ |
| Provider | State management and dependency injection | 6.1.1 |
| Dio | HTTP client for API communication | 5.8.0 |
| web_socket_channel | Real-time WebSocket communication | 3.0.3 |
| fl_chart | Data visualization (charts & graphs) | 0.68.0 |
| image_picker | Camera/gallery integration | 1.1.2 |
| camera | Direct camera control | 0.12.0 |
| google_sign_in | Social authentication | 6.2.2 |
| permission_handler | Runtime permissions management | 12.0.1 |
| Technology | Purpose | Version |
|---|---|---|
| Node.js | JavaScript runtime | 18+ LTS |
| Express.js | Web framework | 4.19.2 |
| MongoDB | Document database (Atlas or local) | 6.0+ |
| Mongoose | ODM for MongoDB | 8.8.3 |
| jsonwebtoken (JWT) | Token-based authentication | 9.0.2 |
| bcryptjs | Password hashing | 2.4.3 |
| Axios | HTTP client (inter-service communication) | 1.16.0 |
| Nodemailer | Email service for verification | 6.9.7 |
| CORS | Cross-origin request handling | 2.8.5 |
| Technology | Purpose | Environment |
|---|---|---|
| FastAPI | High-performance async API framework | Both services |
| Pydantic | Data validation & serialization | Both services |
| Scikit-Learn | Machine learning library | venv-ai/ |
| MediaPipe | Computer vision solutions | venv-pose/ |
| NumPy/Pandas | Data processing | Both services |
| OpenCV | Image processing | venv-pose/ |
| Service | Purpose | Fallback |
|---|---|---|
| Google Gemini 2.5 Flash | Food image analysis | Gemini Flash-Lite |
| Google Gemini 2.5 Flash-Lite | Lightweight food analysis | OpenRouter Gemma 3 |
| OpenRouter Gemma 3 Vision | Fallback vision model | None |
integration/
│
├── backend/ # Node.js core API
│ ├── src/
│ │ ├── config/ # Configuration files database
│ │ ├── controllers/ # Request handlers
│ │ │ ├── exerciseController.js # Exercise CRUD operations
│ │ │ ├── workoutController.js # Workout logging & tracking
│ │ │ └── workoutPlanController.js # AI-generated plan management
│ │ │
│ │ ├── middleware/ # Express middleware
│ │ │ └── requireUnifiedAuth.js # JWT token validation
│ │ │
│ │ ├── models/ # Mongoose schemas
│ │ │ ├── User.js # User identity & auth
│ │ │ ├── UserProfile.js # Physical metrics & goals
│ │ │ ├── Food.js # Food database (nutrition data)
│ │ │ ├── FoodLog.js # User food consumption records
│ │ │ ├── Meal.js # Single meal data
│ │ │ ├── MealPlan.js # 7-day meal plan templates
│ │ │ └── Workout.js # Exercise sessions
│ │ │
│ │ ├── routes/ # Express route handlers
│ │ │ ├── auth.routes.js # /api/v1/auth/*
│ │ │ ├── foods.routes.js # /api/v1/foods/*
│ │ │ ├── foodLog.routes.js # /api/v1/food-log/*
│ │ │ ├── meals.routes.js # /api/v1/meals/*
│ │ │ ├── plans.routes.js # /api/v1/plans/*
│ │ │ ├── profile.routes.js # /api/v1/profile/*
│ │ │ ├── workout.routes.js # /api/v1/workouts/*
│ │ │ ├── workoutPlans.routes.js # /api/v1/workout-plans/*
│ │ │ ├── exercises.routes.js # /api/v1/exercises/*
│ │ │ └── pose.routes.js # /api/v1/pose/* & WebSocket
│ │ │
│ │ ├── services/ # Business logic & external APIs
│ │ │ ├── emailService.js # Email sending & verification
│ │ │ ├── visionAnalysisService.js # Cascading AI fallback chain
│ │ │ ├── mealPlannerService.js # Meal plan generation algorithm
│ │ │ └── poseService.js # WebSocket communication
│ │ │
│ │ ├── utils/ # Utility functions
│ │ │ ├── nutritionCalculator.js # TDEE & macro calculations
│ │ │ └── constants.js # App-wide constants
│ │ │
│ │ ├── scripts/ # Maintenance & setup scripts
│ │ │ ├── seedFoods.js # Populate food database
│ │ │ ├── migrateData.js # Data migration & merging
│ │ │ └── smokeTest.js # Quick health verification
│ │ │
│ │ └── server.js # Express app & MongoDB connection
│ │
│ ├── ai-planner/ # Python microservice (:8000)
│ │ ├── api_server.py # FastAPI entry point
│ │ ├── requirements.txt # Python dependencies
│ │ └── models/ # Trained ML models
│ │
│ ├── pose-corrector/ # Python microservice (:8001)
│ │ ├── pose_corrector_api.py # FastAPI WebSocket server
│ │ ├── requirements.txt # Python dependencies
│ │ └── models/ # MediaPipe & pose data
│ │
│ ├── venv-ai/ # Python virtual environment (AI Planner)
│ ├── venv-pose/ # Python virtual environment (Pose Corrector)
│ ├── package.json # Node.js dependencies & scripts
│ ├── .env.example # Environment template
│ ├── .env # Local environment variables (git ignored)
│ └── README.md # Backend-specific setup guide
│
├── frontend/ # Flutter mobile & web app
│ ├── lib/
│ │ ├── main.dart # App entry point
│ │ │
│ │ ├── config/ # Application configuration
│ │ │ └── app_config.dart # API URLs, constants
│ │ │
│ │ ├── controllers/ # Business logic & API calls
│ │ │ ├── auth_controller.dart # Authentication flow
│ │ │ ├── food_controller.dart # Food logging
│ │ │ ├── meal_controller.dart # Meal plan management
│ │ │ ├── workout_controller.dart # Workout tracking
│ │ │ └── pose_controller.dart # Pose analysis WebSocket
│ │ │
│ │ ├── models/ # Data models & serialization
│ │ │ ├── User.dart # User data structure
│ │ │ ├── Food.dart # Food item structure
│ │ │ ├── Meal.dart # Meal data structure
│ │ │ ├── MealPlan.dart # Complete meal plan
│ │ │ ├── Workout.dart # Workout session data
│ │ │ └── Exercise.dart # Individual exercise
│ │ │
│ │ ├── pages/ # Full-screen UI views
│ │ │ ├── auth/ # Authentication pages
│ │ │ │ ├── login_page.dart # User login screen
│ │ │ │ ├── register_page.dart # User registration
│ │ │ │ └── verify_email_page.dart # Email verification
│ │ │ │
│ │ │ ├── onboarding/ # Initial user setup
│ │ │ │ ├── get_started_page.dart # Welcome screen
│ │ │ │ ├── profile_setup_page.dart # Physical metrics collection
│ │ │ │ └── goal_selection_page.dart # User goals & preferences
│ │ │ │
│ │ │ ├── home_page.dart # Main navigation scaffold
│ │ │ ├── dashboard_page.dart # Home feed with summaries
│ │ │ ├── analytics_page.dart # Historical charts & trends
│ │ │ │
│ │ │ ├── nutrition/ # Food & meal planning
│ │ │ │ ├── food_scanner_page.dart # Camera-based food capture
│ │ │ │ ├── food_log_page.dart # Food history & logs
│ │ │ │ ├── meal_plan_page.dart # Generated meal plans
│ │ │ │ └── meal_detail_page.dart # Individual meal view
│ │ │ │
│ │ │ └── workout/ # Exercise tracking
│ │ │ ├── workout_page.dart # Active workout screen
│ │ │ ├── pose_feedback_page.dart # Real-time pose correction
│ │ │ └── workout_history_page.dart # Past workouts
│ │ │
│ │ ├── services/ # HTTP & business logic
│ │ │ ├── api_client.dart # Dio HTTP wrapper
│ │ │ ├── auth_service.dart # Auth endpoints
│ │ │ ├── food_service.dart # Food API calls
│ │ │ ├── meal_service.dart # Meal plan API calls
│ │ │ ├── workout_service.dart # Workout API calls
│ │ │ └── pose_service.dart # WebSocket to pose server
│ │ │
│ │ ├── providers/ # State management (Provider pattern)
│ │ │ ├── auth_provider.dart # Auth state
│ │ │ ├── food_provider.dart # Food & FoodLog state
│ │ │ ├── meal_provider.dart # Meal plan state
│ │ │ ├── workout_provider.dart # Workout state
│ │ │ └── ui_provider.dart # Navigation & UI state
│ │ │
│ │ ├── widgets/ # Reusable UI components
│ │ │ ├── common_widgets.dart # Generic buttons, cards
│ │ │ ├── nutrition_widgets.dart # Nutrition-specific widgets
│ │ │ ├── workout_widgets.dart # Workout-specific widgets
│ │ │ ├── charts/ # Chart components
│ │ │ └── dialogs/ # Modal dialogs
│ │ │
│ │ ├── theme/ # UI styling & theming
│ │ │ ├── app_theme.dart # Color schemes & typography
│ │ │ └── constants.dart # UI constants
│ │ │
│ │ └── utils/ # Helper functions
│ │ ├── formatters.dart # Date/number formatting
│ │ └── validators.dart # Input validation
│ │
│ ├── test/ # Unit & integration tests
│ ├── android/ # Android-specific code
│ ├── ios/ # iOS-specific code
│ ├── web/ # Web-specific code
│ ├── windows/ # Windows-specific code
│ ├── pubspec.yaml # Flutter dependencies
│ ├── analysis_options.yaml # Dart linting rules
│ └── README.md # Frontend-specific guide
│
├── COMPREHENSIVE_GUIDE.md # Architecture & technical guide
├── DOCUMENTATION.md # Feature overview
├── INTEGRATION_STATUS.md # Integration progress tracking
├── FULL_DOCUMENTATION.md # This file - Complete documentation
├── START_ALL_SERVICES.ps1 # PowerShell script to start all services
└── README.md # Quick start guide
Files: auth.routes.js, requireUnifiedAuth.js
All services use JWT tokens issued by the Node.js backend:
// Token payload structure
{
sub: userId, // Alternative: id or userId
email: user@example.com,
iat: timestamp,
exp: timestamp
}Supported endpoints:
POST /api/v1/auth/register- Create new userPOST /api/v1/auth/login- Authenticate and get tokenGET /api/v1/auth/verify-email?token=...- Email verificationGET /api/v1/auth/me- Get current user profilePOST /api/v1/auth/refresh- Refresh JWT token (if implemented)
Core Files:
- Models:
Food.js(nutrition database),FoodLog.js(user logs),Meal.js,MealPlan.js - Routes:
foods.routes.js,foodLog.routes.js,meals.routes.js,plans.routes.js - Services:
visionAnalysisService.js(AI image analysis),mealPlannerService.js(plan generation)
-
Food Scanning (Vision Analysis)
- User uploads food photo
- System calls Gemini 2.5 Flash → Gemini Flash-Lite → OpenRouter fallback
- Returns: Calories, Macros (protein/carbs/fats), Confidence score
- User reviews and saves to FoodLog
-
Meal Plan Generation
- Based on user: BMR, activity level, goal (fat loss/gain/maintenance)
- Algorithm filters foods matching macro targets
- Applies soft constraints for variety (recently used foods penalized but not excluded)
- Returns 7-day plan with breakfast/lunch/dinner/snacks
-
Food Database
- Pre-seeded with 20+ foods and their nutritional data per 100g
- Searchable by category and dietary tags
Core Files:
- Models:
Workout.js(exercise sessions) - Controllers:
workoutController.js,workoutPlanController.js,exerciseController.js - Routes:
workout.routes.js,workoutPlans.routes.js,exercises.routes.js
-
Workout Logging
- Log completed exercises with sets, reps, weight
- Stores exercise form feedback and timestamps
-
Workout Plans
- AI-generated personalized plans from Python microservice
- Based on user goals and experience level
-
Exercise Database
- Pre-defined exercises with body part targets
- Linked to workout sessions
Files: pose.routes.js, poseService.js
- Real-time WebSocket communication with Python pose service
- Sends video frames and receives live feedback
- Tracks joint angles and exercise form quality
Files: profile.routes.js, UserProfile.js
Stores user physical data:
- Height, Weight, Age, Gender
- Body Fat %, Goal (fat loss/muscle gain/maintenance)
- Dietary preferences (vegetarian/vegan/high-protein, etc.)
- Activity level
Home (IndexedStack)
├── Dashboard (home)
│ ├── Nutrition Summary
│ └── Workout Summary
├── Nutrition Tab
│ ├── Food Scanner
│ ├── Food Log History
│ └── Meal Plans
├── Workouts Tab
│ ├── Active Workout
│ ├── Pose Correction
│ └── Workout History
└── Analytics Tab
├── Nutrition Charts
└── Workout Charts
Providers manage app state:
AuthProvider- User authentication & sessionFoodProvider- Food data & food logsMealProvider- Meal plansWorkoutProvider- Workouts & exercisesUIProvider- Navigation & UI state
Each provider handles:
- Data fetching from API
- Local state caching
- Error handling
- Notify listeners on state changes
-
Dashboard (
dashboard_page.dart)- Nutrition progress rings (calories, macros)
- Daily workout summary
- Quick action buttons
-
Analytics (
analytics_page.dart)- Tabbed interface with fl_chart
- Historical nutrition trends
- Exercise volume charts
-
Food Scanner (
food_scanner_page.dart)- Camera integration
- AI-powered nutrition extraction
- User verification & editing
-
Meal Plans (
meal_plan_page.dart)- Display generated 7-day plans
- Swap meals between days
- Save favorite combinations
-
Workout (
workout_page.dart)- Display current exercise
- Log sets/reps/weight
- Real-time pose feedback overlay
Production: https://api.nutripal.app/api/v1
Development: http://localhost:4000/api/v1
All protected endpoints require:
Header: Authorization: Bearer <JWT_TOKEN>
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| POST | /register |
❌ | {email, password, name} |
{token, user} |
| POST | /login |
❌ | {email, password} |
{token, user} |
| GET | /me |
✅ | - | {user profile} |
| GET | /verify-email?token=... |
❌ | Query token | {success, message} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| GET | / |
✅ | - | {profile object} |
| PUT | / |
✅ | {height, weight, goal, ...} |
{updated profile} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| GET | / |
✅ | Query: ?category=...&tags=... |
{foods: [...]} |
| POST | / |
✅ | {name, calories, ...} |
{new food} |
| GET | /:id |
✅ | - | {food object} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| POST | /analyze |
✅ | {image: base64} |
{calories, macros, confidence} |
| POST | / |
✅ | {foodId, servingSize, mealType} |
{new log entry} |
| GET | / |
✅ | Query: ?date=... |
{logs: [...]} |
| DELETE | /:logId |
✅ | - | {success} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| GET | / |
✅ | - | {meals: [...]} |
| POST | / |
✅ | {mealType, foods: [...]} |
{new meal} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| POST | /generate |
✅ | {days: 7, goal, preferences} |
{generated plan} |
| GET | / |
✅ | - | {plans: [...]} |
| GET | /:planId |
✅ | - | {plan details} |
| PUT | /:planId |
✅ | {updates} |
{updated plan} |
| DELETE | /:planId |
✅ | - | {success} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| POST | / |
✅ | {exercises: [...]} |
{new workout} |
| GET | / |
✅ | Query: ?date=...&limit=10 |
{workouts: [...]} |
| GET | /:workoutId |
✅ | - | {workout details} |
| PUT | /:workoutId |
✅ | {updates} |
{updated workout} |
| DELETE | /:workoutId |
✅ | - | {success} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| POST | /generate |
✅ | {goal, experience, preferences} |
{generated plan} |
| GET | / |
✅ | - | {plans: [...]} |
| Method | Endpoint | Auth | Request | Response |
|---|---|---|---|---|
| GET | / |
✅ | Query: ?bodyPart=... |
{exercises: [...]} |
| Method | Endpoint | Type | Purpose |
|---|---|---|---|
| WS | /ws |
WebSocket | Upgrade connection for real-time pose feedback |
WebSocket Protocol:
// Client sends frame:
{"type": "frame", "image": "base64..."}
// Server responds:
{"type": "feedback", "angle": 90, "form": "Good", "message": "Keep steady"}- Node.js 18+ LTS
- MongoDB (Atlas cloud or local instance)
- Python 3.9+
- Flutter 3.9.2+
- Git
-
Navigate to backend:
cd integration/backend -
Install Node.js dependencies:
npm install
-
Create
.envfile:# Database MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/nutripal # Server NODE_ENV=development PORT=4000 CORS_ORIGIN=http://localhost:3000 # JWT JWT_SECRET=your_super_secret_key_change_in_production JWT_EXPIRY=7d # AI Services GOOGLE_API_KEY=your_gemini_api_key OPENROUTER_API_KEY=your_openrouter_key # Email SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your_email@gmail.com SMTP_PASSWORD=your_app_password # AI Microservices AI_PLANNER_URL=http://localhost:8000 POSE_CORRECTOR_URL=http://localhost:8001 -
Create Python virtual environments:
# AI Planner python -m venv venv-ai # Pose Corrector python -m venv venv-pose
-
Install Python dependencies:
# Activate and install for AI Planner .\venv-ai\Scripts\activate # Windows # or: source venv-ai/bin/activate # Unix cd ai-planner pip install -r requirements.txt cd .. # Activate and install for Pose Corrector .\venv-pose\Scripts\activate # Windows # or: source venv-pose/bin/activate # Unix cd pose-corrector pip install -r requirements.txt cd ..
-
Seed the food database:
npm run seed:foods
-
Navigate to frontend:
cd integration/frontend -
Get Flutter dependencies:
flutter pub get
-
Update API configuration (
lib/config/app_config.dart):static const String API_BASE_URL = 'http://localhost:4000/api/v1'; static const String WEBSOCKET_URL = 'ws://localhost:8001';
Use the provided PowerShell script:
cd integration
.\START_ALL_SERVICES.ps1This starts:
- ✅ Node.js backend (:4000)
- ✅ Python AI Planner (:8000)
- ✅ Python Pose Corrector (:8001)
- ✅ Flutter frontend
Terminal 1 - Node.js Backend:
cd integration/backend
npm run dev
# Runs on http://localhost:4000Terminal 2 - AI Planner:
cd integration/backend/ai-planner
.\..\..\venv-ai\Scripts\activate # Windows
python api_server.py
# Runs on http://localhost:8000Terminal 3 - Pose Corrector:
cd integration/backend/pose-corrector
.\..\..\venv-pose\Scripts\activate # Windows
python pose_corrector_api.py
# Runs on http://localhost:8001Terminal 4 - Flutter App:
cd integration/frontend
# Run on Android emulator
flutter run -d emulator-5554
# Run on iOS simulator
flutter run -d iPhone
# Run on Web
flutter run -d chromeVerify all services are running:
# Backend health
curl http://localhost:4000/health
# Response:
# {
# "status": "OK",
# "timestamp": "2024-05-01T10:00:00Z",
# "services": {
# "database": "connected",
# "aiPlanner": "available",
# "poseCorrector": "available"
# }
# }Flow:
- User opens Food Scanner page
- Captures photo via camera
- Image sent to Node backend
- Backend tries Gemini 2.5 Flash:
- Success → Return nutrition data
- Rate limited → Try Gemini Flash-Lite
- Still failed → Try OpenRouter Gemma 3
- Frontend displays: Calories, Macros, Confidence
- User confirms or manually adjusts
- Data saved to FoodLog
Benefits:
- ✅ Automatic calorie tracking
- ✅ Fallback system for reliability
- ✅ User verification before saving
Algorithm:
- Get user profile (goals, constraints, preferences)
- Calculate TDEE using Mifflin-St Jeor equation:
Men: 10W + 6.25H - 5A + 5 Women: 10W + 6.25H - 5A - 161 Then multiply by activity level (1.2-1.9) - Calculate macro targets based on goal:
- Fat Loss: 35% protein, 40% carbs, 25% fats
- Muscle Gain: 30% protein, 50% carbs, 20% fats
- Maintenance: 30% protein, 45% carbs, 25% fats
- For each meal slot (breakfast/lunch/dinner/snacks):
- Filter foods matching constraints (vegetarian, etc.)
- Score foods by macro fit
- Penalize recently-used foods (soft constraint)
- Pick top food for meal
- Return 7-day plan
Example Output:
{
"day": 1,
"meals": {
"breakfast": {
"name": "Oatmeal with Berries",
"calories": 350,
"macros": {"protein": 10, "carbs": 60, "fats": 7}
},
"lunch": {...},
"dinner": {...},
"snack": {...}
}
}Flow:
- User starts workout (e.g., Squats)
- Phone camera feed captured
- WebSocket connection opened to pose service
- Frames sent to Python MediaPipe service
- Service tracks:
- Joint positions (knees, hips, shoulders)
- Calculates angles
- Compares against thresholds for exercise
- Sends real-time feedback: "Go deeper!", "Form good!", "Adjust knees"
- UI displays feedback overlay on video
Exercises Supported:
- Squats (knee angle, hip depth)
- Push-ups (shoulder alignment, elbow angle)
- Planks (body alignment, core engagement)
- And more...
Dashboard shows:
- Daily calorie intake vs. target
- Macro breakdown
- Workout volume (total sets × reps × weight)
- Exercise frequency
Charts include:
- Weekly calorie trends
- Monthly workout volume
- Body weight progression
User
↓
[Register Page] inputs email/password
↓
POST /api/v1/auth/register
↓
[Node Backend] hashes password, creates User
↓
Sends verification email
↓
User clicks link → GET /api/v1/auth/verify-email?token=...
↓
[Node Backend] marks email verified
↓
[Get Started Page] collects height/weight/age/gender
↓
POST /api/v1/profile
↓
[Goal Selection] user picks fat loss/gain/maintenance + preferences
↓
POST /api/v1/profile (update goals)
↓
[Dashboard] user ready to start
User captures food photo
↓
POST /api/v1/food-log/analyze (image as base64)
↓
[Node Backend]
├→ Try: Gemini 2.5 Flash
├→ Try: Gemini 2.5 Flash-Lite
└→ Try: OpenRouter Gemma 3
↓
[Response] {calories: 450, protein: 15, carbs: 60, fats: 12, confidence: 0.92}
↓
[Food Scanner Page] displays analysis
↓
User confirms or edits
↓
POST /api/v1/food-log (save to FoodLog collection)
↓
[Dashboard] reflects in daily totals
User clicks "Generate Plan"
↓
POST /api/v1/plans/generate {goal: "fat_loss", preferences: ["vegetarian"]}
↓
[Node Backend]
├→ Fetch user profile
├→ Calculate TDEE & macro targets
├→ Score foods by fit
├→ Generate 7-day plan
└→ Save to MealPlan collection
↓
[Response] {day1: {...}, day2: {...}, ...}
↓
[Meal Plan Page] displays plan
↓
User can swap meals or save for later
User selects exercise (e.g., Squats)
↓
[Workout Page] loads exercise details
↓
User taps "Start Pose Correction"
↓
[Pose Feedback Page]
├→ Requests camera permission
├→ Opens camera stream
└→ WebSocket connect to ws://localhost:8001
↓
[MediaPipe Processing Loop]
├→ Capture frame (30fps)
├→ Send to Python service
├→ Detect joints & calculate angles
└→ Send feedback: "Perfect!", "Go deeper!", etc.
↓
[UI] displays real-time feedback overlay
↓
User completes set
↓
POST /api/v1/workouts {exercise: "squats", sets: 3, reps: 10, weight: 185}
↓
[Dashboard] updates workout summary
{
_id: ObjectId,
email: String (unique, lowercase),
password: String (hashed with bcrypt),
name: String,
emailVerified: Boolean,
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
userId: ObjectId (ref: User),
height: Number (cm),
weight: Number (kg),
age: Number,
gender: String (male/female/other),
bodyFat: Number (optional, %),
goal: String (fat_loss/muscle_gain/maintenance),
activityLevel: Number (1.2-1.9),
dietaryPreferences: [String] (vegetarian, vegan, etc.),
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
name: String,
caloriesPer100g: Number,
proteinPer100g: Number,
carbsPer100g: Number,
fatsPer100g: Number,
category: String (fruit, vegetable, protein, etc.),
tags: [String] (vegetarian, vegan, high-protein, etc.),
createdAt: Date
}{
_id: ObjectId,
userId: ObjectId (ref: User),
foodId: ObjectId (ref: Food),
servingSize: Number (grams),
mealType: String (breakfast, lunch, dinner, snack),
date: Date,
confidence: Number (0-1, from AI analysis),
aiAnalyzed: Boolean,
createdAt: Date
}{
_id: ObjectId,
userId: ObjectId (ref: User),
goal: String,
constraints: [String],
days: [
{
dayNumber: Number,
meals: {
breakfast: { foodId, servingSize, calories, macros },
lunch: {...},
dinner: {...},
snack: {...}
},
totalCalories: Number,
totalMacros: { protein, carbs, fats }
}
],
createdAt: Date
}{
_id: ObjectId,
userId: ObjectId (ref: User),
date: Date,
exercises: [
{
exerciseId: ObjectId (ref: Exercise),
sets: Number,
reps: Number,
weight: Number,
duration: Number (seconds),
notes: String,
formQuality: Number (0-100, from pose correction)
}
],
totalDuration: Number (minutes),
createdAt: Date
}-
Create Controller (
src/controllers/newFeature.js):exports.getFeature = async (req, res) => { try { // Logic here res.json({ success: true, data: result }); } catch (error) { res.status(500).json({ error: error.message }); } };
-
Create Route (
src/routes/feature.routes.js):const router = require('express').Router(); const { getFeature } = require('../controllers/newFeature'); const { requireUnifiedAuth } = require('../middleware/requireUnifiedAuth'); router.get('/', requireUnifiedAuth, getFeature); module.exports = router;
-
Mount Route (
src/server.js):app.use('/api/v1/features', require('./routes/feature.routes'));
-
Create Page File (
lib/pages/feature_page.dart):class FeaturePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Feature')), body: Consumer<FeatureProvider>( builder: (context, featureProvider, _) { return ListView(...); }, ), ); } }
-
Create Provider (
lib/providers/feature_provider.dart):class FeatureProvider with ChangeNotifier { Future<void> fetchFeature() async { // Call API service notifyListeners(); } }
-
Add to Navigation (
lib/pages/home_page.dart):pages: [ DashboardPage(), FeaturePage(), // New page AnalyticsPage(), ]
Backend Smoke Test:
npm run test:smokeRun specific test:
node src/scripts/smokeTest.jsSolution:
rm -rf node_modules package-lock.json
npm installSolution:
- Check MongoDB connection string in
.env - Verify MongoDB is running (local) or accessible (Atlas)
- Check firewall/network settings
- Verify IP whitelist in MongoDB Atlas
Solution:
# Activate correct virtual environment
.\venv-ai\Scripts\activate # Windows
source venv-ai/bin/activate # Unix
# Check Python version
python --version # Should be 3.9+
# Reinstall dependencies
pip install -r requirements.txt --force-reinstallSolution:
- Verify backend is running:
curl http://localhost:4000/health - Check API URL in
lib/config/app_config.dart - If on real device, use computer's IP instead of localhost
- Verify firewall isn't blocking port 4000
Solution:
- Verify token hasn't expired (default 7 days)
- Check JWT_SECRET matches between services
- Ensure requireUnifiedAuth middleware is applied to protected routes
Solution:
- Verify GOOGLE_API_KEY and OPENROUTER_API_KEY in
.env - Check API keys have correct permissions
- Verify image is valid (not corrupted, proper format)
- Check API rate limits haven't been exceeded
Solution:
- Verify pose corrector running on port 8001
- Check WebSocket URL in Flutter:
ws://localhost:8001 - If on real device, use computer's IP:
ws://192.168.x.x:8001 - Verify firewall allows WebSocket connections
Backend:
DEBUG=* npm run devFlutter:
flutter run --verbose- Backend: Console output (or implement file logging)
- Flutter: DevTools (in VS Code or Android Studio)
- Python: Standard output
-
Database Indexing
// In models, add indexes for frequently queried fields userSchema.index({ email: 1 }); foodLogSchema.index({ userId: 1, date: 1 });
-
API Response Caching
- Cache food database in frontend
- Implement Redis for backend caching
- Use ETags for conditional requests
-
Image Optimization
- Compress images before sending to AI services
- Resize to appropriate resolution
- Consider WebP format
-
WebSocket Optimization
- Adjust frame capture rate (30fps vs. 60fps)
- Implement message batching
- Graceful disconnection handling
-
Frontend Performance
- Use
ListView.builderfor large lists - Implement pagination for food/workout history
- Lazy load images
- Use
For Production:
- Deploy backend to cloud (AWS, GCP, Azure)
- Use managed MongoDB (Atlas)
- Implement CDN for static assets
- Use Redis for caching
- Deploy Python services independently
- Implement load balancing
- Set up monitoring & logging (Sentry, DataDog)
-
Mobile App Deployment
- Build and release to Google Play & App Store
- Implement in-app purchases for premium features
-
Advanced Analytics
- Machine learning for weight prediction
- Recommendation engine for exercises
- Nutritionist AI assistant
-
Social Features
- Share meal plans and workouts
- Community challenges
- Leaderboards
-
Integration with Wearables
- Apple Watch integration
- Fitbit/Garmin data sync
- Real-time heart rate feedback during workouts
-
Offline Support
- Local caching with Hive
- Sync when connection restored
Documentation:
- COMPREHENSIVE_GUIDE.md - Detailed architecture
- DOCUMENTATION.md - Feature overview
- Backend README - Backend setup
- Frontend README - Frontend setup
External Resources:
Contact & Issues:
- Report bugs in GitHub Issues
- Check INTEGRATION_STATUS.md for current status
- Review phase completion tracking
Last Updated: May 4, 2026
Maintained By: NutriPal Development Team
Version: 1.0.0 (Fully Integrated)
If you use this project, please provide attribution by linking back to this repository.
Author: Atul Sharma
If this project helped you, please leave a ⭐ on GitHub.