# 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