{"id":18878315,"url":"https://github.com/captaincluster/exercise-tracker","last_synced_at":"2025-04-14T18:32:12.478Z","repository":{"id":239058975,"uuid":"797336327","full_name":"CaptainCluster/Exercise-Tracker","owner":"CaptainCluster","description":"The fourth project for the \"Back End Development and APIs\" course provided by FreeCodeCamp. ","archived":true,"fork":false,"pushed_at":"2024-05-09T18:02:13.000Z","size":13,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-20T12:47:03.774Z","etag":null,"topics":["backend","expressjs","freecodecamp","freecodecamp-project","mongodb","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CaptainCluster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-07T16:31:17.000Z","updated_at":"2024-09-26T07:27:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"3c42efd5-52e8-47a5-ac8d-63c6adfa392c","html_url":"https://github.com/CaptainCluster/Exercise-Tracker","commit_stats":null,"previous_names":["captaincluster/exercise-tracker"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCluster%2FExercise-Tracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCluster%2FExercise-Tracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCluster%2FExercise-Tracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCluster%2FExercise-Tracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CaptainCluster","download_url":"https://codeload.github.com/CaptainCluster/Exercise-Tracker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248936859,"owners_count":21186115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","expressjs","freecodecamp","freecodecamp-project","mongodb","nodejs"],"created_at":"2024-11-08T06:25:53.487Z","updated_at":"2025-04-14T18:32:12.447Z","avatar_url":"https://github.com/CaptainCluster.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Exercise Tracker\n\n![Express.js](https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge\u0026logo=express\u0026logoColor=%2361DAFB)\n![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge\u0026logo=mongodb\u0026logoColor=white)\n\nExercise Tracker is the 4th project for FreeCodeCamp *Back End Development and APIs* course. It uses **MongoDB** to save the users and their exercise\ninformation into a database. This data can then be retrieved and processed into logs.\n\nHere is an example of a use case:\n\u003e A user sends a POST request with a username. The server saves the user data and gives an ID that is required for creating exercise data entries\n\u003e and linking them to the user The user uses the ID and starts sending POST requests containing the exercise data. They get an overview of all of\n\u003e their exercise data with a GET request to their logs.\n\n🙏 Credits\n---\n![FreeCodeCamp](https://img.shields.io/badge/Freecodecamp-%23123.svg?\u0026style=for-the-badge\u0026logo=freecodecamp\u0026logoColor=green)\n\nEverything **not** written by me has been cloned from [this GitHub repository](https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/).\n\nThe default README that comes with the cloned repository:\n\u003e This is the boilerplate for the Exercise Tracker project. Instructions for building your project can be found at https://www.freecodecamp.org/learn/apis-and-microservices/apis-and-microservices-projects/exercise-tracker\n\nHere is the solution I wrote for this project:\n```\n/** \n * My additions\n * Using: express.js and MongoDB \n */\nconst bodyParser = require(\"body-parser\");\napp.use(bodyParser.urlencoded({ extended: false }));\n\n// Setting up MongoDB\nconst mongoose = require(\"mongoose\");\nasync function connectToMongoose()\n{\n  try\n  {\n    mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });\n    console.log(\"Connecting to MongoDB successful\");\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n}\nconnectToMongoose();\n\n// Creating the schemas\nconst userSchema = new mongoose.Schema({\n  username: { type: String, required: true }\n}, { versionKey: false });\n\nconst exerciseSchema = new mongoose.Schema({\n  username: {\n    type: String,\n  },\n  description: {\n    type: String\n  },\n  duration: {\n    type: Number\n  },\n  date: {\n    type: Date\n  },\n  userId: {\n    type: String\n  }\n}, { versionKey: false });\n\n// Creating the models\nconst User      = mongoose.model(\"User\", userSchema);\nconst Exercise  = mongoose.model(\"Exercise\", exerciseSchema);\n\n\n/**\n * A POST request to save a user to the database.\n * \n * Creating a JSON record to be saved into the database. Notifying through\n * console.log of it being successful and responding with the data in JSON\n * format.\n * \n * On failure: Writing the error message with console.error\n */\napp.post(\"/api/users\", async function(req, res)\n{ \n  try\n  {\n    const newUser = new User({\n      username: req.body.username,\n    });\n\n    const saveUser = await newUser.save();\n    console.log(`The following record has been saved: ${saveUser}`);\n    res.json(saveUser);\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n});\n\n/**\n * A GET request that retrieves each user\n */\napp.get(\"/api/users\", async function(req, res)\n{\n  try\n  {\n    const users = await User.find();\n    res.json(users);\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n});\n\n/**\n * A POST request that searches for a with a matching ID that is\n * given as a parameter. \n * \n * On failure: Writing the error message with console.error\n * If no matching ID is found, a JSON error response is sent\n * to the user.\n * \n * On failure: Writing the error message with console.error\n */\napp.post(\"/api/users/:_id/exercises\", async function(req, res, next)\n{\n  // Phase 1: Finding out whether a user record with the given ID param exists\n  try\n  {\n    req.selectedUser = await User.findById(req.params._id);\n    if(!req.selectedUser)\n    {\n      return res.json({ error: \"No user with the given ID exists.\" });\n    }\n    next();\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n},\nasync function(req, res)\n{\n  // Phase 2: Creating and saving an exercise record with the received data\n  try\n  {\n    let chosenDate = new Date();\n    if(req.body.date)\n    {\n      chosenDate = req.body.date;\n    }\n\n    const newExercise = new Exercise({\n      description:  req.body.description,\n      duration:     req.body.duration,\n      date:         chosenDate,\n      userId:       req.selectedUser._id\n    });\n\n    await newExercise.save()\n    res.json({\n      username:     req.selectedUser.username,\n      description:  newExercise.description,\n      duration:     newExercise.duration,\n      date:         new Date(newExercise.date).toDateString(),\n      _id:          newExercise.userId\n    })\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n});\n\n/**\n * A GET request that retrieves a log based on the given user ID\n * \n * On failure: Writing the error message with console.error\n */\napp.get(\"/api/users/:_id/logs\", async function(req, res, next)\n{\n  try\n  {\n    req.selectedUser = await User.findById(req.params._id);\n    if(!req.selectedUser)\n    {\n      return res.json({ error: \"No user with the given ID exists.\" });\n    }\n\n    next();\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n},\nasync function(req, res)\n{\n  try\n  {\n    let newDate = new Object();\n\n    if(req.query.from)\n    {\n      newDate[\"$gte\"] = new Date(req.query.from);\n    }\n    if(req.query.to)\n    {\n      newDate[\"$lte\"] = new Date(req.query.to);\n    }\n\n    let findCondition = { userId: req.params._id};\n\n    if(newDate[\"$gte\"] || newDate[\"$lte\"])\n    {\n      findCondition = {\n        userId: req.params._id,\n        date: newDate\n      }\n    } \n\n    const exercises = await Exercise.find(findCondition).limit(req.query.limit);\n\n    const innerLogsArray = [];\n    for(let i = 0; i \u003c exercises.length; i++)\n    {\n      innerLogsArray.push({\n        description:  exercises[i].description,\n        duration:     exercises[i].duration,\n        date:         new Date(exercises[i].date).toDateString()\n      });\n    }\n\n    res.json({\n      username: req.selectedUser.username,\n      count:    exercises.length,\n      _id:      req.selectedUser._id,\n      log:      innerLogsArray\n    });\n  }\n  catch(error)\n  {\n    console.error(error);\n  }\n});\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaptaincluster%2Fexercise-tracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaptaincluster%2Fexercise-tracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaptaincluster%2Fexercise-tracker/lists"}