Skip to content

Repository files navigation

NESTLY Engine

The NESTLY Engine is the server-side component of the NESTLY apartment renting website. It is built using ExpressJS and Apollo Server.

Table of Contents

Overview

The NESTLY Engine serves as the backend for the apartment renting website. It handles requests from the client, interacts with the database, and implements the business logic of the application.

Project Structure

The project structure of the NESTLY Engine is as follows:

  • src: Contains the source code of the NestJS application.
    • config: Contains the application configuration (eg. PORT, NODE_ENV, MongoDB URI etc).
    • graphql: Contains GraphQL operations for handling client requests.
    • middlewares: Contains middlewares for decoding user from token , handling errors etc.
    • models: Contains database schemas.
    • services: Contains business logic services.
    • types: Contains typescript types.
    • utils: Contains other app utilities.
    • start: Contains app and apollo server initiation logic.

Getting Started

Prerequisites

Before running the NESTLY Engine, make sure you have the following installed:

  • Node.js
  • npm or Yarn
  • MongoDB

Installation

  1. Clone the repository:

git clone https://github.com/jewtechx/nestly_engine.git

  1. Navigate to the engine directory:

cd nestly_engine/engine

  1. Install dependencies:

yarn install

  1. Add the following environment variables to the .env file:
NODE_ENV=development
PORT=8000
DEV_MONGO_URI=
TEST_MONGO_URI=
PROD_MONGO_URI=
TOKEN_EXPIRY=
LOGGER_LEVEL=
DEV_MAIL_USER=
DEV_MAIL_PASS=
DEV_MAIL_HOST=
DEV_MAIL_PORT=
DEV_MAIL_SECURE=

MAIL_USER=
MAIL_PASS=
MAIL_HOST=
MAIL_PORT=
MAIL_SECURE=

PAYSTACK_TEST_SECRET_KEY=

Usage

To start the NESTLY Engine, run the following command:

npm run dev

The engine will start running on the specified port, and you can access the GraphQL endpoint in your browser at http://localhost:80/graphql.

GraphQL Schema

This document provides detailed information about the GraphQL schema used in the NESTLY apartment renting website. It includes descriptions of all queries, mutations, types, and enums available in the schema.

Queries

USER

user

Returns a verified user's details, including profile, settings, and rating.

# Query: user
query {
  user {
    _id
    username
    email
    type
    profile {
      avatar
      firstname
      lastname
      phoneNumber
      address
    }
    rating {
      ratedBy
      criteria
      score
      comment
    }
    settings {
      language
      theme
      notificationEnabled
      soundEnabled
      autoSaveInterval
      profileVisibility
      contactInfoVisibility
      locationSharingEnabled
      activityTrackingEnabled
      dataSharingEnabled
      dataRetentionPeriod
      twoFactorAuthEnabled
      dataEncryptionEnabled
    }
  }
}

getUsersByType

Returns a list of users grouped by their type (OWNER,RENTER).

# Query: getUsersByType
query {
  getUsersByType {
    _id
    users {
      _id
      username
      email
      type
      profile {
        avatar
        firstname
        lastname
        phoneNumber
        address
      }
      rating {
        ratedBy
        criteria
        score
        comment
      }
      settings {
        language
        theme
        notificationEnabled
        soundEnabled
        autoSaveInterval
        profileVisibility
        contactInfoVisibility
        locationSharingEnabled
        activityTrackingEnabled
        dataSharingEnabled
        dataRetentionPeriod
        twoFactorAuthEnabled
        dataEncryptionEnabled
      }
    }
  }
}

getRecentUsers

Returns a list of users who recently registered within the last month.

# Query: getRecentUsers
query {
  getRecentUsers {
    _id
    username
    email
    type
    profile {
      firstname
      lastname
      phoneNumber
      address
    }
    rating {
      ratedBy
      criteria
      score
      comment
    }
    settings {
      language
      theme
      notificationEnabled
      soundEnabled
      autoSaveInterval
      profileVisibility
      contactInfoVisibility
      locationSharingEnabled
      activityTrackingEnabled
      dataSharingEnabled
      dataRetentionPeriod
      twoFactorAuthEnabled
      dataEncryptionEnabled
    }
  }
}

getAllUsers

Returns a list of all users, including both verified and unverified users.

# Query: getAllUsers
query {
  getAllUsers {
    _id
    username
    email
    type
    verified
  }
}

getAllVerifiedUsers

Returns a list of all verified users.

