Skip to content

Latest commit

Β 

History

History
587 lines (444 loc) Β· 10.2 KB

README.md

File metadata and controls

587 lines (444 loc) Β· 10.2 KB

Q&A API

Description

Simple Questios & Answers API with permissions. There are 2 User Roles: ORGANIZER and PARTICIPANT. Only Organizers can create questions while both roles can answer questions.

Technologies

  • Nest.js
  • Prisma (With PostgresSQL)
  • Docker

Technical Decisions

  • Only Organizers can create Questions;
  • Both roles can answer questions, but only once;
  • Organizers cannot answer their own questions;
  • There is no Administrator role, so anyone can create new Users. But User can only πŸ”΅ GET/🟣 PATCH/πŸ”΄ DELETE their own information;
  • There is no route to get All users;
  • Users can only 🟣 PATCH/πŸ”΄ DELETE their own Questions/Answers;
  • A PARTICIPANT user can get only their own answers. ORGANIZER users can get all answers from all questions.

Installation

1 - Clone the repository

git clone https://github.com/eduraio/qanda-api.git

2 - Install Dependecies

yarn install

3 - Populate .env file based on .env.example

DATABASE_URL="postgresql://user:password@localhost:5432/database?schema=public"
JWT_SECRET=

Note

Postgres User, Password and Database available on docker-compose.yml

Tip

Generate a JWT Secret, you can run the following script to generate yours:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

4 - Run docker-compose

docker-compose up

5 - Run Prisma Migrations

yarn prisma migrate dev

Usage

To start the project use:

yarn start

To run tests use:

yarn test

Tip

This project supports Swagger. Access the API Documentation on http://localhost:3000/docs

Note that all routes, except 🟒 POST /login and 🟒 POST /users, are protected.

AccessTokens are valid for 10 minutes

You will need the AccessToken to authenticate on other routes

Routes

Here goes all the routes. You can also check Docs for full details.

πŸ”’ All routes, except 🟒 POST /login and 🟒 POST /users, must have an Authorization header containing the accessToken

{
  "Authorization": "Bearer {accessToken}"
}

Login

🟒 POST /auth/login

Log In

Request Body

{
  "email": "string",
  "password": "string"
}

Response Application/json

{
  "accessToken": "string"
}

πŸ”’ Users

Parameter Description
id User UUID
email UNIQUE User e-mail
name User name
password User password
role Role of the user. ORGANIZER | PARTICIPANT
questions? Array of questions created by this user
answers? Array of answers created by this user
created_at Date of creation
updated_at Last updated date

🟒 POST /users

Create a new user

Request Body

{
  "email": "string",
  "name": "string",
  "password": "string",
  "role": "ORGANIZER | PARTICIPANT"
}

Response Application/json

{
  "id": "string",
  "email": "string",
  "name": "string",
  "role": "ORGANIZER | PARTICIPANT",
  "questions": [],
  "answers": [],
  "created_at": "date",
  "updated_at": "date"
}

πŸ”΅ GET /users/{id}

Get user info. User can get only their own information.

Request Body

{}

Response Application/json

{
  "id": "string",
  "email": "string",
  "name": "string",
  "role": "ORGANIZER | PARTICIPANT",
  "questions": [],
  "answers": [],
  "created_at": "date",
  "updated_at": "date"
}

🟣 PATCH /users/{id}

Update user info. User can update only their own information.

Request Body

{
  "email": "string",
  "password": "string",
  "name": "string",
  "role": "ORGANIZER | PARTICIPANT"
}

Response Application/json

