{"info":{"_postman_id":"00c0689b-beae-4a39-8929-4059abee70ee","name":"scriptorium backend","description":"<html><head></head><body><p>Author: Kevin Le 1007952805</p>\n<p>To first introduce the context of the app, it is a blog post platform that allows users to share code and run code all in one app. This is the documentation for the backend server of the app.</p>\n<h1 id=\"getting-started\">Getting Started</h1>\n<p>IMPORTANT NOTE: - please read the directories of each endpoint section as it will help explain some prerequisites, order of execution for requests etc.</p>\n<h3 id=\"pre-reqs\">Pre-reqs:</h3>\n<p>Please ensure you have ran the <code>./startup.sh</code> to set up a fresh new environment with fresh data and an admin account. After so, run <code>./run.sh</code> to start up the backend server to start calling the endpoints.</p>\n<p>If you run into permission issues running the scripts please run the following command: <code>chmod +x ./startup.sh ./run.sh</code></p>\n<h3 id=\"admin-account\">Admin Account:</h3>\n<p>Below is the admin account that should have been generated / created upon running the <code>./startup.sh</code> script. Just for reference and whenever needed - but there is already a <code>login admin</code> postman request under the <code>auth directory</code> that has prefilled the admin data for you to just login as an admin.</p>\n<ul>\n<li><p>email: <a href=\"https://mailto:admin@gmail.com\">admin@gmail.com</a></p>\n</li>\n<li><p>password: 12345</p>\n</li>\n</ul>\n<h3 id=\"first-steps\">First Steps:</h3>\n<ul>\n<li><p><a href=\"http://localhost:3000\">First, the postman collection assumes that the baseUrl is <code>http://localhost:3000</code></a> . If it is different, feel free to change the <code>baseUrl</code> environment variable of the postman collection to the your baseUrl. Make sure it is the <code>environment</code> variables.</p>\n</li>\n<li><p>Next, please head to the live folder to ensure that the app is running. This is just a health check endpoint to ensure that everything is up and running.</p>\n</li>\n<li><p>Next, head over to the auth folder where you can start logging in/ registering new users to initialize postman environment variables that will be propped to the other endpoint folders.</p>\n<ul>\n<li><p>Register the user register user , there is already data there for you to register immediately.</p>\n</li>\n<li><p>The creds of the user email and passwordwill automatically be passed into the login user postman request</p>\n</li>\n<li><p>There is also a login admin request that prefills the admin creds to log in with the user.</p>\n</li>\n<li><p>Important Note: the tokens are set to expire in a 24h window for both access and login</p>\n</li>\n</ul>\n</li>\n<li><p>This is a good chance to try out the logout request and refresh request features</p>\n</li>\n</ul>\n<p>With these, now you can navigate to specific directories with more information of the different endpoints. Again, please refer to the respective directory documentation for more information about order of execution and such.</p>\n<p>However, the order of execution should be top to bottom respective in context of the requests with in the level of the directory.</p>\n<h1 id=\"data-models\">Data Models</h1>\n<p>Here is a database diagram showcasing the database tables and its relation, below will be a brief outline and explanation of each one. Here is the link: <a href=\"https://dbdiagram.io/d/scriptorium-backend-db-diagram-6727b01fb1b39dd858520245\">https://dbdiagram.io/d/scriptorium-backend-db-diagram-6727b01fb1b39dd858520245</a></p>\n<img src=\"https://content.pstmn.io/24b32aab-0029-4306-a15f-b40210a38ec0/VW50aXRsZWQucG5n\">\n\n<p>Here is a brief skim of the database models that helps orchestrate all the endpoints together.</p>\n<h3 id=\"1-user\">1. User</h3>\n<p>This is the user table that stores all information relating to the user.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>email (String): Unique email identifier for each user. (this is encrpyed in db)</p>\n</li>\n<li><p>password (String): Hashed password for authentication.</p>\n</li>\n<li><p>firstName (String): User's first name.</p>\n</li>\n<li><p>lastName (String): User's last name.</p>\n</li>\n<li><p>avatar (String?): Optional URL to the user's profile image.</p>\n</li>\n<li><p>phone (String): Contact phone number.</p>\n</li>\n<li><p>role (String): Role of the user, default is \"user\".</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>codeTemplates (CodeTemplate[]): Code templates created by the user.</p>\n</li>\n<li><p>blogs (BlogPost[]): Blog posts created by the user.</p>\n</li>\n<li><p>comments (Comment[]): Comments created by the user.</p>\n</li>\n<li><p>reports (Report[]): Reports created by the user.</p>\n</li>\n<li><p>votes (Vote[]): Votes cast by the user.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"2-codetemplate\">2. CodeTemplate</h3>\n<p>This is a saved code template that a user would have saved or forked.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>title (String): Title of the code template.</p>\n</li>\n<li><p>code (String): The code content.</p>\n</li>\n<li><p>language (String): Programming language of the code.</p>\n</li>\n<li><p>explanation (String?): Optional explanation or documentation for the code.</p>\n</li>\n<li><p>userId (Int): Foreign key linking to the user who created the template.</p>\n</li>\n<li><p>createdAt (DateTime): Timestamp when the template was created.</p>\n</li>\n<li><p>updatedAt (DateTime): Timestamp when the template was last updated.</p>\n</li>\n<li><p>parentTemplateId (Int?): Optional ID of the parent template if the code is a fork.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>user (User): The user who created the template.</p>\n</li>\n<li><p>tags (CodeTemplateTag[]): Tags associated with the template.</p>\n</li>\n<li><p>blogPosts (BlogPostCodeTemplate[]): Blog posts associated with the template.</p>\n</li>\n<li><p>forkedTemplates (CodeTemplate[]): Templates forked from this template.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"3-blogpost\">3. BlogPost</h3>\n<p>This is a blog post by a certain user that can be hidden.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>title (String): Title of the blog post.</p>\n</li>\n<li><p>description (String): Short description or excerpt.</p>\n</li>\n<li><p>content (String): Full content of the blog post.</p>\n</li>\n<li><p>userId (Int): Foreign key linking to the author.</p>\n</li>\n<li><p>createdAt (DateTime): Timestamp when the post was created.</p>\n</li>\n<li><p>updatedAt (DateTime): Timestamp when the post was last updated.</p>\n</li>\n<li><p>hidden (Boolean): Flag indicating if the post is hidden due to reports or moderation.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>user (User): The author of the blog post.</p>\n</li>\n<li><p>tags (BlogPostTag[]): Tags associated with the blog post.</p>\n</li>\n<li><p>codeTemplates (BlogPostCodeTemplate[]): Code templates linked to this post.</p>\n</li>\n<li><p>comments (Comment[]): Comments on this post.</p>\n</li>\n<li><p>votes (Vote[]): Votes on this post.</p>\n</li>\n<li><p>report (Report[]): Reports filed against the post.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"4-blogpostcodetemplate-relationship-table\">4. BlogPostCodeTemplate (Relationship Table)</h3>\n<p>To associate a relationship between blog post and code template, this table is created for blogposts to be able to easily fetch the code templates relating to the blog post (attached within the post)</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>blogPostId (Int): Foreign key linking to the blog post.</p>\n</li>\n<li><p>codeTemplateId (Int): Foreign key linking to the code template.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>blogPost (BlogPost): The blog post associated with the template.</p>\n</li>\n<li><p>codeTemplate (CodeTemplate): The code template associated with the blog post.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"5-comment\">5. Comment</h3>\n<p>This table is for commenting. It can either be a comment to a blog post or a comment to another comment (i.e a reply). This can also be hidden as well.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>content (String): Text content of the comment.</p>\n</li>\n<li><p>userId (Int): Foreign key linking to the author of the comment.</p>\n</li>\n<li><p>blogPostId (Int?): Foreign key linking to the blog post, if the comment is on a post.</p>\n</li>\n<li><p>parentId (Int?): Foreign key linking to the parent comment, if it is a reply.</p>\n</li>\n<li><p>createdAt (DateTime): Timestamp when the comment was created.</p>\n</li>\n<li><p>hidden (Boolean): Flag indicating if the comment is hidden due to reports or moderation.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>user (User): The author of the comment.</p>\n</li>\n<li><p>blogPost (BlogPost?): The blog post associated with the comment, if applicable.</p>\n</li>\n<li><p>parent (Comment?): The parent comment if it is a reply.</p>\n</li>\n<li><p>replies (Comment[]): Replies to the comment.</p>\n</li>\n<li><p>votes (Vote[]): Votes on this comment.</p>\n</li>\n<li><p>reports (Report[]): Reports filed against the comment.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"6-report\">6. Report</h3>\n<p>This is a report table that stores all reports for blog posts or comments.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>reason (String): Reason for reporting the content.</p>\n</li>\n<li><p>userId (Int): Foreign key linking to the user who reported the content.</p>\n</li>\n<li><p>blogPostId (Int?): Foreign key linking to the blog post if it was reported.</p>\n</li>\n<li><p>commentId (Int?): Foreign key linking to the comment if it was reported.</p>\n</li>\n<li><p>createdAt (DateTime): Timestamp when the report was created.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>user (User): The user who reported the content.</p>\n</li>\n<li><p>blogPost (BlogPost?): The blog post being reported, if applicable.</p>\n</li>\n<li><p>comment (Comment?): The comment being reported, if applicable.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"7-tag\">7. Tag</h3>\n<p>This is a generic tag table that stores a unique tag by its name.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>name (String): Unique name of the tag.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>codeTags (CodeTemplateTag[]): Tags associated with code templates.</p>\n</li>\n<li><p>blogTags (BlogPostTag[]): Tags associated with blog posts.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"8-codetemplatetag-relationship-table\">8. CodeTemplateTag (Relationship Table)</h3>\n<p>Using the Tag table, this table helps declare a relationship / tag with a code template.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>codeTemplateId (Int): Foreign key linking to the code template.</p>\n</li>\n<li><p>tagId (Int): Foreign key linking to the tag.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>codeTemplate (CodeTemplate): The code template associated with the tag.</p>\n</li>\n<li><p>tag (Tag): The tag associated with the code template.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"9-blogposttag-relationship-table\">9. BlogPostTag (Relationship Table)</h3>\n<p>Using the Tag table, this table helps declare a relationship / tag with a blog post.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>blogPostId (Int): Foreign key linking to the blog post.</p>\n</li>\n<li><p>tagId (Int): Foreign key linking to the tag.</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>blogPost (BlogPost): The blog post associated with the tag.</p>\n</li>\n<li><p>tag (Tag): The tag associated with the blog post.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"10-vote\">10. Vote</h3>\n<p>This table stores a certain vote that a user has invoked on a blog post or comment. UP or DOWN.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>userId (Int): Foreign key linking to the user who cast the vote.</p>\n</li>\n<li><p>blogPostId (Int?): Foreign key linking to the blog post, if applicable.</p>\n</li>\n<li><p>commentId (Int?): Foreign key linking to the comment, if applicable.</p>\n</li>\n<li><p>voteType (String): Type of vote (UP or DOWN).</p>\n</li>\n</ul>\n</li>\n<li><p>Relationships:</p>\n<ul>\n<li><p>user (User): The user who cast the vote.</p>\n</li>\n<li><p>blogPost (BlogPost?): The blog post associated with the vote.</p>\n</li>\n<li><p>comment (Comment?): The comment associated with the vote.</p>\n</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"11-revokedtoken\">11. RevokedToken</h3>\n<p>This table is used to store all revoked tokens when the user logs out so that they can't use the same token to log back in again or else the backend server will know and decline access the respective endpoint.</p>\n<ul>\n<li><p>Fields:</p>\n<ul>\n<li><p>id (Int): Primary key, automatically increments.</p>\n</li>\n<li><p>token (String): Unique identifier for the revoked token.</p>\n</li>\n<li><p>tokenType (String): Type of token (e.g., \"access\" or \"refresh\").</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>createdAt (DateTime): Timestamp when the token was revoked.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[{"content":"Getting Started","slug":"getting-started"},{"content":"Data Models","slug":"data-models"}],"owner":"30523314","collectionId":"00c0689b-beae-4a39-8929-4059abee70ee","publishedId":"2sAY4x9LpN","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2024-11-01T09:44:40.000Z"},"item":[{"name":"live","item":[{"name":"health check","id":"1ed08fe6-642b-4404-8c2f-e0aebf3998a3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:3000/api/live","description":"<p>This endpoint is a health check to indicate if the server is running and up. It makes an HTTP GET request to <a href=\"http://localhost:3000/api/live\">http://localhost:3000/api/live</a> and returns a status code of 200 with a JSON response containing a message field.</p>\n","urlObject":{"path":["api","live"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"1ed08fe6-642b-4404-8c2f-e0aebf3998a3"}],"id":"34c94b2e-1a85-40f9-a916-9174d962693e","description":"<p>First let's make sure that the server is running properly. This \"live\" endpoint does a basic ping to ensure that the server is running.</p>\n","_postman_id":"34c94b2e-1a85-40f9-a916-9174d962693e"},{"name":"auth","item":[{"name":"register user","event":[{"listen":"test","script":{"id":"a77fff7e-eff5-481a-b333-3c77aa551408","exec":["","const requestString= pm.request.body.raw","const requestBody = JSON.parse(requestString)","","pm.test(requestBody.email)","pm.test(requestBody.password)","","pm.environment.set(\"userEmail\", String(requestBody.email));","pm.environment.set(\"userPassword\", String(requestBody.password));","","const response = pm.response.json();","","pm.test(response.user.id)","pm.environment.set(\"userId\", response.user.id);"],"type":"text/javascript","packages":{}}}],"id":"16d4587e-7d72-4c56-bf76-f0d1e104d029","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"user@gmail.com\",\n    \"phone\": \"+16479903830\",\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"password\": \"12345\",\n    \"role\": \"user\",\n    \"avatar\": \"https://example.com/avatar.png\"\n}\n","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/users/register","description":"<p>Registers a new user, supporting both user and admin roles</p>\n<p>{<br />\"email\": \"<a href=\"mailto:user@example.com\">user@example.com</a>\",<br />\"phone\": \"+123456789\",<br />\"firstName\": \"John\",<br />\"lastName\": \"Doe\",<br />\"password\": \"your_password\",<br />\"role\": \"user\",<br />\"avatar\": \"<a href=\"https://example.com/avatar.png\">https://example.com/avatar.png</a>\"<br />}</p>\n<p><strong>Required Fields</strong>: <code>email</code>, <code>phone</code>, <code>firstName</code>, <code>lastName</code>, <code>password</code>, <code>role</code></p>\n<p><strong>Optional Field</strong>: <code>avatar</code></p>\n<p>{<br />\"message\": \"User registered successfully\",<br />\"user\": {<br />\"id\": 1,<br />\"email\": \"<a href=\"mailto:user@example.com\">user@example.com</a>\",<br />\"phone\": \"+123456789\",<br />\"firstName\": \"John\",<br />\"lastName\": \"Doe\",<br />\"avatar\": \"<a href=\"https://example.com/avatar.png\">https://example.com/avatar.png</a>\"<br />}<br />}</p>\n","urlObject":{"path":["api","users","register"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"16d4587e-7d72-4c56-bf76-f0d1e104d029"},{"name":"login user","event":[{"listen":"test","script":{"id":"e710d146-0e33-4827-b12c-2487f152d35b","exec":["const responseJson = pm.response.json();","","pm.environment.set(\"accessToken\", responseJson[\"accessToken\"]);","pm.environment.set(\"refreshToken\", responseJson[\"refreshToken\"]);","","const response = pm.response.json();","","pm.test(response.user.id)","pm.environment.set(\"userId\", response.user.id);"],"type":"text/javascript","packages":{}}}],"id":"d3d1bd1c-e7b1-4910-b4a3-004d5f8745df","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"\",\n    \"password\": \"\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/users/login","description":"<p>Authenticates a user and returns access and refresh tokens if credentials are valid.</p>\n<p><strong>Required Fields</strong>: <code>email</code>, <code>password</code></p>\n<p>returns:</p>\n<p>{<br />\"accessToken\": \"your_access_token\",<br />\"refreshToken\": \"your_refresh_token\",<br />\"user\": {<br />\"id\": 1,<br />\"email\": \"<a href=\"mailto:user@example.com\">user@example.com</a>\",<br />\"phone\": \"+123456789\",<br />\"firstName\": \"John\",<br />\"lastName\": \"Doe\",<br />\"avatar\": \"<a href=\"https://example.com/avatar.png\">https://example.com/avatar.png</a>\",<br />\"role\": \"user\"<br />}<br />}</p>\n","urlObject":{"path":["api","users","login"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"d3d1bd1c-e7b1-4910-b4a3-004d5f8745df"},{"name":"login admin","event":[{"listen":"test","script":{"id":"e710d146-0e33-4827-b12c-2487f152d35b","exec":["const responseJson = pm.response.json();","","pm.environment.set(\"accessToken\", responseJson.accessToken);","pm.environment.set(\"refreshToken\", responseJson.refreshToken);","pm.environment.set(\"userId\", responseJson.user.id);"],"type":"text/javascript","packages":{}}},{"listen":"prerequest","script":{"id":"23eeedf7-d223-490d-96c7-1849bb55a96d","exec":["pm.environment.set(\"adminEmail\", \"admin@gmail.com\");","pm.environment.set(\"addminPassword\", \"12345\");"],"type":"text/javascript","packages":{}}}],"id":"12415ba3-a207-40f2-9837-cfd220471065","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"admin@gmail.com\",\n    \"password\": \"12345\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/users/login","description":"<p>same as <code>login user</code> but here to login to admin user to test admin operations later on (down below in <code>admin</code> directory)</p>\n","urlObject":{"path":["api","users","login"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"12415ba3-a207-40f2-9837-cfd220471065"},{"name":"refresh","event":[{"listen":"test","script":{"id":"1f844c48-4439-41c8-8c4f-13b44a7d8e01","exec":["const responseJson = pm.response.json();","","pm.environment.set(\"accessToken\", responseJson[\"accessToken\"]);","pm.environment.set(\"refreshToken\", responseJson[\"refreshToken\"]);"],"type":"text/javascript","packages":{}}}],"id":"d35e06d2-7dda-434c-b4a3-a084bb0acbd0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"refreshToken\": \"{{refreshToken}}\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/users/refresh","description":"<p>Refreshes the access token using a valid, non-revoked refresh token. If the refresh token is not revoked and valid, new tokens are issued</p>\n<p><strong>Required Field</strong>: <code>refreshToken</code></p>\n<p>returns</p>\n<p>{<br />\"accessToken\": \"new_access_token\",<br />\"refreshToken\": \"new_refresh_token\"<br />}</p>\n","urlObject":{"path":["api","users","refresh"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"d35e06d2-7dda-434c-b4a3-a084bb0acbd0"},{"name":"logout","event":[{"listen":"test","script":{"id":"37b8fa67-bf7a-4264-8d95-7735cd477365","exec":["// pm.environment.set(\"accessToken\", undefined);","// pm.environment.set(\"refreshToken\", undefined);"],"type":"text/javascript","packages":{}}}],"id":"01d085d7-4d2f-4120-9b57-5ee0763cba4e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Authorization","value":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsImVtYWlsIjoia2V2aW5AZ21haWwuY29tIiwicm9sZSI6InVzZXIiLCJpYXQiOjE3MzAzNDIwNDQsImV4cCI6MTczMDM0NTY0NH0.Wsl8Zvgioc4-2vOyjhaAXnXoslVQyRVEY5oaE0AWeAA","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"refreshToken\": \"{{refreshToken}}\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/users/logout","description":"<p>Logs out the user by revoking both the access token provided in the request headers and the refresh token in the request body.</p>\n<p><strong>Headers</strong></p>\n<ul>\n<li><code>Authorization</code>: <code>Bearer</code></li>\n</ul>\n<p>Body:</p>\n<p><strong>Required Field</strong>: <code>refreshToken</code></p>\n<p>returns</p>\n<p>{<br />\"message\": \"Logged out successfully\"<br />}</p>\n","urlObject":{"path":["api","users","logout"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"01d085d7-4d2f-4120-9b57-5ee0763cba4e"}],"id":"e6a815bd-d823-43a4-aa71-e5088a1a3a35","description":"<p>This directory holds all endpoints relating to authentication and authorization. The <code>login user</code> and <code>login admin</code> is recommended to be ran before going to other directories to automatically associate environment <code>accessToken</code> and <code>refreshToken</code> variables that will use in other requests in other directories.</p>\n","_postman_id":"e6a815bd-d823-43a4-aa71-e5088a1a3a35"},{"name":"users","item":[{"name":"get user profile","id":"05be77d9-af5e-4e28-b0e5-15788ac0f377","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[{"key":"Authorization","value":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsImVtYWlsIjoia2V2aW5AZ21haWwuY29tIiwicm9sZSI6InVzZXIiLCJpYXQiOjE3MzAzNDI2ODYsImV4cCI6MTczMDM0NjI4Nn0.HDcN1URgh3LI7swbCe3VP4etfgQAWLyw8d436dfopK0","type":"text"}],"url":"http://localhost:3000/api/users/{{userId}}","description":"<p>Fetches the user profile by ID. This endpoint performs an identity check by matching the <code>idToken</code> in the request headers with the user ID in the path. If the IDs do not match, access is denied.</p>\n<h4 id=\"request\">Request</h4>\n<ul>\n<li><p><strong>Headers</strong></p>\n<ul>\n<li><code>Authorization</code>: <code>Bearer</code></li>\n</ul>\n</li>\n<li><p><strong>Path Parameters</strong></p>\n<ul>\n<li><code>id</code>: The ID of the user to fetch.</li>\n</ul>\n</li>\n</ul>\n<p>returns</p>\n<p>{<br />\"message\": \"User fetched successfully\",<br />\"user\": {<br />\"id\": 1,<br />\"email\": \"<a href=\"mailto:user@example.com\">user@example.com</a>\",<br />\"phone\": \"+123456789\",<br />\"firstName\": \"John\",<br />\"lastName\": \"Doe\",<br />\"avatar\": \"<a href=\"https://example.com/avatar.png\">https://example.com/avatar.png</a>\"<br />}<br />}</p>\n","urlObject":{"path":["api","users","{{userId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"05be77d9-af5e-4e28-b0e5-15788ac0f377"},{"name":"update user","id":"bc3cfbd1-30c3-4619-b39e-d7b195679e55","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"","value":"","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"firstName\": \"Newname2\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/users/{{userId}}","description":"<p>Updates the user's profile details based on provided fields. This endpoint also performs an identity check by matching the <code>idToken</code> in the request headers with the user ID in the path, ensuring only the respective user can modify their data.</p>\n<h4 id=\"request\">Request</h4>\n<ul>\n<li><p><strong>Headers</strong></p>\n<ul>\n<li><code>Authorization</code>: <code>Bearer</code></li>\n</ul>\n</li>\n<li><p><strong>Path Parameters</strong></p>\n<ul>\n<li><code>id</code>: The ID of the user to update.</li>\n</ul>\n</li>\n<li><p><strong>Body Parameters</strong> (at least one field is required)</p>\n<ul>\n<li><p><code>email</code> <em>(optional)</em>: Updated email address.</p>\n</li>\n<li><p><code>phone</code> <em>(optional)</em>: Updated phone number.</p>\n</li>\n<li><p><code>firstName</code> <em>(optional)</em>: Updated first name.</p>\n</li>\n<li><p><code>lastName</code> <em>(optional)</em>: Updated last name.</p>\n</li>\n<li><p><code>avatar</code> <em>(optional)</em>: Updated avatar URL.</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>returns</p>\n<p>{<br />\"message\": \"User updated successfully\",<br />\"user\": {<br />\"id\": 1,<br />\"email\": \"<a href=\"mailto:updated@example.com\">updated@example.com</a>\",<br />\"phone\": \"+123456789\",<br />\"firstName\": \"John\",<br />\"lastName\": \"Doe\",<br />\"avatar\": \"<a href=\"https://example.com/new-avatar.png\">https://example.com/new-avatar.png</a>\"<br />}<br />}</p>\n","urlObject":{"path":["api","users","{{userId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"bc3cfbd1-30c3-4619-b39e-d7b195679e55"}],"id":"99fa0e46-cc55-4894-ba17-840bf5e6b89c","description":"<p>Before trying requests in this user folder, make sure you have ran any of the login requests in the auth folder of this postman request to make sure postman environment variables as respective <code>userId</code> , <code>tokens</code> etc.</p>\n","_postman_id":"99fa0e46-cc55-4894-ba17-840bf5e6b89c"},{"name":"code templates","item":[{"name":"execute","item":[{"name":"python","id":"22da905b-d97c-40c0-b7a7-5c975ad00711","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"language\": \"python\",\n    \"code\": \"print(input().strip())\",\n    \"stdin\": \"Hello, World!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/execute","description":"<p>This endpoint allows users to execute a code snippet in a specified programming language with optional input. If the execution is successful, it returns the output of the code; otherwise, it returns an error message.</p>\n<p><strong>Body Parameters</strong> (all required):</p>\n<ul>\n<li><p><code>language</code>: The programming language to execute the code in. Supported values might include <code>python</code>, <code>javascript</code>, <code>c</code>, <code>cpp</code>, or <code>java</code>.</p>\n</li>\n<li><p><code>code</code>: The code snippet to be executed.</p>\n</li>\n<li><p><code>stdin</code> <em>(optional)</em>: Standard input to provide to the code during execution (useful for interactive programs).</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Code executed successfully\",<br />\"result\": \"Hello, World!\"<br />}</p>\n<p>returns a 400 if there is a code execution error and the logs will be sent in the response body</p>\n","urlObject":{"path":["api","code","execute"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"22da905b-d97c-40c0-b7a7-5c975ad00711"},{"name":"c++","id":"01ce4cfd-9de9-4bc2-8f7b-407549c2f365","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"language\": \"c++\",\n    \"code\": \"#include <iostream>\\n#include <string>\\nint main() {\\n    std::string input;\\n    std::getline(std::cin, input);\\n    std::cout << input << std::endl;\\n    return 0;\\n}\",\n    \"stdin\": \"Hello, World!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/execute","description":"<p>This endpoint allows users to execute a code snippet in a specified programming language with optional input. If the execution is successful, it returns the output of the code; otherwise, it returns an error message.</p>\n<p><strong>Body Parameters</strong> (all required):</p>\n<ul>\n<li><p><code>language</code>: The programming language to execute the code in. Supported values might include <code>python</code>, <code>javascript</code>, <code>c</code>, <code>cpp</code>, or <code>java</code>.</p>\n</li>\n<li><p><code>code</code>: The code snippet to be executed.</p>\n</li>\n<li><p><code>stdin</code> <em>(optional)</em>: Standard input to provide to the code during execution (useful for interactive programs).</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Code executed successfully\",<br />\"result\": \"Hello, World!\"<br />}</p>\n<p>returns a 400 if there is a code execution error and the logs will be sent in the response body</p>\n","urlObject":{"path":["api","code","execute"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"01ce4cfd-9de9-4bc2-8f7b-407549c2f365"},{"name":"c","id":"eb7cff70-3b94-4a3c-b53b-cc80ce74e75c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"language\": \"c\",\n    \"code\": \"#include <stdio.h>\\n#define BUFFER_SIZE 100\\nint main() {\\n    char input[BUFFER_SIZE];\\n    if (fgets(input, BUFFER_SIZE, stdin) != NULL) {\\n        printf(\\\"%s\\\", input);\\n    }\\n    return 0;\\n}\",\n    \"stdin\": \"Hello, World!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/execute","description":"<p>This endpoint allows users to execute a code snippet in a specified programming language with optional input. If the execution is successful, it returns the output of the code; otherwise, it returns an error message.</p>\n<p><strong>Body Parameters</strong> (all required):</p>\n<ul>\n<li><p><code>language</code>: The programming language to execute the code in. Supported values might include <code>python</code>, <code>javascript</code>, <code>c</code>, <code>cpp</code>, or <code>java</code>.</p>\n</li>\n<li><p><code>code</code>: The code snippet to be executed.</p>\n</li>\n<li><p><code>stdin</code> <em>(optional)</em>: Standard input to provide to the code during execution (useful for interactive programs).</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Code executed successfully\",<br />\"result\": \"Hello, World!\"<br />}</p>\n<p>returns a 400 if there is a code execution error and the logs will be sent in the response body</p>\n","urlObject":{"path":["api","code","execute"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"eb7cff70-3b94-4a3c-b53b-cc80ce74e75c"},{"name":"javascript","id":"90c229db-0b69-4d83-8480-e47931f0a9fa","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"language\": \"javascript\",\n    \"code\": \"process.stdin.on('data', data => {\\n    console.log(data.toString().trim());\\n    process.exit();\\n});\",\n    \"stdin\": \"Hello, World!\"\n}\n","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/execute","description":"<p>This endpoint allows users to execute a code snippet in a specified programming language with optional input. If the execution is successful, it returns the output of the code; otherwise, it returns an error message.</p>\n<p><strong>Body Parameters</strong> (all required):</p>\n<ul>\n<li><p><code>language</code>: The programming language to execute the code in. Supported values might include <code>python</code>, <code>javascript</code>, <code>c</code>, <code>cpp</code>, or <code>java</code>.</p>\n</li>\n<li><p><code>code</code>: The code snippet to be executed.</p>\n</li>\n<li><p><code>stdin</code> <em>(optional)</em>: Standard input to provide to the code during execution (useful for interactive programs).</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Code executed successfully\",<br />\"result\": \"Hello, World!\"<br />}</p>\n<p>returns a 400 if there is a code execution error and the logs will be sent in the response body</p>\n","urlObject":{"path":["api","code","execute"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"90c229db-0b69-4d83-8480-e47931f0a9fa"},{"name":"java","id":"5b901cd1-f20a-43a4-89c0-23f35bf1d550","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"language\": \"java\",\n    \"code\": \"import java.util.Scanner;\\n\\npublic class Main {\\n    public static void main(String[] args) {\\n        Scanner scanner = new Scanner(System.in);\\n        String input = scanner.nextLine();\\n        System.out.println(\\\"You entered: \\\" + input);\\n        scanner.close();\\n    }\\n}\",\n    \"stdin\": \"Hello, Java!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/execute","description":"<p>This endpoint allows users to execute a code snippet in a specified programming language with optional input. If the execution is successful, it returns the output of the code; otherwise, it returns an error message.</p>\n<p><strong>Body Parameters</strong> (all required):</p>\n<ul>\n<li><p><code>language</code>: The programming language to execute the code in. Supported values might include <code>python</code>, <code>javascript</code>, <code>c</code>, <code>cpp</code>, or <code>java</code>.</p>\n</li>\n<li><p><code>code</code>: The code snippet to be executed.</p>\n</li>\n<li><p><code>stdin</code> <em>(optional)</em>: Standard input to provide to the code during execution (useful for interactive programs).</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Code executed successfully\",<br />\"result\": \"Hello, World!\"<br />}</p>\n<p>returns a 400 if there is a code execution error and the logs will be sent in the response body</p>\n","urlObject":{"path":["api","code","execute"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"5b901cd1-f20a-43a4-89c0-23f35bf1d550"}],"id":"0bb3a75a-09fb-4c46-9933-edd7157ccbea","description":"<p>no auth required to run these.</p>\n","_postman_id":"0bb3a75a-09fb-4c46-9933-edd7157ccbea"},{"name":"save / create code template","event":[{"listen":"test","script":{"id":"7f9b9c2a-61dc-4b34-a97b-52c3c5773798","exec":["const response = pm.response.json();","","pm.test(response.codeTemplate.id)","pm.environment.set(\"codeTemplateId\", response.codeTemplate.id);"],"type":"text/javascript","packages":{}}}],"id":"59c33912-b44e-4012-8c6f-7148763ac895","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"title\": \"Hello World 2 Example\",\n    \"userId\": {{userId}},\n    \"code\": \"print('Hello, World!')\",\n    \"parentTemplateId\": null,\n    \"language\": \"Python\",\n    \"explanation\": \"This code prints 'Hello, World!' to the console.\",\n    \"tags\": [\"basic\", \"hello world\", \"python\"]\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/","description":"<ul>\n<li><p><strong>Description</strong>: Creates a new code template for a user, requiring <code>userId</code>, <code>title</code>, <code>language</code>, and <code>code</code> fields. The user's authorization is validated based on <code>userId</code> from the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires identity verification to ensure <code>userId</code> in the request matches the authenticated user.</p>\n</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: ID of the user creating the template.</p>\n</li>\n<li><p><code>title</code> <em>(required)</em>: Title of the code template.</p>\n</li>\n<li><p><code>language</code> <em>(required)</em>: Programming language of the template.</p>\n</li>\n<li><p><code>code</code> <em>(required)</em>: The code snippet content.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Tags associated with the code template.</p>\n</li>\n<li><p><code>parentTemplateId</code> <em>(optional)</em>: ID of the parent template if this is a forked template.</p>\n</li>\n</ul>\n<p>returns</p>\n<p>{<br />\"message\": \"Code Template created successfully\",<br />\"codeTemplate\": {<br />\"id\": 2,<br />\"userId\": 1,<br />\"title\": \"New JavaScript Template\",<br />\"language\": \"javascript\",<br />\"code\": \"console.log('Hello World');\",<br />\"tags\": [\"javascript\", \"console\"],<br />\"createdAt\": \"2023-01-01T00:00:00Z\",<br />\"updatedAt\": \"2023-01-01T00:00:00Z\"<br />}<br />}</p>\n","urlObject":{"path":["api","code",""],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"59c33912-b44e-4012-8c6f-7148763ac895"},{"name":"fork code template","id":"4261675d-ffc7-4ad8-87e7-90edc4855952","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"title\": \"Hello World 2 Example FORKED\",\n    \"userId\": {{userId}},\n    \"code\": \"print('Hello, World!')\",\n    \"parentTemplateId\": {{codeTemplateId}},\n    \"language\": \"Python\",\n    \"explanation\": \"This code prints 'Hello, World!' to the console.\",\n    \"tags\": [\"basic\", \"hello world\", \"python\"]\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/","description":"<ul>\n<li><p><strong>Description</strong>: Creates a new code template for a user, requiring <code>userId</code>, <code>title</code>, <code>language</code>, and <code>code</code> fields. The user's authorization is validated based on <code>userId</code> from the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires identity verification to ensure <code>userId</code> in the request matches the authenticated user.</p>\n</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: ID of the user creating the template.</p>\n</li>\n<li><p><code>title</code> <em>(required)</em>: Title of the code template.</p>\n</li>\n<li><p><code>language</code> <em>(required)</em>: Programming language of the template.</p>\n</li>\n<li><p><code>code</code> <em>(required)</em>: The code snippet content.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Tags associated with the code template.</p>\n</li>\n<li><p><code>parentTemplateId</code> <em>(optional)</em>: ID of the parent template if this is a forked template.</p>\n</li>\n</ul>\n<p>returns</p>\n<p>{<br />\"message\": \"Code Template created successfully\",<br />\"codeTemplate\": {<br />\"id\": 2,<br />\"userId\": 1,<br />\"title\": \"New JavaScript Template\",<br />\"language\": \"javascript\",<br />\"code\": \"console.log('Hello World');\",<br />\"tags\": [\"javascript\", \"console\"],<br />\"createdAt\": \"2023-01-01T00:00:00Z\",<br />\"updatedAt\": \"2023-01-01T00:00:00Z\"<br />}<br />}</p>\n","urlObject":{"path":["api","code",""],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"4261675d-ffc7-4ad8-87e7-90edc4855952"},{"name":"update code template","id":"1959b76c-41c8-4a98-ac47-1c5b34461fe3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"title\": \"new title\",\n    \"tags\": [\"new\", \"basic\", \"python\"]\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/code/{{codeTemplateId}}","description":"<ul>\n<li><p><strong>Description</strong>: Updates an existing code template by ID, modifying attributes like title, code, language, and tags. Only the original author (identified by <code>userId</code>) is permitted to update.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires user identity verification to ensure the <code>userId</code> in the request matches the template's creator.</p>\n</li>\n<li><p>Path Parameters:Request Body:</p>\n<ul>\n<li><p><code>id</code> <em>(required)</em>: The unique identifier for the code template to be updated.</p>\n</li>\n<li><p><code>title</code> <em>(optional)</em>: New title for the code template.</p>\n</li>\n<li><p><code>code</code> <em>(optional)</em>: Updated code snippet.</p>\n</li>\n<li><p><code>language</code> <em>(optional)</em>: Programming language.</p>\n</li>\n<li><p><code>explanation</code> <em>(optional)</em>: Explanation for the code template.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Updated tags for the code template.</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>returns</p>\n<p>{<br />\"message\": \"Code template updated successfully\",<br />\"codeTemplate\": {<br />\"id\": 1,<br />\"userId\": 1,<br />\"title\": \"Updated Template Title\",<br />\"code\": \"console.log('Updated Code');\",<br />\"language\": \"javascript\",<br />\"explanation\": \"Logs an updated message.\",<br />\"tags\": [\"javascript\", \"update\"]<br />}<br />}</p>\n","urlObject":{"path":["api","code","{{codeTemplateId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"1959b76c-41c8-4a98-ac47-1c5b34461fe3"},{"name":"get code template","id":"d71f9c64-19b4-4fc3-9720-11d7c7e1ad24","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/code/{{codeTemplateId}}","description":"<ul>\n<li><p><strong>Description</strong>: Fetches a code template by its ID, returning all relevant details including tags, language, and explanation if provided.</p>\n</li>\n<li><p><strong>Authorization</strong>: No authorization check for this endpoint; anyone can access code templates by ID.</p>\n</li>\n<li><p>Path Parameters:</p>\n<ul>\n<li><code>id</code> <em>(required)</em>: The unique identifier for the code template.</li>\n</ul>\n</li>\n</ul>\n<p>returns</p>\n<p>{<br />\"message\": \"Code template fetched successfully\",<br />\"codeTemplate\": {<br />\"id\": 1,<br />\"userId\": 1,<br />\"title\": \"Example Template\",<br />\"code\": \"console.log('Hello World');\",<br />\"language\": \"javascript\",<br />\"explanation\": \"Logs a message to the console.\",<br />\"tags\": [\"javascript\", \"console\"]<br />}<br />}</p>\n","urlObject":{"path":["api","code","{{codeTemplateId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"d71f9c64-19b4-4fc3-9720-11d7c7e1ad24"},{"name":"get saved code templates","id":"b58c4885-8819-4229-a001-58a8774da6bd","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/code/?userId={{userId}}","description":"<ul>\n<li><p>For this example, we filter by userId for when we want to fetch a user's saved code templates</p>\n</li>\n<li><p><strong>Description</strong>: Fetches code templates based on optional filters like <code>title</code>, <code>content</code>, <code>tags</code>, <code>userId</code>, <code>page</code>, and <code>limit</code>.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires user identity verification if <code>userId</code> is provided to ensure only authorized users can access data.</p>\n</li>\n<li><p>Query Parameters:</p>\n<ul>\n<li><p><code>page</code> <em>(optional)</em>: Page number for pagination (e.g., <code>1</code>, <code>2</code>).</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: Number of templates per page.</p>\n</li>\n<li><p><code>userId</code> <em>(optional)</em>: User ID to filter code templates by a specific user.</p>\n</li>\n<li><p><code>title</code> <em>(optional)</em>: Filters by title.</p>\n</li>\n<li><p><code>content</code> <em>(optional)</em>: Searches templates containing specific content.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Comma-separated list of tags to filter templates (e.g., <code>javascript,api</code>).</p>\n</li>\n</ul>\n</li>\n</ul>\n","urlObject":{"path":["api","code",""],"host":["http://localhost:3000"],"query":[{"key":"userId","value":"{{userId}}"}],"variable":[]}},"response":[],"_postman_id":"b58c4885-8819-4229-a001-58a8774da6bd"},{"name":"get code templates","id":"70f347fc-a389-463a-96c1-5c85ac4e7ad2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/code/?tag=python","description":"<ul>\n<li><p><strong>Description</strong>: Fetches code templates based on optional filters like <code>title</code>, <code>content</code>, <code>tags</code>, <code>userId</code>, <code>page</code>, and <code>limit</code>.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires user identity verification if <code>userId</code> is provided to ensure only authorized users can access data.</p>\n</li>\n<li><p>Query Parameters:</p>\n<ul>\n<li><p><code>page</code> <em>(optional)</em>: Page number for pagination (e.g., <code>1</code>, <code>2</code>).</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: Number of templates per page.</p>\n</li>\n<li><p><code>userId</code> <em>(optional)</em>: User ID to filter code templates by a specific user.</p>\n</li>\n<li><p><code>title</code> <em>(optional)</em>: Filters by title.</p>\n</li>\n<li><p><code>content</code> <em>(optional)</em>: Searches templates containing specific content.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Comma-separated list of tags to filter templates (e.g., <code>javascript,api</code>).</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Code templates fetched successfully\",<br />\"codeTemplates\": [<br />{<br />\"id\": 1,<br />\"userId\": 1,<br />\"title\": \"Sample Template\",<br />\"language\": \"javascript\",<br />\"code\": \"console.log('Hello World');\",<br />\"tags\": [\"javascript\", \"console\"],<br />\"createdAt\": \"2023-01-01T00:00:00Z\",<br />\"updatedAt\": \"2023-01-01T00:00:00Z\"<br />}<br />],<br />\"totalCount\": 50<br />}</p>\n","urlObject":{"path":["api","code",""],"host":["http://localhost:3000"],"query":[{"key":"tag","value":"python"}],"variable":[]}},"response":[],"_postman_id":"70f347fc-a389-463a-96c1-5c85ac4e7ad2"},{"name":"delete code template","id":"79db1bfd-f3f5-4991-a33e-d0387e7f552a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"DELETE","header":[],"url":"http://localhost:3000/api/code/{{codeTemplateId}}","urlObject":{"path":["api","code","{{codeTemplateId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"79db1bfd-f3f5-4991-a33e-d0387e7f552a"}],"id":"8bcd33b0-90ec-444d-9022-066d14468b6c","description":"<p>Before trying requests in this folder, make sure you have ran any of the login requests in the auth folder of this postman request to ensure that the environment variables for <code>userId</code> , <code>accessToken</code> etc are. set.</p>\n","_postman_id":"8bcd33b0-90ec-444d-9022-066d14468b6c"},{"name":"blog posts","item":[{"name":"fetch sorted blog posts","item":[{"name":"search blog posts","id":"6c3bb8b7-eea8-42c4-a5d3-a7cc21856368","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/blogs?title=timeless&tags=Async","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves a list of blog posts, with options to filter by title, content, tags, and associated code templates. Supports pagination and sorting.</p>\n</li>\n<li><p><strong>Authorization</strong>: Checks the user ID from the request header and filters blog posts accordingly.</p>\n</li>\n<li><p>Query Parameters:</p>\n<ul>\n<li><p><code>page</code> <em>(optional)</em>: Page number for pagination.</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: Number of blog posts per page.</p>\n</li>\n<li><p><code>title</code> <em>(optional)</em>: Filter blog posts by title.</p>\n</li>\n<li><p><code>content</code> <em>(optional)</em>: Filter blog posts by content.</p>\n</li>\n<li><p><code>codeTemplateIds</code> <em>(optional)</em>: Comma-separated list of code template IDs to filter by.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Comma-separated list of tags to filter by.</p>\n</li>\n<li><p><code>orderBy</code> <em>(optional)</em>: Sort blog posts by <code>mostReported</code>, <code>mostValued</code>, or <code>mostControversial</code>. (NOTE mostValued is only available to be used in admin endpoint, so it will be canceled / nulled at this endpoint)</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Blog Posts fetched successfully\",<br />\"blogPosts\": [<br />{<br />\"id\": 1,<br />\"userId\": 2,<br />\"title\": \"Understanding Async in JavaScript\",<br />\"description\": \"An intro to asynchronous programming in JS.\",<br />\"content\": \"Content goes here...\",<br />\"hidden\": false,<br />\"codeTemplateIds\": [1, 3],<br />\"createdAt\": \"2024-11-01T12:00:00Z\",<br />\"updatedAt\": \"2024-11-01T12:30:00Z\",<br />\"tags\": [\"javascript\", \"async\"],<br />\"commentIds\": [10, 11]<br />}<br />],<br />\"totalCount\": 1<br />}</p>\n","urlObject":{"path":["api","blogs"],"host":["http://localhost:3000"],"query":[{"disabled":true,"key":"page","value":"1"},{"disabled":true,"key":"limit","value":"1"},{"key":"title","value":"timeless"},{"key":"tags","value":"Async"}],"variable":[]}},"response":[],"_postman_id":"6c3bb8b7-eea8-42c4-a5d3-a7cc21856368"},{"name":"fetch most controversial blog posts","id":"1c2f53de-29a8-4a3f-969b-eca4f25ebbeb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/blogs?orderBy=mostControversial","description":"<p>same as <code>search blog posts</code> but this time just an example of the orderBy usage for most controversial blog posts which means most impressions (upvotes and downvotes)</p>\n","urlObject":{"path":["api","blogs"],"host":["http://localhost:3000"],"query":[{"key":"orderBy","value":"mostControversial"}],"variable":[]}},"response":[],"_postman_id":"1c2f53de-29a8-4a3f-969b-eca4f25ebbeb"},{"name":"fetch most valued blog posts","id":"f58a50d8-6b7a-4314-91ee-5381d65cf5b0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/blogs?orderBy=mostValued","description":"<p>same as <code>search blog posts</code> but this time just an example of the orderBy usage for most valued which is the highest positive difference between upvotes and downvotes.</p>\n","urlObject":{"path":["api","blogs"],"host":["http://localhost:3000"],"query":[{"key":"orderBy","value":"mostValued"}],"variable":[]}},"response":[],"_postman_id":"f58a50d8-6b7a-4314-91ee-5381d65cf5b0"}],"id":"42bbe8fd-09ba-40ee-affc-f1dde13e8e63","description":"<p>before fetching blogposts make sure to have created some blog posts to see results and such</p>\n","_postman_id":"42bbe8fd-09ba-40ee-affc-f1dde13e8e63"},{"name":"comments","item":[{"name":"comment on blog post","event":[{"listen":"test","script":{"id":"2605f2fa-79f8-4066-b371-0a0d28f5ba74","exec":["const response = pm.response.json();","","pm.test(response.comment.id)","pm.environment.set(\"commentId\", response.comment.id);"],"type":"text/javascript","packages":{}}}],"id":"f8a0dadc-e53a-4be7-a38c-2cffb37fe1d3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"userId\": {{userId}},\n    \"content\": \"Wow!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/blogs/{{blogPostId}}/comment","description":"<ul>\n<li><p><strong>Description</strong>: Allows an authorized user to add a comment to a specific blog post by <code>id</code>. This endpoint ensures the user making the comment matches the <code>userId</code> specified in the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the user making the request matches the <code>userId</code> associated with the comment.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post to comment on.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: The ID of the user adding the comment.</p>\n</li>\n<li><p><code>content</code> <em>(required)</em>: The content of the comment.</p>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Blog Post successfully commented on\",<br />\"comment\": {<br />\"id\": 45,<br />\"userId\": 3,<br />\"blogPostId\": 12,<br />\"content\": \"Great post!\",<br />\"createdAt\": \"2024-10-01T12:00:00.000Z\"<br />}<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}","comment"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"f8a0dadc-e53a-4be7-a38c-2cffb37fe1d3"},{"name":"get direct comments from blog post","id":"4ff7452b-5124-41a8-9b3a-9c4637baada8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/blogs/{{blogPostId}}/comment","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves a paginated list of direct comments for a specific blog post by <code>id</code>. Optionally filters comments to only include those visible to the <code>userId</code> making the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the requesting user has permission to view comments on the blog post if any comments are restricted.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post for which to retrieve comments.</li>\n</ul>\n<h5 id=\"query-parameters\">Query Parameters:</h5>\n<ul>\n<li><p><code>page</code> <em>(optional)</em>: The page number to fetch (default: <code>1</code>).</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: The number of comments per page (default: <code>10</code>).</p>\n</li>\n</ul>\n<p>{<br />\"message\": \"Blog Post direct comments fetched successfully\",<br />\"comments\": [<br />{<br />\"id\": 45,<br />\"userId\": 3,<br />\"blogPostId\": 12,<br />\"content\": \"Great post!\",<br />\"createdAt\": \"2024-10-01T12:00:00.000Z\"<br />}<br />],<br />\"totalCount\": 25<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}","comment"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"4ff7452b-5124-41a8-9b3a-9c4637baada8"},{"name":"reply to comment","id":"545f1104-7b1c-409f-8acd-26db453bc9a0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"userId\": {{userId}},\n    \"content\": \"you said the same thing before!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/comments/{{commentId}}/comment","description":"<ul>\n<li><p><strong>Description</strong>: Allows an authorized user to add a reply to a specific comment by <code>id</code>. The endpoint ensures that the user making the request matches the <code>userId</code> specified in the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the user making the request matches the <code>userId</code> associated with the reply; otherwise, the request is rejected.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment to reply to.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: The ID of the user adding the reply.</p>\n</li>\n<li><p><code>content</code> <em>(required)</em>: The content of the reply.</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Comment successfully replied\",<br />\"comment\": {<br />\"id\": 78,<br />\"userId\": 3,<br />\"parentId\": 45,<br />\"content\": \"Thanks for the insight!\"<br />}<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}","comment"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"545f1104-7b1c-409f-8acd-26db453bc9a0"},{"name":"get direct replies from comments","id":"d68243e4-3b44-4917-b528-d50378e5c0e1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/comments/{{commentId}}/comment","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves a paginated list of direct replies for a specific comment by <code>id</code>. Optionally filters replies to only include those visible to the <code>userId</code> making the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the requesting user has permission to view replies on the comment if any replies are restricted.</p>\n</li>\n<li><p>Path Parameters:Query Parameters:</p>\n<ul>\n<li><p><code>id</code> <em>(required)</em>: The ID of the comment for which to retrieve replies.</p>\n</li>\n<li><p><code>page</code> <em>(optional)</em>: The page number to fetch (default: <code>1</code>).</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: The number of replies per page (default: <code>10</code>).</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Comment direct replies fetched successfully\",<br />\"comments\": [<br />{<br />\"id\": 78,<br />\"userId\": 3,<br />\"parentId\": 45,<br />\"content\": \"Thanks for the insight!\"<br />}<br />],<br />\"totalCount\": 5<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}","comment"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"d68243e4-3b44-4917-b528-d50378e5c0e1"},{"name":"get comment","id":"0fba4232-f080-4ae9-9041-882e8b1f60a4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/comments/{{commentId}}","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves details of a specific comment by <code>id</code>. If the comment is hidden, only the comment owner can access it.</p>\n</li>\n<li><p><strong>Authorization</strong>: If the comment is hidden, the authorization check ensures only the comment owner can view it.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment to retrieve.</li>\n</ul>\n<p>return {<br />\"message\": \"Comment fetched successfully\",<br />\"comment\": {<br />\"id\": 12,<br />\"content\": \"This is a comment.\",<br />\"userId\": 3,<br />\"blogPostId\": 5,<br />\"parentId\": null,<br />\"createdAt\": \"2023-10-31T10:00:00Z\",<br />\"hidden\": false,<br />\"replyIds\": [13, 14],<br />\"upVotes\": 10,<br />\"downVotes\": 2,<br />\"reportIds\": [21, 22]<br />}<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"0fba4232-f080-4ae9-9041-882e8b1f60a4"},{"name":"update comment","id":"8069e2f2-1af5-4542-bf88-6fff847ef89c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"content\": \"wow edited!\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/comments/{{commentId}}","description":"<ul>\n<li><p><strong>Description</strong>: Updates the content of a specific comment by <code>id</code>. Only the comment owner can update it.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the user making the request matches the comment's <code>userId</code>.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment to update.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><code>content</code> <em>(required)</em>: The updated content of the comment.</li>\n</ul>\n<p>return {<br />\"message\": \"Comment updated successfully\",<br />\"comment\": {<br />\"id\": 12,<br />\"userId\": 3,<br />\"content\": \"Updated comment content.\"<br />}<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"8069e2f2-1af5-4542-bf88-6fff847ef89c"},{"name":"report comment","id":"0a26362e-043e-4b49-9cb7-bc43f965e8fb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"userId\": {{userId}},\n    \"reason\": \"hurt my feelings\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/comments/{{commentId}}/report","description":"<ul>\n<li><p><strong>Description</strong>: Allows a user to report a specific comment by <code>id</code>, specifying a reason for the report. Only accessible if the user matches the <code>userId</code> provided in the request.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the user making the request matches the <code>userId</code> associated with the report.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment to be reported.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: The ID of the user reporting the comment.</p>\n</li>\n<li><p><code>reason</code> <em>(required)</em>: The reason for reporting the comment (e.g., \"Spam,\" \"Inappropriate content\").</p>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Comment successfully reported\",<br />\"report\": {<br />\"id\": 45,<br />\"userId\": 3,<br />\"commentId\": 12,<br />\"reason\": \"Inappropriate content\"<br />}<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}","report"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"0a26362e-043e-4b49-9cb7-bc43f965e8fb"},{"name":"vote comment","id":"0c5739e6-96a1-4f46-af60-71f0141b8b86","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"userId\": {{userId}},\n    \"voteType\": \"UP\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/comments/{{commentId}}/rate","description":"<ul>\n<li><p><strong>Description</strong>: Allows an authorized user to toggle a vote on a specific comment by <code>id</code>. The endpoint verifies that the user making the request is the same as the <code>userId</code> specified.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check to confirm that the <code>userId</code> in the request matches the authenticated user.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment to vote on.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: The ID of the user toggling the vote.</p>\n</li>\n<li><p><code>voteType</code> <em>(required)</em>: The type of vote to toggle, such as <code>upvote</code> or <code>downvote</code>.</p>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Comment vote toggle successfully applied\",<br />\"vote\": {<br />\"id\": 123,<br />\"userId\": 1,<br />\"commentId\": 456,<br />\"voteType\": \"upvote\"<br />}<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}","rate"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"0c5739e6-96a1-4f46-af60-71f0141b8b86"},{"name":"get vote for comment","id":"9f0fe5a7-c7e2-470b-ad94-96948478509b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/comments/{{commentId}}/rate","description":"<ul>\n<li><p><strong>Description</strong>: Fetches the current vote of an authenticated user for a specific comment by <code>id</code>.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires that the user be authenticated, and the user ID must match the user associated with the vote.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment for which to fetch the vote.</li>\n</ul>\n<p>return {<br />\"message\": \"Comment vote successfully fetched for user\",<br />\"vote\": {<br />\"id\": 123,<br />\"userId\": 1,<br />\"commentId\": 456,<br />\"voteType\": \"upvote\"<br />}<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}","rate"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"9f0fe5a7-c7e2-470b-ad94-96948478509b"},{"name":"delete comment","id":"2f3af71d-6bd2-45a1-877e-fcda9e64828d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"http://localhost:3000/api/comments/{{commentId}}","description":"<ul>\n<li><p><strong>Description</strong>: Deletes a specific comment by <code>id</code>.</p>\n</li>\n<li><p><strong>Authorization</strong>: Only accessible if the user has permission to delete the comment.</p>\n</li>\n<li><p>Path Parameters:</p>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment to delete.</li>\n</ul>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Comment deleted successfully\"<br />}</p>\n","urlObject":{"path":["api","comments","{{commentId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"2f3af71d-6bd2-45a1-877e-fcda9e64828d"}],"id":"6baaa881-12ef-4b23-a620-fa930e9e65e0","description":"<p>Before trying requests in this folder, make sure a blog post has been created within <code>create blog post</code> in the parent directory.</p>\n","_postman_id":"6baaa881-12ef-4b23-a620-fa930e9e65e0"},{"name":"create blog post","event":[{"listen":"test","script":{"id":"5cccd77d-f036-4c44-96cc-762ceee7755b","exec":["const response = pm.response.json();","","pm.test(response.blogPost.id)","pm.environment.set(\"blogPostId\", response.blogPost.id);"],"type":"text/javascript","packages":{}}}],"id":"441d9610-34ee-4d00-a16b-dc780b954e41","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"title\": \"Exploring TIMELESS\",\n    \"description\": \"A deep dive into async programming in JavaScript, covering callbacks, promises, and async/await.\",\n    \"content\": \"Asynchronous programming is crucial for developing responsive applications. In this post, we'll explore various approaches to handle async operations in JavaScript, including callbacks, promises, and async/await...\",\n    \"userId\": {{userId}}, \n    \"codeTemplateIds\": [],\n    \"tags\": [\"JavaScript\", \"Async\", \"Programming\", \"Web Development\"]\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/blogs","description":"<ul>\n<li><p><strong>Description</strong>: Creates a new blog post with the provided details and associates it with code templates and tags. The request is authorized by checking the <code>userId</code> in the request with the authenticated user ID.</p>\n</li>\n<li><p><strong>Authorization</strong>: Verifies that the <code>userId</code> in the request body matches the authorized user.</p>\n</li>\n<li><p>Request Body:</p>\n<ul>\n<li><p><code>title</code> <em>(required)</em>: Title of the blog post.</p>\n</li>\n<li><p><code>description</code> <em>(required)</em>: Short description of the blog post.</p>\n</li>\n<li><p><code>content</code> <em>(required)</em>: Main content of the blog post.</p>\n</li>\n<li><p><code>userId</code> <em>(required)</em>: ID of the user creating the post.</p>\n</li>\n<li><p><code>codeTemplateIds</code> <em>(optional)</em>: Array of code template IDs associated with the blog post.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: Array of tags associated with the blog post.</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Blog Post created successfully\",<br />\"blogPost\": {<br />\"id\": 1,<br />\"userId\": 2,<br />\"title\": \"Getting Started with REST APIs\",<br />\"description\": \"A beginner's guide to REST APIs.\",<br />\"content\": \"Content of the blog post...\",<br />\"hidden\": false,<br />\"codeTemplateIds\": [1, 2],<br />\"createdAt\": \"2024-11-01T12:00:00Z\",<br />\"updatedAt\": \"2024-11-01T12:30:00Z\",<br />\"tags\": [\"REST\", \"API\", \"backend\"],<br />\"commentIds\": []<br />}<br />}</p>\n","urlObject":{"path":["api","blogs"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"441d9610-34ee-4d00-a16b-dc780b954e41"},{"name":"get blog post","id":"8082252f-a0f5-4dc1-8cb1-5c75489978a1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/blogs/{{blogPostId}}","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves a specific blog post by ID. If the post is hidden, the endpoint verifies the user’s authorization to view it.</p>\n</li>\n<li><p><strong>Authorization</strong>: If the blog post is hidden, the <code>userId</code> of the request must match the <code>userId</code> of the post.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post to fetch.</li>\n</ul>\n<p>returns {<br />\"message\": \"Blog Post fetched successfully\",<br />\"blogPost\": {<br />\"id\": 1,<br />\"userId\": 2,<br />\"title\": \"Understanding REST APIs\",<br />\"description\": \"Introduction to REST principles\",<br />\"content\": \"Content of the post...\",<br />\"hidden\": false,<br />\"codeTemplateIds\": [1, 2],<br />\"createdAt\": \"2024-11-01T12:00:00Z\",<br />\"updatedAt\": \"2024-11-01T12:30:00Z\",<br />\"upVotes\": 10,<br />\"downVotes\": 3,<br />\"tags\": [\"API\", \"REST\"],<br />\"commentIds\": [101, 102]<br />}<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"8082252f-a0f5-4dc1-8cb1-5c75489978a1"},{"name":"vote blog post","id":"7186a376-6e73-493f-bd19-3fe711d76705","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"userId\": {{userId}},\n    \"voteType\": \"DOWN\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/blogs/{{blogPostId}}/rate","description":"<ul>\n<li><p><strong>Description</strong>: Allows a user to toggle their vote on a specific blog post. The <code>voteType</code> specifies whether the vote is an upvote, downvote, or a removal of an existing vote.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an identity check by validating the <code>userId</code> in the request body against the authenticated user's ID in the authorization header.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post to vote on.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>userId</code> <em>(required)</em>: The ID of the user casting the vote.</p>\n</li>\n<li><p><code>voteType</code> <em>(optional)</em>: The type of vote, either <code>\"upvote\"</code>, <code>\"downvote\"</code>, or <code>null</code> to remove the vote.</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Blog Post vote toggle successfully applied\",<br />\"vote\": {<br />\"id\": 45,<br />\"userId\": 2,<br />\"blogPostId\": 1,<br />\"voteType\": \"upvote\"<br />}<br />}</p>\n<p>if the user doesn't have a vote or canceled out then the vote would be returned null</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}","rate"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"7186a376-6e73-493f-bd19-3fe711d76705"},{"name":"get vote for blog post","id":"05b01b3e-9585-49c3-94b4-5c1fa37b752d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/blogs/{{blogPostId}}/rate","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves the vote of the currently authenticated user on the specified blog post.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires authorization to fetch the current user's vote on the blog post.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post to retrieve the vote for.</li>\n</ul>\n<p>returns {<br />\"message\": \"Blog Post vote successfully fetched for user\",<br />\"vote\": {<br />\"id\": 45,<br />\"userId\": 2,<br />\"blogPostId\": 1,<br />\"voteType\": \"downvote\"<br />}<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}","rate"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"05b01b3e-9585-49c3-94b4-5c1fa37b752d"},{"name":"report blog post","id":"7e42cea8-84b3-497b-9394-7559d9e79441","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"userId\": {{userId}},\n    \"reason\": \"hurt my feelings\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/blogs/{{blogPostId}}/report","description":"<ul>\n<li><p><strong>Description</strong>: Reports a blog post by its ID, providing a reason for the report. The endpoint creates a new report entry for the specified blog post.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires <code>userId</code> from the request body, which should be the ID of the user submitting the report.</p>\n</li>\n<li><p>Path Parameters:Request Body:</p>\n<ul>\n<li><p><code>id</code> <em>(required)</em>: The ID of the blog post to report.</p>\n</li>\n<li><p><code>userId</code> <em>(required)</em>: The ID of the user reporting the blog post.</p>\n</li>\n<li><p><code>reason</code> <em>(required)</em>: A string describing the reason for reporting the blog post.</p>\n</li>\n</ul>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Blog Post successfully reported\",<br />\"report\": {<br />\"id\": 123,<br />\"userId\": 2,<br />\"blogPostId\": 1,<br />\"reason\": \"Inappropriate content\"<br />}<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}","report"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"7e42cea8-84b3-497b-9394-7559d9e79441"},{"name":"update blog post","id":"a8fb7744-2f69-4dce-827e-9a58a6e3b202","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"description\": \"new description\"\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/blogs/{{blogPostId}}","description":"<ul>\n<li><p><strong>Description</strong>: Updates an existing blog post. Ensures the <code>userId</code> from the request header matches the <code>userId</code> of the blog post.</p>\n</li>\n<li><p><strong>Authorization</strong>: Only the post author (matching <code>userId</code>) can update the blog post.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post to update.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><p><code>title</code> <em>(optional)</em>: New title for the blog post.</p>\n</li>\n<li><p><code>description</code> <em>(optional)</em>: New description for the blog post.</p>\n</li>\n<li><p><code>content</code> <em>(optional)</em>: New content for the blog post.</p>\n</li>\n<li><p><code>codeTemplateIds</code> <em>(optional)</em>: List of associated code template IDs.</p>\n</li>\n<li><p><code>tags</code> <em>(optional)</em>: List of associated tags.</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Blog Post updated successfully\",<br />\"blogPost\": {<br />\"id\": 1,<br />\"userId\": 2,<br />\"title\": \"Updated REST API Guide\",<br />\"description\": \"Updated description for REST guide\",<br />\"content\": \"Updated content...\",<br />\"hidden\": false,<br />\"codeTemplateIds\": [1, 3],<br />\"createdAt\": \"2024-11-01T12:00:00Z\",<br />\"updatedAt\": \"2024-11-01T13:00:00Z\",<br />\"tags\": [\"API\", \"REST\", \"Backend\"],<br />\"commentIds\": [101, 102]<br />}<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"a8fb7744-2f69-4dce-827e-9a58a6e3b202"},{"name":"delete blog post","id":"8cb31615-c8f0-4b20-9bb5-d3bc87f2f326","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"http://localhost:3000/api/blogs/{{blogPostId}}","description":"<ul>\n<li><p><strong>Description</strong>: Deletes a specific blog post by ID after verifying that the <code>userId</code> matches the post author’s ID.</p>\n</li>\n<li><p><strong>Authorization</strong>: Only the post author (matching <code>userId</code>) can delete the blog post.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post to delete.</li>\n</ul>\n<h5 id=\"return-\">return {</h5>\n<p>\"message\": \"Blog Post deleted successfully\"<br />}</p>\n","urlObject":{"path":["api","blogs","{{blogPostId}}"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"8cb31615-c8f0-4b20-9bb5-d3bc87f2f326"}],"id":"ab08ea7f-8fae-4dac-bc0c-b9f5970f7ceb","description":"<p>Before trying requests in this folder, make sure you have ran any of the login requests in the auth folder of this postman request.</p>\n<p>also for the nested folders relating to</p>\n<ul>\n<li><p><code>fetch sorted blog posts</code></p>\n</li>\n<li><p><code>comments</code></p>\n</li>\n</ul>\n<p>I suggest ensuring you have created a blog post already with the respective user before going any further into the nested folders. Go to <code>create blog post</code> request to do so.</p>\n","_postman_id":"ab08ea7f-8fae-4dac-bc0c-b9f5970f7ceb"},{"name":"admin","item":[{"name":"set hidden status for comment","id":"908624ca-ad5e-4247-a78e-b4c7a5de3552","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"hidden\": true\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/admin/comments/{{commentId}}/hide","description":"<ul>\n<li><strong>Description</strong>: This endpoint allows an administrator to toggle the <code>hidden</code> status of a comment. Setting a comment to <code>hidden</code> will make it invisible to regular users, while administrators will still be able to access it. Only users with admin privileges are authorized to perform this action.<strong>Authorization</strong>: Requires an admin-level authorization.</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the comment whose hidden status is to be toggled.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><code>hidden</code> <em>(required)</em>: A boolean value to set the comment as hidden (<code>true</code>) or visible (<code>false</code>).</li>\n</ul>\n<p>return {<br />\"message\": \"Comment hidden status has been updated\",<br />\"commentId\": 123,<br />\"hidden\": true<br />}</p>\n","urlObject":{"path":["api","admin","comments","{{commentId}}","hide"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"908624ca-ad5e-4247-a78e-b4c7a5de3552"},{"name":"set hidden status for blog post","id":"2f83df2f-6b88-4e17-8977-3d7e8312c004","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n    \"hidden\": true\n}","options":{"raw":{"language":"json"}}},"url":"http://localhost:3000/api/admin/blogs/{{blogPostId}}/hide","description":"<ul>\n<li><p><strong>Description</strong>: Allows an administrator to update the <code>hidden</code> status of a blog post. This is intended to hide or unhide blog posts as needed. Only users with admin privileges are authorized to perform this action.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an admin-level authorization.</p>\n</li>\n</ul>\n<h5 id=\"path-parameters\">Path Parameters:</h5>\n<ul>\n<li><code>id</code> <em>(required)</em>: The ID of the blog post whose hidden status is to be toggled.</li>\n</ul>\n<h5 id=\"request-body\">Request Body:</h5>\n<ul>\n<li><code>hidden</code> <em>(optional)</em>: A boolean value to set the blog post as hidden (<code>true</code>) or visible (<code>false</code>). If not provided, the default is <code>false</code>.</li>\n</ul>\n<p>return {<br />\"message\": \"Blog Post hidden status has been updated\",<br />\"blogPostId\": 123,<br />\"hidden\": true<br />}</p>\n","urlObject":{"path":["api","admin","blogs","{{blogPostId}}","hide"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"2f83df2f-6b88-4e17-8977-3d7e8312c004"},{"name":"get most reported blog posts","id":"c70c8bf6-53ae-4784-9d05-53491cf2c8d5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/admin/blogs","description":"<ul>\n<li><p><strong>Description</strong>: Retrieves blog posts with the highest number of reports, allowing administrators to review potentially inappropriate or flagged content. Only posts that have received user reports are included in the response.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an admin-level authorization.</p>\n</li>\n<li><p><code>page</code> <em>(optional)</em>: Specifies the page number of results to retrieve. Defaults to the first page if not provided.</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: Specifies the maximum number of blog posts to retrieve per page. Defaults to a preset limit if not provided.</p>\n</li>\n</ul>\n<p>returns {<br />\"message\": \"Most reported blog posts fetched successfully\",<br />\"blogPosts\": [<br />{<br />\"id\": 123,<br />\"userId\": 1,<br />\"title\": \"Inappropriate Post\",<br />\"content\": \"Flagged content\",<br />\"reportCount\": 10,<br />\"createdAt\": \"2024-01-01T12:00:00Z\"<br />},<br />{<br />\"id\": 456,<br />\"userId\": 3,<br />\"title\": \"Reported Post\",<br />\"content\": \"Content flagged by multiple users\",<br />\"reportCount\": 7,<br />\"createdAt\": \"2024-01-03T09:20:00Z\"<br />}<br />],<br />\"totalCount\": 2<br />}</p>\n","urlObject":{"path":["api","admin","blogs"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"c70c8bf6-53ae-4784-9d05-53491cf2c8d5"},{"name":"get most reported comments","id":"e855d379-6ba0-4d5e-984c-92cd7a9bd1cc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{accessToken}}"}]},"isInherited":false},"method":"GET","header":[],"url":"http://localhost:3000/api/admin/comments","description":"<ul>\n<li><p><strong>Description</strong>: This endpoint retrieves the most reported comments to assist administrators in reviewing flagged content. Only comments that have one or more reports will be included in the results. Access to this endpoint is restricted to users with admin privileges.</p>\n</li>\n<li><p><strong>Authorization</strong>: Requires an admin-level authorization.</p>\n</li>\n</ul>\n<h5 id=\"query-parameters\">Query Parameters:</h5>\n<ul>\n<li><p><code>page</code> <em>(optional)</em>: The page number to fetch. Defaults to the first page if not provided.</p>\n</li>\n<li><p><code>limit</code> <em>(optional)</em>: The maximum number of comments to return per page. Defaults to a set limit if not provided.</p>\n</li>\n</ul>\n<p>return {<br />\"message\": \"Most reported comments fetched successfully\",<br />\"comments\": [<br />{<br />\"id\": 123,<br />\"userId\": 1,<br />\"content\": \"Inappropriate content\",<br />\"reportCount\": 5,<br />\"createdAt\": \"2024-01-01T12:00:00Z\"<br />},<br />{<br />\"id\": 124,<br />\"userId\": 2,<br />\"content\": \"Another reported comment\",<br />\"reportCount\": 3,<br />\"createdAt\": \"2024-01-02T15:30:00Z\"<br />}<br />]<br />}</p>\n","urlObject":{"path":["api","admin","comments"],"host":["http://localhost:3000"],"query":[],"variable":[]}},"response":[],"_postman_id":"e855d379-6ba0-4d5e-984c-92cd7a9bd1cc"}],"id":"4c2fb9c5-2e06-4ecf-ba61-29822cdd7e9a","description":"<p>IN ORDER TO RUN THESE ADMIN ENDPOINTS YOU MUST BE LOGGED IN AS ADMIN</p>\n<p>Before trying requests in this folder, make sure you have ran the admin login requests in the auth folder of this postman request - <code>login admin</code></p>\n<p>Running <code>login admin</code> request in the <code>auth</code> directory will set idTokens and userIds to an ADMIN role user to run these requests within this directory</p>\n","_postman_id":"4c2fb9c5-2e06-4ecf-ba61-29822cdd7e9a"}],"event":[{"listen":"prerequest","script":{"id":"aa47b3a6-1b86-4bcb-b72b-ba9cbd1d2e04","type":"text/javascript","packages":{},"exec":[""]}},{"listen":"test","script":{"id":"cdd07579-92c1-46e7-8ebd-aefa33790bb7","type":"text/javascript","packages":{},"exec":[""]}}],"variable":[{"key":"adminEmail","value":"admin@gmail.com","type":"string"},{"key":"adminPassword","value":"12345","type":"string"},{"key":"userEmail","value":"","type":"string"},{"key":"userPassword","value":"","type":"string"},{"key":"baseUrl","value":"http://localhost:3000","type":"string"}]}