Skip to main content

Overview

FitAiid’s nutrition planning system complements the AI workout generator by providing users with meal guidance tailored to their fitness goals. The system considers user profiles including weight goals, activity level, and dietary preferences.

Nutrition Profile

The nutrition planning is based on the user’s fitness profile which includes:

Basic Metrics

  • Current weight
  • Height
  • Age
  • Gender

Fitness Goals

  • Main goal (lose weight, gain muscle, maintain)
  • Activity level
  • Training frequency

Dietary Preferences

  • Medical conditions
  • Food allergies
  • Dietary restrictions

Calculations

  • BMI (Body Mass Index)
  • Recommended calorie intake
  • Macro distribution

BMI Calculation

The system automatically calculates Body Mass Index when users enter their height and weight:
// Virtual property for BMI calculation
userSchema.virtual('bmi').get(function() {
  if (!this.fitnessProfile?.height || !this.fitnessProfile?.weight) {
    return null;
  }
  
  const heightInMeters = this.fitnessProfile.height / 100;
  const bmi = this.fitnessProfile.weight / (heightInMeters * heightInMeters);
  return Math.round(bmi * 10) / 10;
});

// BMI Category
userSchema.virtual('bmiCategory').get(function() {
  const bmi = this.bmi;
  
  if (!bmi) return null;
  if (bmi < 18.5) return 'Underweight';
  if (bmi < 25) return 'Normal weight';
  if (bmi < 30) return 'Overweight';
  return 'Obese';
});

Fitness Profile API

Save Fitness Profile

Users submit their nutritional information through the questionnaire endpoint:
POST /api/questionnaire
Authorization: Bearer {token}
Content-Type: application/json

{
  "userId": "507f1f77bcf86cd799439011",
  "gender": "male",
  "age": 28,
  "height": 175,
  "weight": 75,
  "fitnessLevel": "intermediate",
  "mainGoal": "ganar masa muscular",
  "medicalConditions": [],
  "trainingLocation": "gym",
  "trainingDaysPerWeek": 4,
  "sessionDuration": "60 min"
}
Response:
{
  "success": true,
  "message": "Questionnaire saved successfully",
  "data": {
    "user": {
      "id": "507f1f77bcf86cd799439011",
      "email": "[email protected]",
      "firstName": "John"
    },
    "fitnessProfile": {
      "gender": "male",
      "age": 28,
      "height": 175,
      "weight": 75,
      "fitnessLevel": "intermediate",
      "mainGoal": "ganar masa muscular",
      "trainingLocation": "gym",
      "trainingDaysPerWeek": 4,
      "sessionDuration": "60 min"
    },
    "bmi": 24.5,
    "bmiCategory": "Normal weight"
  }
}

Get Fitness Profile

GET /api/questionnaire/{userId}
Authorization: Bearer {token}

Backend Implementation

Questionnaire Controller

router.post("/", protect, catchAsync(async (req, res) => {
  const { 
    userId, 
    gender, 
    age, 
    height, 
    weight, 
    fitnessLevel, 
    mainGoal, 
    medicalConditions, 
    trainingLocation, 
    trainingDaysPerWeek, 
    sessionDuration 
  } = req.body;

  const finalUserId = userId || req.user._id.toString();

  // Validate ownership
  if (req.user._id.toString() !== finalUserId) {
    throw new AppError("No permission to save this questionnaire", 403);
  }

  const user = await User.findById(finalUserId);
  if (!user) {
    throw new AppError("User not found", 404);
  }

  // Update fitness profile
  user.fitnessProfile = {
    gender: gender || user.fitnessProfile.gender,
    age: age || user.fitnessProfile.age,
    height: height || user.fitnessProfile.height,
    weight: weight || user.fitnessProfile.weight,
    fitnessLevel: fitnessLevel || user.fitnessProfile.fitnessLevel,
    mainGoal: mainGoal || user.fitnessProfile.mainGoal,
    medicalConditions: medicalConditions || user.fitnessProfile.medicalConditions,
    trainingLocation: trainingLocation || user.fitnessProfile.trainingLocation,
    trainingDaysPerWeek: trainingDaysPerWeek || user.fitnessProfile.trainingDaysPerWeek,
    sessionDuration: sessionDuration || user.fitnessProfile.sessionDuration,
    questionnaireCompleted: true,
    questionnaireCompletedAt: new Date()
  };

  await user.save();

  res.status(201).json({
    success: true,
    message: "Questionnaire saved successfully",
    data: {
      user: user.getPublicProfile(),
      fitnessProfile: user.fitnessProfile,
      bmi: user.bmi,
      bmiCategory: user.bmiCategory
    }
  });
}));

Frontend Integration

Loading User Profile

async function cargarPerfil() {
  try {
    const fitnessProfile = localStorage.getItem('fitnessProfile');

    if (fitnessProfile) {
      userProfile = JSON.parse(fitnessProfile);
    }

    // Load from backend if not in localStorage
    if (!userProfile && userId && userId !== 'anonymous') {
      const response = await fetch(`${CONFIG.API_URL}/api/questionnaire/${userId}`, {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });
      const data = await response.json();

      if (data.success && data.data?.fitnessProfile) {
        userProfile = data.data.fitnessProfile;
        localStorage.setItem('fitnessProfile', JSON.stringify(userProfile));
      }
    }

    actualizarUIConPerfil();
  } catch (error) {
    console.error('Error loading profile:', error);
  }
}

Nutritional Goals by Objective

The system provides different nutritional recommendations based on user goals:
Caloric Deficit: 15-20% below maintenance caloriesMacros:
  • Protein: 30-35% (to preserve muscle)
  • Carbs: 30-40%
  • Fats: 25-30%
Recommendations:
  • Focus on high-protein, low-calorie foods
  • Increase vegetable intake
  • Reduce refined sugars and processed foods
  • Stay hydrated (2-3 liters daily)
Caloric Surplus: 10-15% above maintenance caloriesMacros:
  • Protein: 30-35% (1.6-2.2g per kg of body weight)
  • Carbs: 40-50%
  • Fats: 20-25%
Recommendations:
  • Eat protein with every meal
  • Consume complex carbs around workouts
  • Don’t neglect healthy fats
  • Consider 4-6 smaller meals per day
Maintenance Calories: Stay at current caloric needsMacros:
  • Protein: 25-30%
  • Carbs: 40-45%
  • Fats: 25-30%
Recommendations:
  • Balanced meals with variety
  • Time carbs around training sessions
  • Focus on whole, unprocessed foods
  • Consistent meal timing

User Data Structure

The fitness profile is stored in the User model:
fitnessProfile: {
  gender: {
    type: String,
    enum: ['male', 'female', 'other']
  },
  age: Number,
  height: Number, // in cm
  weight: Number, // in kg
  fitnessLevel: {
    type: String,
    enum: ['principiante', 'intermedio', 'avanzado'],
    default: 'principiante'
  },
  mainGoal: {
    type: String,
    enum: ['bajar de peso', 'ganar masa muscular', 'tonificar', 'vida saludable']
  },
  medicalConditions: [String],
  trainingLocation: {
    type: String,
    enum: ['casa', 'gym']
  },
  trainingDaysPerWeek: {
    type: Number,
    min: 1,
    max: 7
  },
  sessionDuration: String,
  questionnaireCompleted: {
    type: Boolean,
    default: false
  },
  questionnaireCompletedAt: Date
}

User Flow

1

Complete Questionnaire

Users fill out their personal information, including height, weight, age, and fitness goals
2

BMI Calculation

System automatically calculates BMI and determines weight category
3

Goal Selection

Users choose their primary objective: lose weight, gain muscle, or maintain/tone
4

Profile Saved

All data is saved to MongoDB and synced across devices
5

Workout Generation

The fitness profile is used to generate personalized workout routines
The fitness profile is used not only for nutrition recommendations but also to personalize workout routines, exercise difficulty, and rest periods.

Security & Validation

Ownership ValidationAll endpoints validate that users can only access their own nutrition data:
if (req.user._id.toString() !== userId) {
  throw new AppError('No permission to access this data', 403);
}
MongoDB ID ValidationThe system validates user IDs before database queries:
if (!mongoose.Types.ObjectId.isValid(userId)) {
  throw new AppError('Invalid user ID', 400);
}

Integration with Workouts

The nutrition profile directly influences workout generation:
  • Beginners get easier exercises with more rest
  • Weight loss goals include more cardio and HIIT
  • Muscle gain focuses on strength training and progressive overload
  • Home training uses bodyweight and minimal equipment
  • Gym training includes machine and free weight exercises

Build docs developers (and LLMs) love