/gympass-api

Node.js & Typescript based, developed with concepts like SOLID, DDD, TDD, Repository Pattern, Factory Method and RBAC system. Has unit test for especific use-cases and test E2E for every HTTP controller.

Primary LanguageTypeScriptMIT LicenseMIT

GympassAPI

✨ A copy (or something like) of the Gympass API. Node.js & Typescript based, developed with concepts like SOLID, DDD, TDD, Repository Pattern, Factory Method and RBAC system. Has unit test for especific use-cases and test E2E for every HTTP controller. ✨

GitHub Repo stars License: MIT

Table of contents

Why GympassAPI?

GympassAPI was a project to better learn the concepts involved in the backend, such as SOLID concepts, the principles of DDD and TDD. I also learned about the RBAC authorization system, the use of the JWT token, authentication and validation systems and much more.

Getting Started

To get started with GympassAPI, follow these simple steps:

1. Installation

First of all, clone the repository and install de dependencies.

npm install

2. Setting up your environment

Now we must setup our environment variables. Create a file on root as .env. Inside, put all data like is on .env.example

NODE_ENV=dev

# Auth
JWT_SECRET=YOUR_SECRET_HERE

# Database
DATABASE_URL="url_from_your_database"

3. Create a Database

There is a docker-compose.yml file inside the project, so if you want to create the container as I thot, you can run the following command

docker compose up -d

and if you want to stop the container

docker compose stop

🛠️ Features

FRs (Functional requirements)

  • It must be possible to register;
  • It must be possible to authenticate;
  • It must be possible to obtain the profile of a logged-in user;
  • It must be possible to obtain the number of check-ins carried out by the logged-in user;
  • It must be possible for the user to obtain their check-in history;
  • It must be possible for the user to search for nearby gyms (up to 10km);
  • It must be possible for the user to search for gyms by name;
  • It must be possible for the user to check-in at a gym;
  • It must be possible to validate a user's check-in;
  • It must be possible to register a gym;

BRs (Business Rules)

  • The user must not be able to register with a duplicate e-mail address;
  • The user cannot make 2 check-ins on the same day;
  • The user cannot check in if they are not close (100m) to the gym;
  • The check-in can only be validated up to 20 minutes after it has been created;
  • The check-in can only be validated by administrators;
  • The gym can only be registered by administrators;

NFRs (Non-functional requirements)

  • The user's password must be encrypted;
  • The application data must be persisted in a PostgreSQL database;
  • All data lists must be paginated with 20 items per page;
  • The user must be identified by a JWT (JSON Web Token);

🛑 Endpoints

Here you can see all the endpoints of the application

Users

  • POST - '/users'
    • This is the user's entry route, where the user will register with on the application. You must send the request with a data equal a some user's informations on the body of the requisition.

      Params Type Default
      name string -
      email string -
      password string -
      role string 'MEMBER'



  • POST - '/sessions'
    • This is the authenticate route. Here, the user can log-in on our application. Send this data as the body of the request as a JSON. After that, we will generate a access token that contains the user ID and about his role.

      Params Type Default
      email string -
      password string -



  • PATCH - '/token/refresh'
    • This route will check if the user has an access token. If not, it will try to create another one based on the refresh token located in cookies. You must send the requisition with the access token as authorization (if you have one).

      Header Type
      Authorization Bearer



  • GET - '/me'

    • This route requires that you already be logged-in. Here, you send your requisition with a JWT Token as authorization.

      Header Type
      Authorization Bearer

    will be something like this

    fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json' 
      }
    })

Gyms

On Gyms, every route needs to be authenticated, that means every request must have the following header: Authorization Bearer ${token}. Some routes also require role = 'ADMIN'.

  • GET - '/gyms/search'
    • Here you can search gyms by their name. You must send the request with a query as q on the body of the requisition as a JSON.

      Params Type Default
      q string -
      page number 1



  • GET - '/gyms/nearby'
    • Here you can find nearby gyms based on latitude and longitude of the user. You must send the request with a latitude and longitude of the user on the body of the requisitionas as a JSON.

      Params Type Default
      latitude number -
      longitude number -



  • POST - '/gyms'
    • Here we create a new Gym on database. You must do this as a 'ADMIN' user so your access token must have this proprerty. You can pass the informations of the gym on the body of the requisition as a JSON.

      Params Type Default
      title string -
      description string -
      phone number -
      latitude number -
      longitude number -

Check Ins

On Check Ins, every route needs to be authenticated.

  • GET - '/check-ins/history'

    • Here we can take the history of all check-ins that the user made it. You must just provide your JWT Token for the authorization.

      Header Type
      Authorization Bearer

    will be something like this

    fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json' 
      }
    })



  • GET - '/check-ins/metrics'

    • Here we can take the metrics of the user. You must just provide your JWT Token for the authorization.

      Header Type
      Authorization Bearer

    will be something like this

    fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json' 
      }
    })



  • POST - '/gyms/:gymId/check-ins'
    • Here we can create a check-in on a gym. You must provide on the URL param the id of the gym as gymID and on the body of the request the latitude and longitude of the user as a JSON.

      Params Type Default
      gymId string -
      latitude number -
      longitude number -



  • POST - '/check-ins/:checkInId/validate'
    • Here we validate the check-in of the user. You must do this as a 'ADMIN' user so your access token must have this proprerty. You also must provide on the URL param the checkInId as the check-in that will be validated.

      Params Type Default
      checkInId string -

🚀 Technologies

The technologies used to develop this application was:

📝 License

GympassAPI is released under the MIT License.

✍ Author


Pedro Henrique Klein

Made with 💜 by Pedro Henrique Klein

LinkedIn: pedro-klein pedro.klein.sl@gmail.com