# Query: getAllVerifiedUsers
query {
  getAllVerifiedUsers {
    _id
    username
    email
    type
    verified
    profile {
      avatar
      firstname
      lastname
      phoneNumber
      address
    }
    rating {
      ratedBy
      criteria
      score
      comment
    }
    settings {
      language
      theme
      notificationEnabled
      soundEnabled
      autoSaveInterval
      profileVisibility
      contactInfoVisibility
      locationSharingEnabled
      activityTrackingEnabled
      dataSharingEnabled
      dataRetentionPeriod
      twoFactorAuthEnabled
      dataEncryptionEnabled
    }
  }
}

APARTMENT

getApartment

Returns an specific apartment with the provided _id

# Query: getApartment
query {
  getApartment(apartmentId: "exampleId") {
    _id
    owner
    name
    description
    location
    bedrooms
    bathrooms
    amenities
    price
    available
    Images
    reviews {
      rating
      comment
    }
  }
}

getAllOwnerApartments

Returns all apartments that belong to an owner

# Query: getAllOwnerApartments
query {
  getAllOwnerApartments {
    _id
    owner
    name
    description
    location
    bedrooms
    bathrooms
    amenities
    price
    available
    Images
    reviews {
      rating
      comment
    }
  }
}

getAllApartments

Returns all apartments based on query inputs

# Query: getAllApartments
query {
  getAllApartments(GetAllApartmentsInput: { filters: { bedrooms: { eq: 2 }, bathrooms: { gte: 2 }, price: { lte: 1500 } }, sort: { price: 1 }, pagination: { limit: 10, offset: 0 }, search: "exampleSearchString" }) {
    _id
    owner
    name
    description
    location
    bedrooms
    bathrooms
    amenities
    price
    available
    Images
    reviews {
      rating
      comment
    }
  }
}

BOOKING

getApartmentBooking

Returns bookings of an apartment and groups them by status

  # Query: getApartmentBooking
query {
  getApartmentBooking(GetApartmentBookingInput: { apartment: "exampleApartmentId"}) {
    
      apartment
      startDate
      endDate
      status
      notes
  }
}

Mutations

USER

createUser

Creates a new unverified user.

# Mutation: createUser
mutation {
  createUser(CreateUnverifiedUserInput: { username: "example", email: "example@example.com", password: "password", type: RENTER, verified: false }) {
    _id
    username
    email
    type
    verified
  }
}

verifyUser

Verifies a user using their verification code from email.

# Mutation: verifyUser
mutation {
  verifyUser(VerifyUserInput: { id: "exampleId", verificationCode: "verificationCode" })
}

createUserSession

Creates a new user session and returns access and refresh tokens.

# Mutation: createUserSession
mutation {
  createUserSession(CreateUserSessionInput: { email: "example@example.com" }) {
    accessToken
    refreshToken
  }
}

refreshToken

Refreshes the access token using the refresh token.

# Mutation: refreshToken
mutation {
  refreshToken(RefreshTokenInput: { token: "exampleToken" }) {
    accessToken
  }
}

loginUser

Logs in a user and returns their details, including profile, settings, and rating

# Mutation: loginUser
mutation {
  loginUser(LoginUserInput: { email: "example@example.com", password: "password" }) {
    _id
    username
    email
    type
    verified
  }
}

updateUser

Edits user's info but makes the rating open to ulterations by the general users

# Mutation: updateUser
mutation {
  updateUser(UpdateUserInput: {
    username: "newUsername",
    email: "new@example.com",
    password: "newPassword",
    type: RENTER,
    verificationCode: "newVerificationCode",
    verified: true,
    profile: { firstname: "New", lastname: "User", phoneNumber: "1234567890", address: "New Address" },
    rating: [{ ratedBy: "userId", criteria: "exampleCriteria", score: 5, comment: "Example comment" }],
    settings: {
      language: EN,
      theme: LIGHT,
      notificationEnabled: true,
      soundEnabled: true,
      autoSaveInterval: 10,
      profileVisibility: PUBLIC,
      contactInfoVisibility: PUBLIC,
      locationSharingEnabled: true,
      activityTrackingEnabled: true,
      dataSharingEnabled: true,
      dataRetentionPeriod: 365,
      twoFactorAuthEnabled: true,
      dataEncryptionEnabled: true
    }
  }) {
    _id
    username
    email
    type
    verified
    profile {
      firstname
      lastname
      phoneNumber
      address
    }
    rating {
      ratedBy
      criteria
      score
      comment
    }
    settings {
      language
      theme
      notificationEnabled
      soundEnabled
      autoSaveInterval
      profileVisibility
      contactInfoVisibility
      locationSharingEnabled
      activityTrackingEnabled
      dataSharingEnabled
      dataRetentionPeriod
      twoFactorAuthEnabled
      dataEncryptionEnabled
    }
  }
}

