---
# System prepended metadata

title: 'PA: Product and Presentation'

---

# PA: Product and Presentation

The Super Legit Collaborative News (SLCN) is a project headed by a small group of developers with the main goal of free, open, and accessible news sharing for and by users.

This will allow all users to view and browse all types of news and comments on any topic, with access to text search and tag selection..

## A9: Product

The product developed is a collaborative news website, where users can create, view and browse all types of news and comments on most topics, with access to text search and tag selection. 

On he home page, users can find a feed with the highest rated news, with options to search for a specific one or sort them by date. There is also a personalized news feed only with news marked by tag that the user follows.

Both news and comments are able to be rated by any authenticated user, where they can be liked or disliked. A user's own reputation is the sum of the reputation of all their posted news and comments, and can be found on their profile.

The profile houses the user's information, such as their name, reputation, country of origin, profile picture, followed and following users and a list of their posted news. The user's personal information may also be edited here.

News can be posted, using a Rich Text Editor, and are comprised of a Title, Rich Text content and a selection of tags. New tags can be proposed by users and added by administrators. 

A user will be notified whenever another user likes any of their news or comments.

Finally administrators can edit and delete any news, comment or profile, and have access to an admin page where they can manage the proposed tags.

### 1. Installation

final version: [link  ](https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/tree/PA)

> Include the full Docker command to start the image available at the group's GitLab Container Registry using the production database.  

### 2. Usage

http://lbaw2286.lbaw.fe.up.pt

Install:
```
composer install
composer require pusher/pusher-php-server
php artisan route:clear &&   php artisan view:clear &&  php artisan config:clear && php artisan cache:clear &&  php artisan clear-compiled
```

And to run it locally:
```
docker run -it -p 8000:80 --name=lbaw2286 -e DB_DATABASE="lbaw2286" -e DB_SCHEMA="lbaw2286" -e DB_USERNAME="lbaw2286" -e DB_PASSWORD="HfwKxxtO" git.fe.up.pt:5050/lbaw/lbaw2223/lbaw2286
```


#### 2.1. Administration Credentials

| Email | Password |
| -------- | -------- |
| admin@example.com  | 1234 |
| lucas@legitmail.com | legitlucas | 


#### 2.2. User Credentials

| Type          | Email  | Password |
| ------------- | --------- | -------- |
| basic account | andre@legitmail.com | legitandre |


### 3. Application Help

Help was implemented in the about us page, where users can click "contact us" and directly send an email to the team.

### 4. Input Validation

The input data is always validated either through javascript or html. As an example, the number of tags selected are validated through javascript functions with event listeners. The forms for search are verified through html.

### 5. Check Accessibility and Usability

The results of accessibility and usability tests using the checklists are in the following pdfs:

- Accessibility https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/blob/main/docs/checklists/accessibility_checklist.pdf 
- Usability: https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/blob/main/docs/checklists/usability_checklist%20.pdf

### 6. HTML & CSS Validation

The results of the validation of the HTML and CSS code using the required tools are the following:

- For HTML we got the following results: https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/tree/main/docs/results
- For CSS the results are in: https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/tree/main/docs/CSS%20validator

### 7. Revisions to the Project


The revisions we made since the ER were the removal of the descriptions from the tags proposals, and the removal of the images from the user's database since they are now integrated into the newly implemented rich text editor. Also the ones reported before as the change from 'topics' to 'tags' in all files.  

### 8. Web Resources Specification

https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/blob/main/a9_openapi.yaml