{
  "id": "string",
  "email": "string",
  "name": "string",
  "role": "ORGANIZER | PARTICIPANT",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”΄ DELETE /users/{id}

Delete user info. User can delete only their own information.

Request Body

{}

Response Application/json

{
  "id": "string",
  "email": "string",
  "name": "string",
  "role": "ORGANIZER | PARTICIPANT",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”’ Questions

Parameter Description
id User UUID
question Question
created_by_user_id Organizer user UUID
answers? Array of answers for this question
created_at Date of creation
updated_at Last updated date

Note

Property created_by_user_idautomatically populated based on logged in user

🟒 POST /questions

Create a new question. Only users with the role ORGANIZER can create new questions.

Request Body

{
  "question": "string"
}

Response Application/json

{
  "id": "string",
  "question": "string",
  "created_by_user_id": "string",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”΅ GET /questions

Get all questions. This route returns the parameter answered_by_me that indicates whether this questions was already answered by the user or not.

Paginated

Available Request Parameters

"order": "-- | ASC | DESC",
"limit": number,
"offset": number,
"sort": "-- | created_at",
"id": "Question UUID",
"question": "string",
"created_by_user_id": "User UUID"

Response Application/json

{
  "results": [
    {
      "id": "string",
      "question": "string",
      "created_by_user_id": "string",
      "created_at": "date",
      "updated_at": "date",
      "answered_by_me": true
    }
  ],
  "total": 0,
  "limit": 25,
  "offset": 0
}

πŸ”΅ GET /questions/{id}/answers

Get all answers from the specified question. Only users with the role ORGANIZER can have this information,

Paginated

Available Request Parameters

"order": "-- | ASC | DESC",
"limit": number,
"offset": number,
"sort": "-- | created_at",
"answer": "string",
"answer_by_user_id": "User UUID"

Response Application/json

{
  "results": [
    {
      "id": "string",
      "answer": "string",
      "answer_by_user_id": "string",
      "question_id": "string",
      "created_at": "date",
      "updated_at": "date"
    }
  ],
  "total": 0,
  "limit": 25,
  "offset": 0
}

πŸ”΅ GET /questions/{id}

Get question information.

Request Body

{}

Response Application/json

{
  "id": "string",
  "question": "string",
  "created_by_user_id": "string",
  "created_at": "date",
  "updated_at": "date",
  "answered_by_me": true
}

🟣 PATCH /questions/{id}

Update a question. Only the question owner can update the question.

Request Body

{
  "question": "string"
}

Response Application/json

{
  "id": "string",
  "question": "string",
  "created_by_user_id": "string",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”΄ DELETE /questions/{id}

Delete a question. Only the question owner can delete the question.

Request Body

{}

Response Application/json

{
  "id": "string",
  "question": "string",
  "created_by_user_id": "string",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”’ Answers

Parameter Description
id User UUID
answer Answer
answer_by_user_id User UUID
question_id Question UUID
created_at Date of creation
updated_at Last updated date

Note

Property answer_by_user_idautomatically populated based on logged in user

🟒 POST /answers

Create a new answer to a question.

Request Body

{
  "answer": "string",
  "question_id": "string"
}

Response Application/json

{
  "id": "string",
  "answer": "string",
  "answer_by_user_id": "string",
  "question_id": "string",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”΅ GET /answers

Get all answers. Users with the role PARTICIPANT can get only their own answers. Users with the role ORGANIZER can get all answers.

Paginated

Available Request Parameters

"order": "-- | ASC | DESC",
"limit": number,
"offset": number,
"sort": "-- | created_at",
"answer": "string",
"answer_by_user_id": "User UUID",
"id": "Answer UUID",

Response Application/json

{
  "results": [
    {
      "id": "string",
      "answer": "string",
      "answer_by_user_id": "string",
      "question_id": "string",
      "created_at": "date",
      "updated_at": "date"
    }
  ],
  "total": 0,
  "limit": 25,
  "offset": 0
}

πŸ”΅ GET /answers/{id}

Get answer information. Users with the role PARTICIPANT can get information only of their own answers. Users with the role ORGANIZER can get information from all answers.

Request Body

{}

Response Application/json

{
  "id": "string",
  "answer": "string",
  "answer_by_user_id": "string",
  "question_id": "string",
  "created_at": "date",
  "updated_at": "date"
}

🟣 PATCH /answers/{id}

Update a answer. Only the answer owner can update the answer.

Request Body

{
  "answer": "string",
  "question_id": "string"
}

Response Application/json

{
  "id": "string",
  "answer": "string",
  "answer_by_user_id": "string",
  "question_id": "string",
  "created_at": "date",
  "updated_at": "date"
}

πŸ”΄ DELETE /answers/{id}

Delete a answer. Only the answer owner can delete the answer.

Request Body

{}

Response Application/json

{
  "id": "string",
  "answer": "string",
  "answer_by_user_id": "string",
  "question_id": "string",
  "created_at": "date",
  "updated_at": "date"
}