dfout / HeapLeak

2 stars 0 forks source link

HeapLeak

Welcome to the HeapLeak README! HeapLeak is a humble clone of the legendary StackOverflow, built and maintained by Kyle Flores, Drew Fout, Syed Zaidi, and Zach Gold

Tech Stack

Frameworks and Libraries

Python Flask JavaScript React Redux CSS3 HTML5

Database:

Postgres

Hosting:

Render

Wiki Articles

Feature List | Database Schema | User Stories

Homepage

Filters

Question Page

API Documentation

AUTH

Endpoint: GET /

Description: Authenticates a user. Returns user information if authenticated, otherwise returns an unauthorized error.

Response: 200 OK: Returns the current user's information if authenticated.

{
  "id": 1,
  "username": "exampleUser",
  "email": "user@example.com"
}

Error (401 UNAUTHORIZED):

{
  "message": "Unauthorized"
}

Endpoint: POST /login

Description: Logs a user in. Requires email and password. If authentication is successful, the user is logged in and their information is returned.

Request:

Body

{
  "email": "user@example.com",
  "password": "password"
}

Response: 200 OK: Returns the logged in user's information if credentials are correct. Body

{
  "id": 1,
  "username": "exampleUser",
  "email": "user@example.com"
}

Error (401 UNAUTHORIZED):

{
  "email": ["Invalid email address"],
  "password": ["Incorrect password"]
}

Endpoint: GET /logout

Description: Logs the current user out and returns a confirmation message.

Response: 200 OK: Returns a message indicating the user has been logged out.

{
  "message": "User logged out"
}

Endpoint: POST /signup

Description: Creates a new user and logs them in. Requires username, email, and password.

Request:

Body (JSON):

{
  "username": "newUser",
  "email": "newuser@example.com",
  "password": "newpassword"
}

Response: 200 OK: Returns the newly created user's information.

{
  "id": 2,
  "username": "newUser",
  "email": "newuser@example.com"
}

Error (401 UNAUTHORIZED):

{
  "username": ["Username already taken"],
  "email": ["Email already in use"],
  "password": ["Password is too short"]
}

Endpoint: GET /unauthorized

Description: Returns unauthorized JSON when Flask Login authentication fails.

Response:

401 Unauthorized: Returns an error message indicating unauthorized access.

{
  "errors": {
    "message": "Unauthorized"
  }
}

USERS

Endpoint: GET /users

Description: Query for all users and return them in a list of user dictionaries.

Authentication: Required (logged in)

Parameters:

Response:

Success (200 OK):

{
  "users": [
    {
      "id": 1,
      "username": "user1",
      "email": "user1@example.com"
      // Other user fields...
    },
    {
      "id": 2,
      "username": "user2",
      "email": "user2@example.com"
      // Other user fields...
    }
    // More users...
  ]
}

Error (401 UNAUTHORIZED):

{
  "message": "Login required"
}

Endpoint: GET /users/<int:id>

Description: Query for a user by ID and return that user in a dictionary.

Authentication: Required (logged in)

Parameters:

Response:

Success (200 OK):

{
  "id": 1,
  "username": "user1",
  "email": "user1@example.com"
  // Other user fields...
}

Error (401 UNAUTHORIZED):

{
  "message": "Login required"
}

Error (404 NOT FOUND):

{
  "message": "User could not be found"
}

Endpoint: GET /saves

Description: Retrieve all saved questions for the current logged in user. Returns an empty array if there are no saved questions or if the questions no longer exist.

Authentication: Required (logged in)

Parameters:

Response: Success (200 OK):

{
  "SavedQuestions": [
    {
      "id": 1,
      "post": {
        "id": 1,
        "title": "Question Title",
        "body": "Question Body",
        "author": "Author Username",
        "Tags": [{ "id": 1, "tag": "Tag1" }],
        "Answers": [
          {
            "id": 1,
            "body": "Answer Body",
            "author": { "id": 1, "username": "Answer Author" }
          }
        ]
      }
    }
  ]
}

Error (401 UNAUTHORIZED):

{
  "message": "Login required"
}

Endpoint: GET /answers

Description: Retrieve all answers made by the currently logged in user. Returns an empty array if there are no answers or if the related questions no longer exist.

Authentication: Required (logged in)

Parameters:

Response: Success (200 OK):

{
  "Answers": [
    {
      "id": 1,
      "body": "This is an answer.",
      "question_id": 1,
      "user_id": 1,
      "is_primary": false,
      "mainPost": {
        "id": 1,
        "title": "Sample Question",
        "body": "This is a sample question.",
        "ownerId": 2,
        "Tags": [
          {
            "id": 1,
            "tag": "SampleTag"
          }
        ],
        "Answers": [
          {
            "id": 1,
            "body": "This is an answer.",
            "user_id": 1,
            "is_primary": false
          }
        ],
        "author": {
          "id": 2,
          "username": "author_username"
        }
      }
    }
  ]
}

