Blog - COS-301/graduates GitHub Wiki
The feature we are developing for the graduate's website is a blog that will allow the University of Pretoria’s (UP) administration to publish information about the graduates, such as articles, information about the capstone project, demo day, marketing material etc. The goal of this feature is to provide a centralized source of information, about the university’s graduates, to encourage potential employers to employ UP graduates.
- Estian Nel (u20427736)
-Project Manager - Ryan Healy (u20662302)
-API Engineer
-Service/Backend Engineer - Yaasir Barmania (u20448474)
-Data Engineer - Regan Shen (u20460067)
-Developer Operations
-Tester - Juwairiah Carrim (u20435780)
-Business Analyst - Mumtaz Malik (u20486783)
-Designer - Dylan Spies (u20432748)
-UI Engineer - Moloko Magwai (u18350110)
- FR1: Only admin can post and edit blogs. Must be viewable to anyone.
- FR2: There should be an option to upload either a visual (pictures and videos) or textual story (with formatting-font, size, colour, bold, italics etc.). Also allow links to websites.
- FR3: Blog will have its own page on the website, with a separate page for admin (UP staff only) and one for viewing (general users).
- FR4: The users should be able to comment and react to blogs. Previous blog posts should be viewable.
- FR5: Content should be provided via an API as a “headless” content management system.
- NFR1: When UP staff log in, they can access the blog page as admins and edit it and delete comments too. General users will not have access to this, they can only view the blog page.
- NFR2: Blogs can be sorted starting with the most recently uploaded. Scroll to see previous blog posts.
- NFR3: A user should be able to see when another blog was last posted more specifically the time and date.
Introduction This document describes the database used to store the content of the blog feature. This is an updated version of the document from sprint 1. This document contains the changes made during sprint 2.
Database relations for the blog:
User Table
Field Name | Description | Datatype |
---|---|---|
user_id | Primary key to identify each user | String(cuid) |
blog Table
Description: Stores the data of blog posts.
Description of fields:
Field Name | Description | Datatype |
---|---|---|
blog_id | Primary key. Unique ID to indentify the blog post | String (cuid) |
user_id | Foreign key from user table. Unique ID to identify the author of the post | String |
title | The post title to be displayed when viewing | String |
content | The post data | String? |
date | Stores the date and time at which the blog post was created | DateTime |
archived | Indicates whether the post has been archived. Only non-archived blog posts are displayed | Boolean |
blog_comment Table
Description: Stores the data of comments made on blog posts.
Description of fields:
Field Name | Description | Datatype |
---|---|---|
comment_id | Primary Key. Unique ID to identify the comment | String (cuid) |
blog_id | Foreign key from blog table. Used to identify which blog the comment is posted on | String |
user_id | Foreign key from user table. Used to identify which user posted the comment | String |
content | The comment data | String |
date | Stores the date and time at which the comment was created | DateTime |
blog_media Table
Description: Stores information regarding the media used in blog posts.
Description of fields:
Field Name | Description | Datatype |
---|---|---|
blog_id | Partial Key. Foreign key from blog table. Used to identify which blog the media is used on | String |
media | Partial Key. Identifies the filename of the media | String |
Permissions:
Types of users: Admin Student Company
User Permissions:
All permissions will not be accessible by all users. Specific users will be given different permissions. Any user will be allowed to view and comment on any blog post.
Admin permissions:
POST_BLOG_ADMIN: to put a blog post to the blog page. EDIT_BLOG_ADMIN: to edit a blog post on the blog page. REMOVE_BLOG_ADMIN: to remove a blog post from the blog page Only admins will be allowed to post, edit, and remove a blog.
Student and Company Permissions:
Both students and companies will however be allowed to comment on any blog. No specific permissions are required for this. Comments will be limited to text. They will not be limited to the number of comments they can post. They however will not be allowed to post, edit, or remove a blog post.
Future features:
Tags could be added to each blog post. They could be a way for students or companies to post a blog, but it should first be checked by admin/UP staff before being made public. If they approve it, then it goes live otherwise it is removed.
Description of Code:
api/blog/api/shared/entities/data-access/src/lib : • api-blog-entity.entity.ts : We define the blog as an object type. All the blog fields are also added. We also add the field for the BlogMedia and BlogComments that are related to that blog • api-blog-comment-entity.entity.ts : We define the blogComment as an object type. All the blogComment fields are also added. We also add the blogComment foreign key which is the blogid. This allows each comment to be linked to a blog • api-blog-media-entity.entity.ts : We define the blogMedia as an object type. All the blogMedia fields are also added. We also add the blogMedia foreign key which is the blogid.
The data-access files were also generated. This is where the api and related files are stored.
schema.prisma This is where the schema for each table is stored. Tables are linked with each other through foreign keys. The blog table has the user_id as a foreign key so that it links to the user table This allows us to see which user uploaded a specific blog. BlogComment has blog_id and user_id as foreign keys so that each comment can be linked to a specific blog and linked to which user posted that comment. BlogMedia has blog_id as a foreign key so that each media can be linked to the blog that its found on
The service layer exports a BlogService class which consists of a command bus, a query bus, and a function for each operation that can be performed on the repository. These operations are defined as queries if they do not modify the repository, or commands if they do. Each query and command is defined in its own class and each of these classes has a corresponding handler class. When a function in BlogService is called, an object of the appropriate query/command class is instantiated and sent to either the query bus or the command bus to be executed. The query/command bus invokes the handler corresponding to the object it is given, which will then execute the appropriate query/command on the repository.
Function Call | Passed Values | Expected Result |
---|---|---|
blogById | blogId: string | Blog | null |
allBlogs | Blog[] | null | |
allArchivedBlogs | Blog[] | null | |
blogByUserId | userId: string | Blog[] | null |
allComments | BlogComment[] | null | |
commentsByBlogId | blogId: string | BlogComment[] | null |
commentsByCommentId | commentId: string | BlogComment | null |
nameByUserId | userId: string | User | null |
mediaByBlogId | blogId: string | BlogMedia[] | null |
createBlog | title : string content : string archived : boolean userId : string |
Blog |
updateBlogTitle | blogId : string title : string |
Blog | null |
updateBlogContent | blogId : string content : string |
Blog | null |
updateBlogArchived | blogId : string archived : boolean |
Blog | null |
deleteBlog | blogId : string | status: string |
createComment | blogId : string userId : string content : string |
BlogComment | null |
updateComment | commentId : string commentContent : string |
status: string |
deleteComment | commentId : string | status: string |
deleteCommentsByBlogId | blogId : string | status: string |
createMedia | blogId : string media : string |
BlogMedia | null |
The API instantiates a BlogService object (described above) in its constructor. Each endpoint in the API executes its corresponding function in the BlogService object and returns the result.
Designs and description of designs here
Web Design:
Mobile:
I have made the mock-up for our feature using the U.I kit designed by the U.I kit team. Students and companies will be able to view the UP student blog.
The page that they will see first will contain cards of all the blog posts, this is so they can get a quick rundown of what the blog has to offer, there is also a button placed on these cards if they are interested in reading that blog post. Students/companies will be able to view these posts as cards with the option of sorting the posts how they would like (oldest first, newest first) using a drop-down menu. After choosing to view a post, the students/companies will also be given the opportunity to write their comment in the textbox provided below the blog post, with a “post” button to publish the comment on the post. The user with special permissions will be able to see the “Editor” button located near the navigation bar. Once they click on this button, they will be able to view the “UP Student Blog editor” page. They will be able to view a textbox with options to change the text’s font, font colour, font size as drop-down menus. They can also change the text to bold text, italics as well as change the alignment of the text with provided buttons. They can also upload images or links using the provided button and then publish the post using the provided “Post” button on the lower right corner of the textbox or cancel this by clicking on the provided “Cancel” button. They will be able to view the posts as cards and be able to sort it as the viewers can with a drop-down menu. Three buttons will be on each card, a button to edit the post, Delete the post and view the post. If the admin chooses to edit the post, the post will open in the textbox to allow the admin to edit the post and update it. If the admin choses to delete the post, the post will be deleted. If the admin chooses to view the post, they will be able to view the post as well as the comments, along with the ability to delete the comments, with the trash can button placed next to each comment. The layout is simple and easy for any user to navigate.
The UI was implemented using Angular with SCSS. The UI connects through the database using the API in the form Apollo queries and mutations. This makes it easy to fetch and send data to the database. The implementation also makes it mobile friendly as it is all scalable to the screen size and makes use of wrapping. All this is done and then displayed to the user using HTML
Each function below is implemented in their respective .js file
Function | Page | Description |
---|---|---|
ngOnInit() | Blog Create | Gets parameters from URL and calls displayBlog(param) |
cancel() | Blog Create | Return to Blog Explore |
displayBlog(blogID: string) | Blog Create | Populate fields with blog to edit using blogId |
post() | Blog Create | Update/Create a blog using the data retrieved from the input fields |
loadGrid() | Blog Explore | Creates grid for cards containing the blogs to load into |
ngOnInit() | Blog Explore | Calls loadBlogs |
createBlog() | Blog Explore | Opens a Create Blog page |
readBlog(blogID: string) | Blog Explore | Opens a View Blog page with current blog loaded |
editBlog(blogID: string) | Blog Explore | Opens a Create/Edit Blog page with current blog loaded |
deleteBlog(blogID: string) | Blog Explore | Deletes the comments for the blog and then the blog itself from the database |
newestFirst() | Blog Explore | Sorts blogs by newest first |
oldestFirst() | Blog Explore | Sorts blogs by oldest first |
changeAdmin() | Blog Explore | Switches to admin mode |
loadBlogs() | Blog Explore | Load in all the blogs from the database |
ngOnInit() | Blog View | Gets parameters from URL and calls displayBlog(param) as well as comments |
displayBlog(blogID: string) | Blog View | Displays all the blog details for the given blogId |
diplayComments() | Blog View | Displays all the blog comments for the given blogId |
return() | Blog View | Return to Blog Explore |
post() | Blog View | Creates a comment for the blog using the values from the input |
PR884-1
PR Number: 884
Commit Hash: bab90a2771ff358a4ec53612a2d640021dd5e150
Status: Passed
Date: 2022/04/16
Tester(s): Regan Shen
Developer(s): Ryan Healy
Description: The implementation of the api-blog-service.service test. Passed 25 out of the 25 Tests
PR884-2
PR Number: 884
Commit Hash: d6767efef2a99851feaaf6130fb8d3ce48127579
Status: Passed
Date: 2022/04/16
Tester(s): Regan Shen
Developer(s): Ryan Healy / Estian Nel
Description: The implementation of the api-blog-repository.repository test. Passed 29 out of the 29 Tests
PR893
PR Number: 893
Commit Hash: 42b9c8b976446fa934cd1eb2852471f2f401d92e
Status: Passed
Date: 2022/04/16
Tester(s): Regan Shen
Developer(s): Ryan Healy / Estian Nel
Description: The implementation of the api-blog-resolver.resolver test and a update to the api-blog-service.service test. Passed 33 out of the 33
Tests for api-blog-resolver.resolver
PR985
PR Number: 958
Commit Hash: 0d1ffe966b41b244b7efe8f08207b10706bad4d9
Status: Passed
Date: 2022/04/17
Tester(s): Regan Shen
Developer(s): Ryan Healy / Estian Nel
Description: The implementation of the api-blog-repository.repository test. 29 tests passed out of the 29 tests. Update to the comment-entity
code after it failed a test, now comment-entity is successful.
PR1044
PR Number: 1044
Commit Hash: 3bc6bde59ae2d62e3e1be4b182409fe91cb96bcf
Status: Passed
Date: 2022/04/18
Tester(s): Regan Shen
Developer(s): Dylan Spies
Description: The implementation of the client-blog-create.component, client-blog-explore.component, client-blog-view..component and client-blog-
feature.module tests was completed. All the tests were passed.
Uploading and managing media for each blog
Deleting/Managing comments
Usernames for comments and blogs
Integration with authentication to check if user is admin
For the media you will need to check with storing media for each blog using the database. Also load the content as html code. This will allow you to add images within the content.
A user must be able to edit their own comments. And if user is an admin they should be able to edit/delete all comments. Using/Adding the needed API/Service calls will let you do this. Some functions already exist but will need to be implemented properly.
Our getUserById did not work since the authentication team changed it from User to AuthenticatedUser
This will need to be done in the client folders. Check if the current logged in user has the correct permissions to edit blogs. If they do you show the content that the "Admin" button is showing. We added an Admin button since the authentication was not done yet.