```yaml
openapi: 3.0.0

info:
  version: "2.0"
  title: "LBAW SLCN Web API"
  description: "Web Resources Specification (A9) for SLCN"

servers:
  - url: http://lbaw2286.lbaw.fe.up.pt
    description: Production server

externalDocs:
  description: Find more info here.
  url: https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/wikis/home

tags:
  - name: "M01: Authentication"
  - name: "M02: Users"
  - name: "M03: News"
  - name: "M04: Comments"
  - name: "M05: Tags"
  - name: "M06: Notifications"
  - name: "M07: Search"
  - name: "M08: User Administration and Static Pages"

paths:
  /login:
    get:
      operationId: R101
      summary: "R101: LoginForm"
      description: "Provide login form. Access: PUB"
      tags:
        - "M01: Authentication"
      responses:
        "200":
          description: "Ok. Show Log-in UI10"
    post:
      operationId: R102
      summary: "R102: Login Action"
      description: "Processes the login form submission. Access: PUB"
      tags:
        - "M01: Authentication"

      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                email: # <!--- form field name
                  type: string
                password: # <!--- form field name
                  type: string
              required:
                - email
                - password

      responses:
        "302":
          description: "Redirect after processing the login credentials."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Successful authentication. Redirect main page."
                  value: "/"
                302Error:
                  description: "Failed authentication. Redirect to login form."
                  value: "/login"

  /logout:
    post:
      operationId: R103
      summary: "R103: Logout Action"
      description: "Logout the current authenticated user. Access: USR, ADM"
      tags:
        - "M01: Authentication"
      responses:
        "302":
          description: "Redirect after processing logout."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Successful logout. Redirect to main page."
                  value: "/"
                302Failure:
                  description: "Failed logout. Redirect to main page."
                  value: "/"

  /register:
    get:
      operationId: R104
      summary: "R104: Register Form"
      description: "Provide new user registration form. Access: PUB"
      tags:
        - "M01: Authentication"
      responses:
        "200":
          description: "Ok. Show Sign-Up UI09"

    post:
      operationId: R105
      summary: "R105: Register Action"
      description: "Processes the new user registration form submission. Access: PUB"
      tags:
        - "M01: Authentication"

      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                username:
                  type: string
                email:
                  type: string
                password:
                  type: string
              required:
                - username
                - email
                - password
      responses:
        "302":
          description: "Redirect after processing the new user information."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Successful authentication. Redirect to main page."
                  value: "/"
                302Failure:
                  description: "Failed authentication. Redirect to login form."
                  value: "/login"
  /profile/{id}:
    get:
      operationId: R201
      summary: "R201: Gets a profile page of a user."
      description: "Displays profile page of a user. Access: USR"
      tags:
        - "M02: Users"
      responses:
        "200":
          description: "Ok. Show Profile page [UI03]"
        "302":
          description: "Redirect."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "Redirect to login page."
                  value: "/login"

  /edit_profile/{id}:
    post:
      operationId: R202
      summary: "R202: Displays User edit page."
      description: "Display edit page for a user's profile. Access: AUTH, ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "302":
          description: "Redirect."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Redirect to profile edit page."
                  value: "/edit_profile/{id}"
                302Failure:
                  description: "Redirect to profile page."
                  value: "/profile/{id}"

  /api/edit_profile/{id}:
    post:
      operationId: R203
      summary: "R203: Edits a user's profile."
      description: "Processes and edits a user's profile. Access: AUTH, ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                username:
                  type: string
                country:
                  type: string
                email:
                  type: string
                password:
                  type: string
              required:
                - id
                - username
                - country
                - email
                - password
      responses:
        "302":
          description: "Redirect."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Redirect to profile page."
                  value: "/profile/{id}"
                302Failure:
                  description: "Redirect to profile edit page."
                  value: "/edit_profile/{id}"

  /change_admin/{id}:
    post:
      operationId: R204
      summary: "R204: Changes a users admin role."
      description: "Changes a users admin role. If the user is an admin, they lose the role and vice-versa. Access: ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "302":
          description: "Redirect."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Redirect to profile page."
                  value: "/profile/{id}"
                302Failure:
                  description: "Redirect to profile page."
                  value: "/profile/{id}"

  /:
    get:
      operationId: R301
      summary: "R301: Shows home feed."
      description: "Obtains page with the most popular news items. Access; PUB"
      tags:
        - "M03: News"
      responses:
        "200":
          description: "Ok. Show home feed [UI01]"

  /news/{id}:
    get:
      operationId: R302
      summary: "R302: Shows news item."
      description: "Obtains page with the selected news item. Access; USR"
      tags:
        - "M03: News"
      parameters:
        - in: path
          name: id
          schema:
            type: integer
          required: true
      responses:
        "200":
          description: "Ok. Show news item [UI02]"
        "302":
          description: "User not logged in. Redirect to login form"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"

  /api/news:
    post:
      operationId: R303
      summary: "R303: News creation action."
      description: "Processes the new news item form submition and creates the news item. Access; USR"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlenconded:
            schema:
              type: object
              properties:
                title:
                  type: string
                content:
                  type: string
                picture:
                  type: object
                id_author:
                  type: integer
              required:
                - title
                - content
                - id_author

      responses:
        "302":
          description: "Redirect after processing new news item."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Successful news creation. Redirection to news item."
                  value: "/news/{id}"
                302Failure:
                  description: "Failure in news creation. Redirection to home page."
                  value: "/"

  /api/news/{news_id}:
    post:
      operationId: R304
      summary: "R304: Deletes a news item"
      description: "Deletes a news item; Access: AUTH, ADM"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlenconded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "302":
          description: "Redirect after processing and deleting news item."
          headers:
            location:
              schema:
                type: string
              examples:
                302Sucess:
                  description: "Successful news deletion. Redirection to home page."
                  value: "/"
                302Failure:
                  description: "Failure in news deletion. Redirection to news page."
                  value: "/news/{id}"

  /api/news/update/:
    post:
      operationId: R305
      summary: "R305: Edits a news item"
      description: "Processes and edits a news item; Access: AUTH, ADM"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlenconded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                title:
                  type: string
                content:
                  type: string
                picture:
                  type: object
                id_author:
                  type: integer
              required:
                - id
                - title
                - content
                - id_author
      responses:
        "302":
          description: "Redirect after editing news item."
          headers:
            location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Successful news update. Redirection to news page."
                  value: "/news/{id}"
                302Failure:
                  description: "Failure in news update. Redirection to news page."
                  value: "/news/{id}"
  /search:
    get:
      operationId: R701
      summary: "R701: Search for news posts or users"
      description: "Search for news posts or users. Access: PUB"
      tags:
        - "M07: Search"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                query:
                  type: string
              required:
                - query
      responses:
        "302":
          description: "Redirect after processing the query."
          headers:
            Location:
              schema:
                type: string
              examples:
                302Success:
                  description: "Successful search. Redirect to search results page.[UI05]"
                  value: "/search/{query}"
                302Failure:
                  description: "Failed search. Redirect to home page."
                  value: "/"
        "400":
          description: "Bad Request"

  /following:
    get:
      operationId: R306
      summary: "R306: Show user curated news feed"
      description: "Search for news posts or users. Access: AUTH, ADM"
      tags:
        - "M03: News"
      responses:
        "200":
          description: "Ok, show curated news feed"
        "302":
          description: "User not logged in. Redirect to main feed"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to main feed."
                  value: "/"

  /about_us:
    get:
      operationId: R801
      summary: "R801: Show about us page"
      description: "Shows about us page. Access: PUB"
      tags:
        - "M08: User Administration and Static Pages"
      responses:
        "200":
          description: "Ok, show about us page"
  /rte:
    get:
      operationId: R307
      summary: "R307: Show rich text news creation page"
      description: "Shows rich text news creation page. Access: AUTH, ADM"
      tags:
        - "M03: News"
      responses:
        "200":
          description: "Ok, show rich text news create page"
        "302":
          description: "User not logged in. Redirect to login page"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"
  /rte/{id}:
    get:
      operationId: R308
      summary: "R308: Show rich text news edit page"
      description: "Shows rich text news edit page. Access: AUTH, ADM"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, show rich text news edit page"
        "302":
          description: "User not logged in. Redirect to login page"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"

  /api/delete_profile/{id}:
    post:
      operationId: R202
      summary: "R202: Deletes user account"
      description: "Deletes user account. Access: AUTH, ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, deletes user account"
        "401":
          description: "Anauthorized access"
          headers:
            Location:
              schema:
                type: string
  /api/follow:
    post:
      operationId: R203
      summary: "R202: Follows a user"
      description: "Follows a user. Access: AUTH, ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id1:
                  type: integer
                id2:
                  type: integer
              required:
                - id1
                - id2
      responses:
        "200":
          description: "Ok, Follows user"
        "401":
          description: "Anauthorized access"
          headers:
            Location:
              schema:
                type: string
  /api/unfollow:
    post:
      operationId: R204
      summary: "R204: unFollows a user"
      description: "unFollows a user. Access: AUTH, ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id1:
                  type: integer
                id2:
                  type: integer
              required:
                - id1
                - id2
      responses:
        "200":
          description: "Ok, follows user"
        "401":
          description: "Anauthorized access"
          headers:
            Location:
              schema:
                type: string
  /follow_list/{id}:
    get:
      operationId: R205
      summary: "R205: Show followed users list"
      description: "Show followed users list. Access: AUTH, ADM"
      tags:
        - "M02: Users"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, show followed users list"
        "302":
          description: "User not logged in. Redirect to login page"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"
  /api/new_comment:
    post:
      operationId: R401
      summary: "R401: Creates a comment"
      description: "Creates a comment. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id_news:
                  type: integer
                content:
                  type: string
              required:
                - id_news
                - content
      responses:
        "200":
          description: "Ok, creates comment. Refreshes news page."
        "302":
          description: "User not logged in. Redirect to login page"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"
  /api/del_comment:
    post:
      operationId: R402
      summary: "R402: Deletes a comment"
      description: "Deletes a comment. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, deletes a comment. Refreshes news page."
        "302":
          description: "User not logged in. Redirect to login page"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"
  /api/edit_comment:
    post:
      operationId: R403
      summary: "R403: Edits a comment"
      description: "Edits a comment. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                content:
                  type: string
              required:
                - id
                - content
      responses:
        "200":
          description: "Ok, edits comment. Refreshes news page."
        "302":
          description: "User not logged in. Redirect to login page"
          headers:
            Location:
              schema:
                type: string
              examples:
                302Failure:
                  description: "User not logged in. Redirect to login page."
                  value: "/login"
  /api/getReplies:
    post:
      operationId: R404
      summary: "R404: Retrieves replies to a comment."
      description: "Retrieves replies to a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                id_comment:
                  type: integer
              required:
                - id
                - id_comment
      responses:
        "200":
          description: "Ok, returns replies as JSON."
        "401":
          description: "User not logged in. Access Denied"
  /api/createReply:
    post:
      operationId: R405
      summary: "R405: Creates a reply to a comment."
      description: "Creates a reply to a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                news_id:
                  type: integer
                id_comment:
                  type: integer
              required:
                - news_id
                - id_comment
      responses:
        "200":
          description: "Ok, Reply created."
        "401":
          description: "User not logged in. Access Denied"
  /api/editReply:
    post:
      operationId: R406
      summary: "R406: Edits a reply to a comment."
      description: "Edits a reply to a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                content:
                  type: string
              required:
                - id
                - content
      responses:
        "200":
          description: "Ok, Reply Edited Successfuly."
        "401":
          description: "User not logged in. Access Denied"
  /api/delReply:
    delete:
      operationId: R407
      summary: "R407: Deletes a reply to a comment."
      description: "Deletes a reply to a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, Reply Deleted Successfuly."
        "401":
          description: "User not logged in. Access Denied"
  /api/vote/newsCreate:
    post:
      operationId: R309
      summary: "R309: Creates a vote on a news."
      description: "Creates a vote on a news with AJAX. Access: AUTH, ADM"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                is_liked:
                  type: integer
              required:
                - id
                - is_liked
      responses:
        "200":
          description: "Ok, Vote Created."
        "401":
          description: "User not logged in. Access Denied"
  /api/vote/newsUpdate:
    post:
      operationId: R310
      summary: "R310: Updates a vote on a news."
      description: "Updates a vote on a news with AJAX. Access: AUTH, ADM"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                is_liked:
                  type: integer
              required:
                - id
                - is_liked
      responses:
        "200":
          description: "Ok, Vote Updated."
        "401":
          description: "User not logged in. Access Denied"
  /api/vote/newsDelete:
    delete:
      operationId: R311
      summary: "R311: Deletes a vote on a news."
      description: "Deletes a vote on a news with AJAX. Access: AUTH, ADM"
      tags:
        - "M03: News"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, Vote Deleted."
        "401":
          description: "User not logged in. Access Denied"
  /api/vote/commentCreate:
    post:
      operationId: R408
      summary: "R408: Creates a vote on a comment."
      description: "Creates a vote on a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                is_liked:
                  type: integer
              required:
                - id
                - is_liked
      responses:
        "200":
          description: "Ok, Vote Created."
        "401":
          description: "User not logged in. Access Denied"
  /api/vote/commentUpdate:
    post:
      operationId: R409
      summary: "R409: Updates a vote on a comment."
      description: "Updates a vote on a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                is_liked:
                  type: integer
              required:
                - id
                - is_liked
      responses:
        "200":
          description: "Ok, Vote Updated."
        "401":
          description: "User not logged in. Access Denied"
  /api/vote/commentDelete:
    delete:
      operationId: R410
      summary: "R410: Deletes a vote on a comment."
      description: "Deletes a vote on a comment with AJAX. Access: AUTH, ADM"
      tags:
        - "M04: Comments"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, Vote Deleted."
        "401":
          description: "User not logged in. Access Denied"
  /api/tag/propose:
    post:
      operationId: R501
      summary: "R501: Creates a tag proposal."
      description: "Creates a tag proposal with AJAX. Access: AUTH, ADM"
      tags:
        - "M05: Tags"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                name:
                  type: string
              required:
                - name
      responses:
        "200":
          description: "Ok, Tag Proposal Created."
        "401":
          description: "User not logged in. Access Denied"
  /api/tag/create:
    post:
      operationId: R502
      summary: "R502: Creates a tag and handles the proposal."
      description: "Creates a tag and handles the proposal with AJAX. Access: AUTH, ADM"
      tags:
        - "M05: Tags"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
              required:
                - id
      responses:
        "200":
          description: "Ok, Tag Created, Proposal Handled."
        "401":
          description: "User not logged in. Access Denied"
  /recover:
    get:
      operationId: R106
      summary: "R106: Recover Password."
      description: "Allows to change your password. Access: PUB"
      tags:
        - "M01: Authentication"
      responses:
        "302":
          description: "Redirects to recover_password."
  /welcome_email:
    get:
      operationId: R107
      summary: "R107: Send Welcome Email."
      description: "Sends Welcome Email. Access: PUB"
      tags:
        - "M01: Authentication"
      responses:
        "302":
          description: "Email sent, redirect to main page."
  /recover_password:
    get:
      operationId: R108
      summary: "R108: Recover Password."
      description: "Allows to change your password. Access: PUB"
      tags:
        - "M01: Authentication"
      responses:
        "302":
          description: "Ok. Sends email and redirects to login"
  /api/sendnotifications:
    post:
      operationId: R601
      summary: "R601: Send a notification"
      description: "Sends a notification using pusher. Access: AUTH, PUB"
      tags:
        - "M06: Notifications"
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                user_id:
                  type: integer
                receiver_id:
                  type: integer
              required:
                - id
                - type
                - user_id
                - receiver_id
      responses:
        "200":
          description: "Ok, Notification Sent."
        "401":
          description: "User not logged in. Access Denied"
  /admin:
    get:
      operationId: R802
      summary: "R802: Show Admin page"
      description: "Shows the Admin page. Access: ADM"
      tags:
        - "M08: User Administration and Static Pages"
      responses:
        "302":
          description: "Sends the user to the Admin Page"

```

### 9. Implementation Details

#### 9.1. Libraries Used

 - [TinyMCE](https://www.tiny.cloud/tinymce/)
     - Used in the create and edit page for news, allows us to use a rich text editor for its content
     - Link: https://www.tiny.cloud/tinymce/
- [Pusher Notifications](https://pusher.com/)
    - Used for real time notifications
    - Link: https://pusher.com/

#### 9.2 User Stories

| US Identifier | Name    | Module | Priority                       | Team Members               | State  |
| ------------- | ------- | ------ | ------------------------------ | -------------------------- | ------ |
|  US01          | View Top News Feed | Module 3 | High | **João Teixeira**, Rui Soares   |  100%  |
|  US02          | View News Item | Module 3 | High | **João Teixeira**, Rui Soares, Lucas Sousa, André Morais                 |   100%  | 
|  US03          | Search | Module 7 | High | **João Teixeira** | 100%
|  US04          | View News Item Comments | Module B | High | **Lucas Sousa**, Rui Soares                 |   100%  | 
|  US05          | View Other Users' Profiles | Module 2 | Medium | **João Teixeira**, Rui Soares, Lucas Sousa                 |   100%  | 
|  US06          | View News Item Tag | Module 3 | Medium | **Rui Soares**, André Morais   |  100%  |
|  US07          | View Recent News Feed | Module 3 | Medium | **João Teixeira**, Rui Soares                |   100%  | 
|  US08          | About Us | Module 8 | Medium | **Rui Soares**                 |   100%  | 
|  US09          | Contacts | Module 8 | Medium | **Rui Soares** |   100%  | 
|  US10          | Sign-in | Module 1 | High | **Lucas Sousa**, João Teixeira, André Morais   |  100%  |
|  US11          | Sign-up | Module 1 | High | **André Morais**, Lucas Sousa, João Teixeira      |   100%  | 
|  US12          | Recover Password | Module 1 | Medium | **Rui Soares**, João Teixeira                 |   100%  | 
|  US13          | Create News Item | Module 3 | High | **Rui Soares**, João Teixeira, Lucas Sousa, André Morais       |   100%  | 
|  US14          | Sign-out | Module 1 | High | **João Teixeira**, Rui Soares   |  100%  |
|  US15          | Edit Profile | Module 2 | High | **André Morais**, João Teixeira                 |   100%  | 
|  US16          | View Personal Profile | Module 2 | High | **João Teixeira**, André Morais, Rui Soares                 |   100%  | 
|  US17          | View User News Feed | Module 3 | High | **Lucas Sousa**, João Teixeira    |   100%  | 
|  US18          | Create a Comment | Module 4 | Medium | **João Teixeira**, Rui Soares, Lucas Sousa   |  100%  |
|  US19          | Vote/Unvote on News Item | Module 3 | Medium | **Lucas Sousa**, Rui Soares            |   100%  | 
|  US20          | Vote/Unvote on Comment | Module 4 | Medium | **Lucas Sousa**, Rui Soares            |   100%  | 
|  US21          | Delete Account | Module 2 | Medium | **André Morais**, João Teixeira, Rui Soares                 |   100%  | 
|  US22          | Follow/Unfollow Tags | Module 5 | Medium | **André Morais**, João Teixeira   |  100%  |
|  US23          | Follow/Unfollow Users | Module 2 | Medium | **João Teixeira**, Lucas Sousa, Rui Soares                 |   100%  | 
|  US24          | Profile Picture | Module 2 | Medium | **Rui Soares**, João Teixeira                 |   100%  | 
|  US25          | Answer a Comment | Module 4 | Low | **Lucas Sousa**, Rui Soares                 |   100%  | 
|  US26          | Edit News Item | Module 3 | Medium | **Rui Soares**, João Teixeira   |  100%  |
|  US27          | Delete News Item | Module 3 | Medium | **João Teixeira**, André Morais                 |   100%  | 
|  US28          | News Vote Notification | Module 6 | Medium | **Lucas Sousa**, Rui Soares                 |   100%  | 
|  US29          | Edit Comment | Module 4 | Medium | **Lucas Sousa**, Rui Soares, André Morais                |   100%  | 
|  US30          | Delete Comment | Module 4 | Medium | **João Teixeira**, Rui Soares, Lucas Sousa  |  100%  |
|  US31          | Comment Vote Notification | Module 6 | Medium | **Lucas Sousa**, Rui Soares               |   100%  | 
|  US32          | Administer User Accounts | Module 8 | High | **João Teixeira**, Lucas Sousa, Rui Soares, André Morais     |   100%  | 
|  US33          | Delete User Accounts | Module 8 | Medium | **André Morais**, João Teixeira, Rui Soares      |   100%  | 
|  US34          | Manage Content | Module 8 | Low | **André Morais**, Lucas Sousa, Rui Soares, João Teixeira   |  100%  |
|  US35          | Manage Tags Proposals | Module 8 | Low | **João Teixeira**, Lucas Sousa, André Morais                 |   100%  | 


---


## A10: Presentation
 

### 1. Product presentation

Super Legit Collaborative News(SLCN) is a collaborative news website, where users can create, view, rate news and comments on those news. It features top, recent and curated news feeds, aswell as search options for news, users and tags. Speaking of tags, users can follow tags and propose new ones. 

Users have access to a profile, housing their public, editable information, aswell as their posts and reputation. Reputation is the sum of the votes from their news and comments. Everytime another user likes their news or comments, they get a realtime popup notification.

Finally administrators can edit and delete any news, comment or profile, and have access to an admin page where they can manage the proposed tags.

URL to the product: http://lbaw2286.lbaw.fe.up.pt

### 2. Video presentation

https://git.fe.up.pt/lbaw/lbaw2223/lbaw2286/-/blob/main/docs/lbaw2286.mp4

![](https://i.imgur.com/WlGtl4a.jpg)

## Revision history

Changes made to the first submission:
- Changed content of news to rich text

***
GROUP2286, 03/01/2023

- André Morais, up202005303@edu.fe.up.pt (editor)
- João Teixeira, up202005437@edu.fe.up.pt 
- Lucas Sousa, up202004682@edu.fe.up.pt
- Rui Soares, up202103631@edu.fe.up.pt