Error (401 UNAUTHORIZED):

{
  "message": "Login required"
}

QUESTIONS

Endpoint: GET /questions

Description: Retrieve all questions from the database, including each question's tags, author information, answers, and the number of saves.

Response:

Success (200 OK):

{
  "Questions": [
    {
      "id": 1,
      "title": "Question Title",
      "body": "Question Body",
      "ownerId": 1,
      "author": "Author Username",
      "Tags": [
        {
          "id": 1,
          "tag": "Tag Value",
          "question_id": 1
        }
      ],
      "Answers": [
        {
          "id": 1,
          "body": "Answer Body",
          "ownerId": 2,
          "author": {
            "id": 2,
            "username": "Answer Author Username"
          }
        }
      ],
      "numSaves": 5
    }
  ]
}

Endpoint: GET /questions/<int:id>

Description: Retrieve a specific question from the database by its ID, including the question's tags, author information, and answers.

Parameters:

Response:

Success (200 OK):

{
  "Question": {
    "id": 1,
    "title": "Question Title",
    "body": "Question Body",
    "ownerId": 1,
    "author": "Author Username",
    "Tags": [
      {
        "id": 1,
        "tag": "Tag Value",
        "question_id": 1
      }
    ],
    "Answers": [
      {
        "id": 1,
        "body": "Answer Body",
        "ownerId": 2,
        "author": {
          "id": 2,
          "username": "Answer Author Username"
        }
      }
    ]
  }
}

Error (404 NOT FOUND):

{
  "message": "Question could not be found"
}

Endpoint: POST /questions

Description: Create a new question and add it to the database along with any tags provided in the request. The user must be logged in for this operation.

Authentication: Required (logged in)

Request Body:

{
  "title": "Question Title",
  "body": "Question Body",
  "tags": ["Tag1"]
}

Response:

Success (201 CREATED):

{
  "Question": {
    "id": 1,
    "title": "Question Title",
    "body": "Question Body",
    "author": "Current User",
    "Tags": [
      {
        "id": 1,
        "tag": "Tag1",
        "question_id": 1
      }
    ]
  }
}

Error (400 BAD REQUEST):

{
  "message": "Bad Request",
  "errors": {
    "field": ["error message"]
  }
}

Endpoint: PUT /questions/<int:id>

Description: Update a specific question in the database. The user must be logged in and be the owner of the question to make updates.

Authentication: Required (logged in)

Parameters:

Request Body:

{
  "title": "Updated Question Title",
  "body": "Updated Question Body",
  "tags": ["NewTag1"]
}

Response:

Success (200 OK):

{
  "Question": {
    "id": 1,
    "title": "Updated Question Title",
    "body": "Updated Question Body",
    "author": "Current User",
    "Tags": [
      {
        "id": 1,
        "tag": "NewTag1",
        "question_id": 1
      }
    ],
    "Answers": [
      {
        "id": 1,
        "body": "Answer Body",
        "ownerId": 2,
        "author": {
          "id": 2,
          "username": "Answer Author Username"
        }
      }
    ]
  }
}

Error (400 BAD REQEST):

{
  "message": "Bad Request",
  "errors": {
    "field": ["error message"]
  }
}

Error (401 UNAUTHORIZED):

{
  "message": "Bad Request",
  "errors": {
    "field": ["error message"]
  }
}

Endpoint: GET /questions/<int:id>/answers

Description: Retrieve all answers associated with a specific question from the database.

Parameters:

Response:

Success (200 OK):

{
  "Answers": [
    {
      "id": 1,
      "body": "Answer Body",
      "ownerId": 2,
      "author": "Answer Author Username"
    },
    {
      "id": 2,
      "body": "Another Answer Body",
      "ownerId": 3,
      "author": "Another Answer Author Username"
    }
  ]
}

Error (404 NOT FOUND):

{
  "message": "Question could not be found"
}

Endpoint: POST /questions/<int:id>/answers

Description: Create a new answer for a specific question and add it to the database. The answer is created as a non-primary answer by default. The user must be logged in to perform this operation.

Authentication: Required (logged in)

Parameters:

Request Body:

{
  "body": "Answer Body"
}

Response:

Success (201 CREATED):

{
  "Answer": {
    "id": 1,
    "body": "Answer Body",
    "ownerId": 2,
    "mainPost": {
      "id": 1,
      "title": "Question Title",
      "body": "Question Body",
      "owner": {
        "id": 1,
        "username": "Question Author Username"
      }
    }
  }
}