updateProfilePicture

Updates profile picture of user

#mutation updateProfilePicture

mutation {
  updateProfilePicture(useId:"6def12d_eef11223.32"){
    avatar
  }
}

deleteUser

Deletes a user's account and returns a success message

# Mutation: deleteUser
mutation {
  deleteUser(DeleteUserInput: { id: "exampleId" })
}

forgotPassword

Initiates the forgot password process by sending a reset link to the user's email.

# Mutation: forgotPassword
mutation {
  forgotPassword(ForgotPasswordInput: { email: "example@example.com" })
}

resetPassword

Resets the user's password using the password reset code from email.

# Mutation: resetPassword
mutation {
  resetPassword(ResetPasswordInput: { id: "exampleId", passwordResetCode: "resetCode", newPassword: "newPassword" })
}

APARTMENT

createApartment

Creates a new apartment and returns details

# Mutation: createApartment
mutation {
  createApartment(CreateApartmentInput: { name: "New Apartment", description: "Description", location: "Location", bedrooms: 2, bathrooms: 2, amenities: ["Amenity1", "Amenity2"], price: 1500, available: true, reviews: [{ rating: 4, comment: "Example comment" }] }) {
    _id
    owner
    name
    description
    location
    bedrooms
    bathrooms
    amenities
    price
    available
    images{
      path
    }
    reviews {
      rating
      comment
    }
  }
}

uploadImages

Takes Id of apartment and looks for it images in the standalone file upload server and updates apartment details

# Mutation: uploadImages

mutation {
  uploadImages(useId:"65d6159b871a42135367ab2e")
}

updateApartment

Edits an apartment details and returns the result

# Mutation: updateApartment
mutation {
  updateApartment(UpdateApartmentInput: { name: "Updated Apartment", description: "Updated Description", location: "Updated Location", bedrooms: 3, bathrooms: 3, amenities: ["Updated Amenity1", "Updated Amenity2"], price: 2000, available: false, images: ["image1.jpg", "image2.jpg"], reviews: [{ rating: 5, comment: "Updated comment" }] }) {
    _id
    owner
    name
    description
    location
    bedrooms
    bathrooms
    amenities
    price
    available
    images{
      path
    }
    reviews {
      rating
      comment
    }
  }
}

deleteApartment

Deletes an apartment post

# Mutation: deleteApartment
mutation {
  deleteApartment(DeleteApartmentInput: { id: "exampleId" })
}

BOOKING

createApartmentBooking

Creates a new booking and returns the data

# Query: getApartmentBooking
query {
  getApartmentBooking(GetApartmentBookingInput: { apartment: "exampleApartmentId", pagination: { limit: 10, offset: 0 } }) {
    _id
    bookings {
      apartment
      startDate
      endDate
      status
      notes
    }
  }
}

updateApartmentBooking

Updates the details of a booking

 # Mutation: updateApartmentBooking
mutation {
  updateApartmentBooking(UpdateApartmentBookingInput: { bookingId: "exampleBookingId", startDate: "2024-02-20", endDate: "2024-02-25", status: CONFIRMED, notes: "Updated note" }) {
    apartment
    startDate
    endDate
    status
    notes
  }
}

deleteApartmentBooking

Deletes an apartment booking

# Mutation: deleteApartmentBooking
mutation {
  deleteApartmentBooking(DeleteApartmentBookingInput: { bookingId: "exampleBookingId" })
}

PAYMENT

initiateTransaction

Start payment process and return a checkout url

# Mutation initiatePayment
mutation {
  initiateTransaction(InitiateTransactionInput: {
    email:"test@gmail.com",
    amount:"100000",
    })
}

verifyTransaction

verifies the status of the transaction

# Mutation verifyPayment
mutation {
  verifyTransaction(Reference:"0002385498XX1")
}

makePaymentToOwner

Transfers 95% of the amount of the rental to the owner of the apartment

# Mutation makePaymentToOwner
mutation {
  makePaymentToOwner(bookingId:"6ef23bededaad232af",userId:"6ef23bededaad232af2e2")
}

Contributing

Contributions to the NESTLY Engine are welcome! Feel free to open issues or submit pull requests to help improve the engine.

License

This project is licensed under the MIT License

Author

Jew Kofi Larbi Danquah

About

The engine that powers the nestly website

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages