Skip to main content

Overview

FitAiid’s AI Workout Generator creates personalized weekly workout routines based on user fitness profiles, goals, and preferences. The system uses AI to design exercises tailored to each user’s experience level, available equipment, and training objectives.

How It Works

1

User Profile Analysis

The system analyzes the user’s fitness profile including:
  • Fitness level (beginner, intermediate, advanced)
  • Main goal (tonify, gain muscle, lose weight)
  • Training location (home or gym)
  • Available training days per week
  • Session duration preference
2

AI Routine Generation

The backend generates a personalized weekly routine using the user’s profile data and AI algorithms to select appropriate exercises, sets, reps, and rest periods.
3

Workout Tracking

Users complete exercises daily, mark them as done, and the system automatically advances to the next day in the cycle.
4

Progress Recording

All completed workouts are saved to the database with statistics including duration, calories burned, and exercises completed.

Frontend Implementation

Generating a Workout Routine

The frontend calls the workout generation API with the user’s fitness profile:
async function generarRutina() {
  const btnGenerate = document.getElementById('btnGenerate');
  const loadingOverlay = document.getElementById('loadingOverlay');

  btnGenerate.disabled = true;
  loadingOverlay.classList.add('active');

  try {
    const response = await fetch(`${CONFIG.API_URL}/api/generar-rutina`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({
        userId: userId,
        profile: userProfile
      })
    });

    const data = await response.json();

    if (data.success) {
      rutinaActual = data.rutina;
      localStorage.setItem('rutinaActual', JSON.stringify(rutinaActual));
      mostrarRutina();
    }
  } catch (error) {
    console.error('Error generating routine:', error);
  }
}

Completing Exercises

When a user completes all exercises in a day, the system registers the workout:
async function verificarDiaCompletado(diaIndex) {
  const dia = rutinaActual.dias[diaIndex];
  const todosCompletados = dia.ejercicios.every(e => e.completado);

  if (todosCompletados && !dia.registrado) {
    dia.registrado = true;
    
    const workoutData = {
      nombre: dia.nombre || `Día ${diaIndex + 1}`,
      enfoque: dia.enfoque,
      duracionTotal: dia.duracionTotal || 45,
      caloriasEstimadas: dia.caloriasEstimadas || 300,
      ejercicios: dia.ejercicios.map(e => ({
        nombre: e.nombre,
        series: e.series,
        repeticiones: e.repeticiones,
        completado: e.completado
      }))
    };

    // Register workout in backend
    const response = await fetch(`${CONFIG.API_URL}/api/entrenamientos/registrar`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({
        userId: userId,
        workoutData: workoutData
      })
    });

    const data = await response.json();
    
    if (data.success) {
      console.log('Workout saved successfully');
      // Check for achievements
      if (data.data.achievementsUnlocked?.length > 0) {
        mostrarNotificacionLogro(achievement.nombre);
      }
    }
  }
}

Backend Implementation

Workout Registration Controller

The backend controller handles workout completion and updates user statistics:
exports.registrarEntrenamiento = async (req, res) => {
  const { userId, workoutData } = req.body;

  // Security validation
  if (req.user._id.toString() !== userId) {
    throw new AppError('Not authorized', 403);
  }

  const user = await User.findById(userId);
  
  // Create workout progress record
  const workoutProgress = new WorkoutProgress({
    user: userId,
    duration: workoutData.duracionTotal || 45,
    calories: workoutData.caloriasEstimadas || 300,
    createdAt: new Date()
  });
  
  await workoutProgress.save();

  // Calculate streak
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  
  const workoutHistory = user.fitnessStats?.workoutHistory || [];
  const yaEntrenoHoy = workoutHistory.some(w => {
    const workoutDate = new Date(w.date);
    workoutDate.setHours(0, 0, 0, 0);
    return workoutDate.getTime() === today.getTime();
  });

  let newStreak = yaEntrenoHoy 
    ? user.fitnessStats?.currentStreak || 1
    : (user.fitnessStats?.currentStreak || 0) + 1;

  // Update user statistics
  await User.findByIdAndUpdate(userId, {
    $push: {
      'fitnessStats.workoutHistory': nuevoEntrenamiento
    },
    $inc: {
      'fitnessStats.totalWorkouts': 1,
      'fitnessStats.totalExercises': totalExercises,
      'fitnessStats.totalMinutes': workoutData.duracionTotal || 45
    },
    $set: {
      'fitnessStats.currentStreak': newStreak,
      'fitnessStats.maxStreak': Math.max(newStreak, user.fitnessStats?.maxStreak || 0)
    }
  });

  // Check for unlocked achievements
  const achievementsUnlocked = await verificarLogros(userId, totalWorkouts, newStreak);

  // Trigger automatic notifications
  await notificationTriggers.onEntrenamientoCompletado(userId, {
    id: workoutProgress._id,
    nombre: workoutData.nombre,
    duracion: workoutData.duracionTotal,
    calorias: workoutData.caloriasEstimadas
  });

  res.json({
    success: true,
    message: 'Workout registered successfully',
    data: {
      workoutId: workoutProgress._id,
      stats: {
        totalWorkouts: totalWorkouts,
        currentStreak: newStreak,
        maxStreak: newMaxStreak
      },
      achievementsUnlocked: achievementsUnlocked
    }
  });
};

Routine Management

The routine controller handles automatic day progression:
exports.completarDia = async (req, res) => {
  const { userId } = req.params;
  const { duracion, calorias, ejerciciosCompletados } = req.body;
  
  const user = await User.findById(userId);
  const diaActual = user.getDiaActual();
  
  if (diaActual.completado) {
    throw new AppError('This day is already completed', 400);
  }
  
  // Register workout statistics
  if (duracion && calorias) {
    const workoutData = {
      nombre: diaActual.nombre || `Training ${diaActual.nombre}`,
      enfoque: diaActual.enfoque || 'General',
      duracionTotal: duracion,
      caloriasEstimadas: calorias,
      ejerciciosCompletados: ejerciciosCompletados || diaActual.ejercicios?.length || 0,
      ejercicios: diaActual.ejercicios || []
    };
    
    await user.registrarEntrenamiento(workoutData);
  }
  
  // Complete day and advance to next (with automatic restart)
  const resultado = await user.completarDiaYAvanzar();
  
  res.json({
    success: true,
    message: resultado.mensaje,
    data: {
      ...resultado,
      estadisticas: user.obtenerEstadisticas()
    }
  });
};

Key Features

Automatic Cycle

When users complete all 7 days, the routine automatically restarts from day 1, ensuring continuous training.

Streak Tracking

The system tracks consecutive workout days and motivates users to maintain their streak.

Achievement System

Users unlock achievements based on milestones like first workout, 7-day streak, or 50 total workouts.

Real-time Sync

All workout data syncs to the backend immediately, ensuring data consistency across devices.

API Endpoints

Register Workout

POST /api/entrenamientos/registrar
Authorization: Bearer {token}
Content-Type: application/json

{
  "userId": "507f1f77bcf86cd799439011",
  "workoutData": {
    "nombre": "Full Body Workout",
    "enfoque": "Full body",
    "duracionTotal": 45,
    "caloriasEstimadas": 300,
    "ejercicios": [
      {
        "nombre": "Push-ups",
        "series": 3,
        "repeticiones": "12",
        "completado": true
      }
    ]
  }
}
The system automatically prevents duplicate workout registrations for the same day using the registrado flag.

Get Workout History

GET /api/entrenamientos/{userId}/historial?limit=20
Authorization: Bearer {token}
Response:
{
  "success": true,
  "data": {
    "workouts": [
      {
        "date": "2026-03-06T10:30:00.000Z",
        "nombre": "Full Body Workout",
        "enfoque": "Full body",
        "duracionTotal": 45,
        "caloriasEstimadas": 300,
        "ejerciciosCompletados": 8
      }
    ],
    "total": 15
  }
}

User Flow

1

Complete Fitness Profile

Users fill out their fitness questionnaire with goals, experience level, and preferences
2

Generate AI Routine

Click “Generate Routine” to create a personalized 7-day workout plan
3

View Daily Workout

See today’s exercises with detailed instructions, sets, reps, and rest periods
4

Complete Exercises

Mark each exercise as completed. When all exercises are done, the workout is automatically saved
5

Track Progress

View statistics, streak counter, and unlocked achievements in the stats dashboard
The routine automatically cycles back to Day 1 after completing Day 7, ensuring users always have a workout plan.

Security

All workout endpoints validate that the authenticated user can only access their own data:
if (req.user._id.toString() !== userId) {
  throw new AppError('Not authorized to access this data', 403);
}

Build docs developers (and LLMs) love