Error (400 BAD REQUEST):

{
  "message": "Bad Request",
  "errors": {
    "field": ["error message"]
  }
}

Endpoint: POST /questions/<int:id>/tags

Description: Add new tags to an existing question in the database. The user must be logged in to perform this operation.

Authentication: Required (logged in)

Parameters:

Request Body:

{
  "tags": ["Tag1", "Tag2"]
}

Response:

Success (200 OK):

{
  "Tags": [
    {
      "id": 1,
      "tag": "Tag1",
      "question_id": 1
    },
    {
      "id": 2,
      "tag": "Tag2",
      "question_id": 1
    }
  ]
}

Error (400 BAD REQUEST):

{
  "message": "Bad Request",
  "errors": {
    "field": ["error message"]
  }
}

Endpoint: POST /questions/<int:id>/saves

Description: Create a relationship to save the specified question for the currently logged in user.

Authentication: Required (logged in)

Parameters:

Response:

Success (201 Created):

{
  "Save": {
    "id": 1,
    "question_id": 1,
    "user_id": 2,
    "post": {
      "id": 1,
      "title": "Question Title",
      "body": "Question Body",
      "author": "Question Author Username",
      "Tags": [
        {
          "id": 1,
          "tag": "Tag1",
          "question_id": 1
        }
      ]
    }
  }
}

Error (404 NOT FOUND):

{
  "message": "Question could not be found"
}

Endpoint: DELETE /saves/<int:id>

Description: Remove the relationship indicating that the user has saved a specific question.

Authentication: Required (logged in)

Parameters:

Response:

Success (200 OK):

{
  "Id": 1
}

Error (404 NOT FOUND):

{
  "message": "Relation could not be found"
}

Endpoint: DELETE /questions/<int:id>

Description: Delete a specific question from the database if the user is logged in and is the owner of the question.

Authentication: Required (logged in)

Parameters:

Response:

Success (200 OK):

{
  "id": 1
}

Error (404 NOT FOUND):

{
  "id": null
}

ANSWERS

Endpoint: PUT /answers/<int:id>

Description: Update the body of an answer if the user is logged in and is the owner of the answer.

Authentication: Required (logged in)

Parameters:

Request Body:

body (string): The new body of the answer.

Response:

Success (200 OK):

{
  "Answer": {
    "id": 1,
    "body": "Updated answer body",
    "question_id": 1,
    "user_id": 2,
    "mainPost": {
      "id": 1,
      "title": "Question Title",
      "body": "Question Body",
      "owner": {
        "id": 2,
        "username": "Owner Username",
        "email": "owner@example.com"
      }
    }
  }
}

Error (400 BAD REQEST):

{
  "message": "Bad Request",
  "errors": {
    "field": ["error message"]
  }
}

Error (401 UNAUTHORIZED):

{
  "message": "Not the owner of this Answer"
}

Endpoint: PUT /answers/<int:id>/mark_primary

Description: Update an answer to be the primary answer for the linked question if the user is logged in and is the owner of the question. This will demote any existing primary answer.

Authentication: Required (logged in)

Parameters:

Response:

Success (200 OK):

{
  "Answer": {
    "id": 1,
    "body": "Answer body",
    "question_id": 1,
    "user_id": 2,
    "is_primary": true,
    "mainPost": {
      "id": 1,
      "title": "Question Title",
      "body": "Question Body",
      "owner": {
        "id": 2,
        "username": "Owner Username",
        "email": "owner@example.com"
      }
    }
  }
}

Error (401 UNAUTHORIZED):

{
  "message": "Not the owner of this Answer"
}

Endpoint: DELETE /answers/<int:id>

Description: Delete an answer if the user is logged in and is the owner of the answer.

Authentication: Required (logged in)

Parameters:

Response:

Success (200 OK):

{
  "id": 1
}

Error (401 UNAUTHORIZED):

{
  "id": null
}

TAGS

Endpoint: GET /tags

Description: Retrieve a list of all available tags.

Authentication: Required (logged in)

Parameters:

Response: Success (200 OK):

{
  "Tags": ["Tag1", "Tag2", "Tag3"]
}

Error (401 UNAUTHORIZED):

{
  "message": "Login required"
}

Endpoint: DELETE /tags/<int:id>

Description: Remove a tag from a question. The tag is deleted only if the current user is the owner of the question associated with the tag.

Authentication: Required (logged in)

Parameters:

Response: Success (200 OK):

{
  "id": 123
}

Error (401 UNAUTHORIZED):

{
  "message": "Login required"
}

Error (404 NOT FOUND):

{
  "id": null
}