diff --git a/docs/ArtGallery/BackendUpgrades/Indigenous Art Gallery API.postman_test_run.json b/docs/ArtGallery/BackendUpgrades/Indigenous Art Gallery API.postman_test_run.json new file mode 100644 index 000000000..647aa9c3f --- /dev/null +++ b/docs/ArtGallery/BackendUpgrades/Indigenous Art Gallery API.postman_test_run.json @@ -0,0 +1,863 @@ +{ + "id": "dd225af8-3de1-4a9b-93ec-10589d736d8d", + "name": "Indigenous Art Gallery API", + "timestamp": "2023-09-19T23:59:42.764Z", + "collection_id": "22125528-61345646-96f3-4686-969b-2af89f43c52a", + "folder_id": 0, + "environment_id": "0", + "totalPass": 27, + "delay": 0, + "persist": true, + "status": "error", + "startedAt": "2023-09-19T23:59:41.598Z", + "totalFail": 0, + "results": [ + { + "id": "f009c462-5a47-4bac-93af-5982e6fc766a", + "name": "/api/artists/:artistId", + "url": "http://127.0.0.1:7194/api/artists/4", + "time": 17, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 17 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "e6091a48-82c1-47e7-96b5-0b5e2d31c42b", + "name": "/api/artists/:artistId", + "url": "http://127.0.0.1:7194/api/artists/4", + "time": 18, + "responseCode": { + "code": 204, + "name": "No Content" + }, + "tests": { + "Successful PUT request": true + }, + "testPassFailCounts": { + "Successful PUT request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 18 + ], + "allTests": [ + { + "Successful PUT request": true + } + ] + }, + { + "id": "acdce390-dccd-4672-a340-8c49ebd39158", + "name": "/api/artists/:artistId", + "url": "http://127.0.0.1:7194/api/artists/4", + "time": 9, + "responseCode": { + "code": 204, + "name": "No Content" + }, + "tests": { + "Successful DELETE request": true + }, + "testPassFailCounts": { + "Successful DELETE request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 9 + ], + "allTests": [ + { + "Successful DELETE request": true + } + ] + }, + { + "id": "6b7a9de1-6920-4c6c-a003-8da1fcc891d0", + "name": "/api/artists", + "url": "http://127.0.0.1:7194/api/artists", + "time": 7, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 7 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "f9173bc3-d889-4d1b-b50b-7be0cce4d5fc", + "name": "/api/artists", + "url": "http://127.0.0.1:7194/api/artists", + "time": 8, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful POST request": true + }, + "testPassFailCounts": { + "Successful POST request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 8 + ], + "allTests": [ + { + "Successful POST request": true + } + ] + }, + { + "id": "c7ef026f-0aab-4d0f-a82f-b12b35303870", + "name": "/api/artists/of-the-day", + "url": "http://127.0.0.1:7194/api/artists/of-the-day", + "time": 8, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 8 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "d501e368-82f8-4a32-9988-21e48cce9d71", + "name": "/api/artworks/:artworkId", + "url": "http://127.0.0.1:7194/api/artworks/49", + "time": 9, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 9 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "7d4bbb4b-ac8a-4040-ac83-514b1dcfdbb5", + "name": "/api/artworks/:artworkId", + "url": "http://127.0.0.1:7194/api/artworks/49", + "time": 7, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful PUT request": true + }, + "testPassFailCounts": { + "Successful PUT request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 7 + ], + "allTests": [ + { + "Successful PUT request": true + } + ] + }, + { + "id": "f4029369-aa35-4df8-8857-1d72b882a140", + "name": "/api/artworks/:artworkId", + "url": "http://127.0.0.1:7194/api/artworks/49", + "time": 13, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful DELETE request": true + }, + "testPassFailCounts": { + "Successful DELETE request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 13 + ], + "allTests": [ + { + "Successful DELETE request": true + } + ] + }, + { + "id": "14da6b9b-ca48-4a91-acfd-7eebc7f7ff56", + "name": "/api/artworks/:artworkId/assign/artist/:artistId", + "url": "http://127.0.0.1:7194/api/artworks/49/allocate/artist/12", + "time": 12, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful POST request": true + }, + "testPassFailCounts": { + "Successful POST request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 12 + ], + "allTests": [ + { + "Successful POST request": true + } + ] + }, + { + "id": "493fc9df-2859-4f99-8cd2-86e65cdb3e16", + "name": "/api/artworks/:artworkId/deassign/artist/:artistId", + "url": "http://127.0.0.1:7194/api/artworks/49/deallocate/artist/12", + "time": 11, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful DELETE request": true + }, + "testPassFailCounts": { + "Successful DELETE request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 11 + ], + "allTests": [ + { + "Successful DELETE request": true + } + ] + }, + { + "id": "ce3753d4-3b82-4d7c-9370-24b8318fa81c", + "name": "/api/artworks", + "url": "http://127.0.0.1:7194/api/artworks", + "time": 10, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 10 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "95d75c24-b6ca-45e8-8059-cf750077c158", + "name": "/api/artworks", + "url": "http://127.0.0.1:7194/api/artworks", + "time": 6, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful POST request": true + }, + "testPassFailCounts": { + "Successful POST request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 6 + ], + "allTests": [ + { + "Successful POST request": true + } + ] + }, + { + "id": "544346e4-afee-4d82-9afe-95cc243a9d7c", + "name": "/api/artworks/of-the-day", + "url": "http://127.0.0.1:7194/api/artworks/of-the-day", + "time": 7, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 7 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "282b1a9f-dee3-4f20-b9fe-1f9e8d7f51fc", + "name": "/api/media/:mediaId", + "url": "http://127.0.0.1:7194/api/media/5", + "time": 6, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 6 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "8e988f59-105a-48cd-adb0-eb24fbe0e37c", + "name": "/api/media/:mediaId", + "url": "http://127.0.0.1:7194/api/media/5", + "time": 13, + "responseCode": { + "code": 204, + "name": "No Content" + }, + "tests": { + "Successful PUT request": true + }, + "testPassFailCounts": { + "Successful PUT request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 13 + ], + "allTests": [ + { + "Successful PUT request": true + } + ] + }, + { + "id": "ba8cf599-07fb-4900-a311-c51a6a4cd453", + "name": "/api/media/:mediaId", + "url": "http://127.0.0.1:7194/api/media/5", + "time": 8, + "responseCode": { + "code": 204, + "name": "No Content" + }, + "tests": { + "Successful DELETE request": true + }, + "testPassFailCounts": { + "Successful DELETE request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 8 + ], + "allTests": [ + { + "Successful DELETE request": true + } + ] + }, + { + "id": "45f23529-086a-41e6-a9d8-102b988abd4c", + "name": "/api/media", + "url": "http://127.0.0.1:7194/api/media", + "time": 7, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful POST request": true + }, + "testPassFailCounts": { + "Successful POST request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 7 + ], + "allTests": [ + { + "Successful POST request": true + } + ] + }, + { + "id": "bea2b446-71e0-4bfc-91a8-90c2493eb2bb", + "name": "/api/media", + "url": "http://127.0.0.1:7194/api/media", + "time": 5, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 5 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "aeeadf11-7907-439f-a111-3246bb70b410", + "name": "/api/exhibitions/:exhibitionId", + "url": "http://127.0.0.1:7194/api/exhibitions/13", + "time": 4, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 4 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "21b2ec45-d907-482a-a170-1ad101e4bdab", + "name": "/api/exhibitions/:exhibitionId", + "url": "http://127.0.0.1:7194/api/exhibitions/13", + "time": 7, + "responseCode": { + "code": 204, + "name": "No Content" + }, + "tests": { + "Successful PUT request": true + }, + "testPassFailCounts": { + "Successful PUT request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 7 + ], + "allTests": [ + { + "Successful PUT request": true + } + ] + }, + { + "id": "febc5986-e851-44d8-9800-55d8172c549e", + "name": "/api/exhibitions/:exhibitionId", + "url": "http://127.0.0.1:7194/api/exhibitions/13", + "time": 5, + "responseCode": { + "code": 204, + "name": "No Content" + }, + "tests": { + "Successful DELETE request": true + }, + "testPassFailCounts": { + "Successful DELETE request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 5 + ], + "allTests": [ + { + "Successful DELETE request": true + } + ] + }, + { + "id": "7946353d-4fa6-4c0f-aeb1-c69e872cc9f3", + "name": "/api/exhibitions/:exhibitionId/artworks", + "url": "http://127.0.0.1:7194/api/exhibitions/14/artworks", + "time": 7, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 7 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "83dc1ac0-23b5-4f5c-af22-94c11b96d06e", + "name": "/api/exhibitions/:exhibitionId/assign/artwork/:artworkId", + "url": "http://127.0.0.1:7194/api/exhibitions/14/allocate/artwork/49", + "time": 6, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful POST request": true + }, + "testPassFailCounts": { + "Successful POST request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 6 + ], + "allTests": [ + { + "Successful POST request": true + } + ] + }, + { + "id": "315282b1-451f-4acc-bf2d-e6e3c58a6e20", + "name": "/api/exhibitions/:exhibitionId/deassign/artwork/:artworkId", + "url": "http://127.0.0.1:7194/api/exhibitions/14/deallocate/artwork/49", + "time": 6, + "responseCode": { + "code": 404, + "name": "Not Found" + }, + "tests": { + "Successful DELETE request": true + }, + "testPassFailCounts": { + "Successful DELETE request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 6 + ], + "allTests": [ + { + "Successful DELETE request": true + } + ] + }, + { + "id": "ec1f41bd-29ff-4b63-994c-f2443b8c2004", + "name": "/api/exhibitions", + "url": "http://127.0.0.1:7194/api/exhibitions", + "time": 5, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful GET request": true + }, + "testPassFailCounts": { + "Successful GET request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 5 + ], + "allTests": [ + { + "Successful GET request": true + } + ] + }, + { + "id": "ff0e966a-c2a1-4a98-9fff-92103e17bcd5", + "name": "/api/exhibitions", + "url": "http://127.0.0.1:7194/api/exhibitions", + "time": 5, + "responseCode": { + "code": 200, + "name": "OK" + }, + "tests": { + "Successful POST request": true + }, + "testPassFailCounts": { + "Successful POST request": { + "pass": 1, + "fail": 0 + } + }, + "times": [ + 5 + ], + "allTests": [ + { + "Successful POST request": true + } + ] + } + ], + "count": 1, + "totalTime": 226, + "collection": { + "requests": [ + { + "id": "f009c462-5a47-4bac-93af-5982e6fc766a", + "method": "GET" + }, + { + "id": "e6091a48-82c1-47e7-96b5-0b5e2d31c42b", + "method": "PUT" + }, + { + "id": "acdce390-dccd-4672-a340-8c49ebd39158", + "method": "DELETE" + }, + { + "id": "6b7a9de1-6920-4c6c-a003-8da1fcc891d0", + "method": "GET" + }, + { + "id": "f9173bc3-d889-4d1b-b50b-7be0cce4d5fc", + "method": "POST" + }, + { + "id": "c7ef026f-0aab-4d0f-a82f-b12b35303870", + "method": "GET" + }, + { + "id": "d501e368-82f8-4a32-9988-21e48cce9d71", + "method": "GET" + }, + { + "id": "7d4bbb4b-ac8a-4040-ac83-514b1dcfdbb5", + "method": "PUT" + }, + { + "id": "f4029369-aa35-4df8-8857-1d72b882a140", + "method": "DELETE" + }, + { + "id": "14da6b9b-ca48-4a91-acfd-7eebc7f7ff56", + "method": "POST" + }, + { + "id": "493fc9df-2859-4f99-8cd2-86e65cdb3e16", + "method": "DELETE" + }, + { + "id": "ce3753d4-3b82-4d7c-9370-24b8318fa81c", + "method": "GET" + }, + { + "id": "95d75c24-b6ca-45e8-8059-cf750077c158", + "method": "POST" + }, + { + "id": "544346e4-afee-4d82-9afe-95cc243a9d7c", + "method": "GET" + }, + { + "id": "282b1a9f-dee3-4f20-b9fe-1f9e8d7f51fc", + "method": "GET" + }, + { + "id": "8e988f59-105a-48cd-adb0-eb24fbe0e37c", + "method": "PUT" + }, + { + "id": "ba8cf599-07fb-4900-a311-c51a6a4cd453", + "method": "DELETE" + }, + { + "id": "45f23529-086a-41e6-a9d8-102b988abd4c", + "method": "POST" + }, + { + "id": "bea2b446-71e0-4bfc-91a8-90c2493eb2bb", + "method": "GET" + }, + { + "id": "aeeadf11-7907-439f-a111-3246bb70b410", + "method": "GET" + }, + { + "id": "21b2ec45-d907-482a-a170-1ad101e4bdab", + "method": "PUT" + }, + { + "id": "febc5986-e851-44d8-9800-55d8172c549e", + "method": "DELETE" + }, + { + "id": "7946353d-4fa6-4c0f-aeb1-c69e872cc9f3", + "method": "GET" + }, + { + "id": "83dc1ac0-23b5-4f5c-af22-94c11b96d06e", + "method": "POST" + }, + { + "id": "315282b1-451f-4acc-bf2d-e6e3c58a6e20", + "method": "DELETE" + }, + { + "id": "ec1f41bd-29ff-4b63-994c-f2443b8c2004", + "method": "GET" + }, + { + "id": "ff0e966a-c2a1-4a98-9fff-92103e17bcd5", + "method": "POST" + }, + { + "id": "cca5c39e-e6d3-446b-a2d8-c3262745344a", + "method": "GET" + } + ] + } +} diff --git a/docs/ArtGallery/Lighthouse Project/LighthouseReviewReport.md b/docs/ArtGallery/Lighthouse Project/LighthouseReviewReport.md new file mode 100644 index 000000000..a9385bf53 --- /dev/null +++ b/docs/ArtGallery/Lighthouse Project/LighthouseReviewReport.md @@ -0,0 +1,81 @@ +# Report on task: Review Research from T1 and create backlog + +I have reviewed two reports on the Lighthouse scores and identified the issues that needed to be +rectified. One report was a review on the desktop app and the other was a review on the mobile app. +Both had many errors so, I had to analyse both reports and did some research on finding +recommendations and solutions for the issue identified. + +## Desktop App + +For the desktop app, here are the problems/recommendations I have identified from the report: + +- Properly size images (add explicit width & height for images) +- Work on reducing network payloads +- Serve static assets with efficient cache policy +- Optimise the Largest Contentful Paint (make it faster): + - Eliminate resource load delay + - Eliminate element render delay + - Reduce resource load time + - Reduce time to first byte +- Reduce the impact of third-party code (identify slow third-party JavaScript) +- Reduce JavaScript execution time: + - Remove unused code + - Minify and compress code + - Implement code splitting + - Cache code with PRPL pattern +- Minimise main thread work: + - Evaluate the script (debounce input handlers, use web workers) + - Check style layout (reduce complexity of style calculations, avoid large, complex layouts). + - Rendering (manage layer count, simplify paint complexity, and reduce paint areas) + - Parse HTML and CSS (extract critical CSS, minify CSS, defer non-critical CSS) +- Reduce resource counts and transfer sizes (CSS & JavaScript, Images, Fonts, Documents, Media) +- Minify JavaScript +- Improve page loading speed: + - Using Preconnect to required origins + - Preload key requests +- Minimise critical request depth: + - Minimise number of critical resources (eliminate them, defer their download, etc) + - Optimize the number of critical bytes and reduce the download time + - Optimize the order for the remaining resources to be loaded (download all critical assets early + to shorten critical path length) + +## Mobile App + +For the mobile app, here are the problems/recommendations I have identified from the report: + +- Properly size images (add explicit width & height for images) +- Work on reducing network payloads +- Serve static assets with efficient cache policy +- Optimise the Largest Contentful Paint (make it faster): + - Eliminate resource load delay + - Eliminate element render delay + - Reduce resource load time + - Reduce time to first byte +- Improve mobile friendliness (appropriately size tap targets) +- Reduce the impact of third-party code (identify slow third-party JavaScript) +- Reduce JavaScript execution time: + - Remove unused code + - Minify and compress code + - Implement code splitting + - Cache code with PRPL pattern +- Minimise main thread work: + - Evaluate the script (debounce input handlers, use web workers) + - Check style layout (reduce complexity of style calculations, avoid large, complex layouts). + - Rendering (manage layer count, simplify paint complexity, and reduce paint areas) + - Parse HTML and CSS (extract critical CSS, minify CSS, defer non-critical CSS) +- Reduce resource counts and transfer sizes (CSS & JavaScript, Images, Fonts, Documents, Media) +- Minify JavaScript +- Improve page loading speed: + - Using Preconnect to required origins + - Preload key requests +- Minimise critical request depth: + - Minimise number of critical resources (eliminate them, defer their download, etc) + - Optimize the number of critical bytes and reduce the download time + - Optimize the order for the remaining resources to be loaded (download all critical assets early + to shorten critical path length) +- Shorten main-thread tasks +- Check and use discernible name for links +- Add meta description to document + +I have added cards and allocated story points for each of these problems and recommendations into +the Trello board under the ‘Lighthouse Project Implementation’ section. diff --git a/docs/ArtGallery/Lighthouse Project/SpikeUpskillingReport.md b/docs/ArtGallery/Lighthouse Project/SpikeUpskillingReport.md new file mode 100644 index 000000000..d20ddef73 --- /dev/null +++ b/docs/ArtGallery/Lighthouse Project/SpikeUpskillingReport.md @@ -0,0 +1,59 @@ +# Report on Upskilling + +## JavaScript basics with HTML and CSS + +I have spent some time upskilling to contribute to this project. So far, I have learnt the basics of +using JavaScript with HTML and CSS. I have completed a 7-hour course online and followed through +each chapter of the basics and I understand the basic concepts of working with these languages +together for web development. + +The online courses focused mainly on the fundamentals of JavaScript, HTML and CSS. I have learnt a +few important information from this course: + +- JavaScript basics +- Modifying text styles, text boxes and images using CSS +- Chrome DevTools – tool for debugging and inspecting code +- CSS Box Model – designing and positioning elements on a website. Structure of HTML + +### Courses for this upskilling + +- HTML to CSS Full Course (Beginner) +- JavaScript, HTML & CSS Basics + +## CSS and Javascript, vue.js upskilling + +I have learnt how to modify existing CSS code to remove unnecessary code without changing the +appearance of the website. I have also learnt how vue.js works and how to make changes to existing +code. This is to help with tasks related to improving network payloads, . Here is a list of what I +have learnt during this upskilling: + +- remove unused CSS code +- remove unused JavaScript code +- including webpacks to help with CSS & JS codes +- purpose of vue.js, and how it functions + +### Topics covered + +- Removing unused CSS, JavaScript and HTML code +- Learn webpacks to help minify CSS, JavaScript and HTML +- Vue.js for beginners + +## Lazy loading, TreeShaking and Ant Design upskilling + +I have learnt how to implement lazy routing and TreeShaking into the existing code to help with some +performance issues. I have also learnt about Ant Design, it's purpose and how it works. This +upskilling helps with tasks related to PRPL and modifying/reducing impact of thirs party code. I +have learnt the following: + +- What is lazy routing +- How to properly implement lazy loading +- What is TreeShaking and what does it to +- How to implement TreeShaking +- What is Ant Design and why is it used + +### Topics covered for this upskilling + +- Vue router tutorial +- Lazy routing and code splitting +- What is TreeShaking and how to implement +- Ant Design courses diff --git a/docs/ConvertTrello.py b/docs/ConvertTrello.py new file mode 100644 index 000000000..8fca63656 --- /dev/null +++ b/docs/ConvertTrello.py @@ -0,0 +1,78 @@ +import json +import csv + +# Load the JSON file +with open('Trello.json', 'r') as file: + data = json.load(file) + +# Define the backlogs of interest/Sprints Of interest +backlogs_of_interest_names = [ + "Sprint 1 -Upstream Review", "Sprint 1 Complete", + "Sprint 2 Code Review", "Sprint 2 -Upstream Review", "Sprint 2 Complete", + "Sprint 3 Review", "Sprint 3 Complete", + "Sprint 4 Review", "Sprint 4 Complete", + "Numbas - Code-Review", "Numbas - Complete" +] + +# Map the list names to their IDs/Names +list_id_to_name_mapping = {} +backlogs_of_interest = [] + +for list_ in data["lists"]: + if list_["name"] in backlogs_of_interest_names: + backlogs_of_interest.append(list_["id"]) + list_id_to_name_mapping[list_["id"]] = list_["name"] + + +# Extract members +members = {member["id"]: member["fullName"] for member in data["members"]} + +# Process cards +cards_by_member = {} +total_story_points = {} +for card in data["cards"]: + if card["idList"] in backlogs_of_interest: + for member in card["idMembers"]: + if member in cards_by_member: + cards_by_member[member].append(card) + else: + cards_by_member[member] = [card] + + # Extract story points + story_points = 0 + for plugin_data in card.get("pluginData", []): + if "storyPoints" in plugin_data["value"]: + story_points = int(json.loads(plugin_data["value"])["storyPoints"]) + + # Update total story points for member + if member in total_story_points: + total_story_points[member] += story_points + else: + total_story_points[member] = story_points + +# Write the CSV +with open('OntrackTrelloReview.csv', 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(["Sprint", "Full Name", "Card Name", "GitHub Link", "Story Points", "Total Story Points"]) + + for member_id, cards in cards_by_member.items(): + for index, card in enumerate(cards): + # Extract story points for the current card + story_points = 0 + for plugin_data in card.get("pluginData", []): + if "storyPoints" in plugin_data["value"]: + story_points = int(json.loads(plugin_data["value"])["storyPoints"]) + + # Check for GitHub related info + github_link = None + for attachment in card.get("attachments", []): + if "github.com" in attachment["url"]: + github_link = attachment["url"] + break + + # Determine if we should show the total story points for this row + show_total = total_story_points[member_id] if index == len(cards) - 1 else "" + + sprint_name = list_id_to_name_mapping[card["idList"]] + writer.writerow([sprint_name, members[member_id], card["name"], github_link, story_points, show_total]) + diff --git a/docs/OnTrack/Front End Migration/Research & Findings/Spikes/SpikeOutcome - Data Analytics.md b/docs/OnTrack/Front End Migration/Research & Findings/Spikes/SpikeOutcome - Data Analytics.md new file mode 100644 index 000000000..3fbfa37f6 --- /dev/null +++ b/docs/OnTrack/Front End Migration/Research & Findings/Spikes/SpikeOutcome - Data Analytics.md @@ -0,0 +1,44 @@ +# \*\*Spike Outcomes + +================== + +**Spike:** Spike_No + +**Title:** Data Analytics Spike + +**Author:** Dylan Sutherland, + +## Goals / Deliverables + +Summarise from the spike plan goal*Besides this report, what else was created ie UML, code, reports* + +- Data Analytics backlog on Trello + +## Technologies, Tools, and Resources used + +List of information needed by someone trying to reproduce this work\ + +- Internet Browser; Google Chrome, FireFox, Safari + +## Tasks undertaken + +List key tasks likely to help another developer + +- Engaged in Discussion with Andrew Cain +- Created a Trello backlog for the continued development of Data Analytics + +## What we found out + +The Data Analytics feature as it currently exists in OnTrack provides a limited set of +visualisations given the data available. The current visualisations are: Target Grade Pie Chart, +Task Status Pie Chart & Task Completion Box Plot. For the future development of Data Analytics, +although integrated visualisations will continue to play a key role in providing a quick overview of +the data, the ability to export the data to a third party tool such as Tableau or PowerBI will be a +key feature. This will allow for more complex visualisations to be created and for the data to be +analysed in more depth. The current visualisations will need to be migrated to the latest version of +Angular and maintained as they provide a quick overview of the data. One particular area where the +current visualisations are lacking is the ability to track interaction time such as tutor time to +provide task feedback, this is a key visualisation which could be added to the existing +visualisations. In parallel to extending the current visualisations, the requirements of the export +feature will be investigated including a questionnaire to understand the needs of Unit chairs and +tutors, before designing UML diagrams and implementing the feature. diff --git a/docs/OnTrack/Incorporate Content Ontrack/Section_1.png b/docs/OnTrack/Incorporate Content Ontrack/Section_1.png new file mode 100644 index 000000000..b3da99c6a Binary files /dev/null and b/docs/OnTrack/Incorporate Content Ontrack/Section_1.png differ diff --git a/docs/OnTrack/Incorporate Content Ontrack/Section_2.png b/docs/OnTrack/Incorporate Content Ontrack/Section_2.png new file mode 100644 index 000000000..80d9558cf Binary files /dev/null and b/docs/OnTrack/Incorporate Content Ontrack/Section_2.png differ diff --git a/docs/OnTrack/Incorporate Content Ontrack/Section_3.png b/docs/OnTrack/Incorporate Content Ontrack/Section_3.png new file mode 100644 index 000000000..482b9b1a4 Binary files /dev/null and b/docs/OnTrack/Incorporate Content Ontrack/Section_3.png differ diff --git a/docs/OnTrack/Incorporate Content Ontrack/Section_4.png b/docs/OnTrack/Incorporate Content Ontrack/Section_4.png new file mode 100644 index 000000000..81732431c Binary files /dev/null and b/docs/OnTrack/Incorporate Content Ontrack/Section_4.png differ diff --git a/docs/OnTrack/Incorporate Content Ontrack/Section_5.png b/docs/OnTrack/Incorporate Content Ontrack/Section_5.png new file mode 100644 index 000000000..4c364e552 Binary files /dev/null and b/docs/OnTrack/Incorporate Content Ontrack/Section_5.png differ diff --git a/docs/OnTrack/Tutor Times/Documentation/DESIGN-BACK-END.md b/docs/OnTrack/Tutor Times/Documentation/DESIGN-BACK-END.md new file mode 100644 index 000000000..5a2f7412a --- /dev/null +++ b/docs/OnTrack/Tutor Times/Documentation/DESIGN-BACK-END.md @@ -0,0 +1,143 @@ +# Backend Design Document for "Tutor Times" Feature in OnTrack + +## 1. Introduction + +### 1.1 Purpose + +This document outlines the design of the backend for the "Tutor Times" feature in OnTrack (formerly +known as Doubtfire). The purpose is to establish the architectural and functional aspects of the +backend necessary to support efficient time tracking and management for tutors. + +### 1.2 Scope + +The scope of this design document covers the following aspects of the backend development for the +"Tutor Times" feature: + +- Data Models and Schema +- API Endpoints +- Authentication and Authorisation +- Background Jobs/Triggers +- Data Integrity Constraints +- Performance Optimization +- Security Measures +- Compatibility with Frontend and Other Modules + +### 1.3 Intended Audience + +This document is intended for backend developers, database administrators, and stakeholders involved +in the implementation of the "Tutor Times" feature. + +## 2. Architecture and Data Models + +- A link for UML diagrams will be provided here in future to illustrate the architecture and data + models for the "Tutor Times" feature. + +### 2.1 Data Storage + +- Create a new database table named `tutor_times` or modify an existing one to store marking time + data for tutors and students. +- Define fields such as `tutor_id`, `student_id`, `task_id`, `start_time`, and `end_time` to record + marking session details. + +### 2.2 Data Schema + +- Define a comprehensive data schema that includes relationships between tables to support the + required functionality. +- Ensure that the schema accommodates storing marking time data at both the student and task levels. + +### 2.3 Database Relationships + +- Establish relationships between tables to associate marking time data with tutors, students, and + tasks. +- Define foreign keys and indices to optimize query performance. + +## 3. API Design + +### 3.1 API Endpoints + +- Develop a set of RESTful API endpoints to interact with marking time data. +- Implement the following endpoints: + - `POST /api/tutor-times`: Create a new marking session record. + - `GET /api/tutor-times/:id`: Retrieve a specific marking session record. + - `GET /api/tutor-times/tutor/:tutor_id`: Retrieve all marking session records for a specific + tutor. + - `GET /api/tutor-times/student/:student_id`: Retrieve all marking session records for a specific + student. + - `PUT /api/tutor-times/:id`: Update an existing marking session record. + - `DELETE /api/tutor-times/:id`: Delete a marking session record. + +### 3.2 Authentication and Authorisation + +- Implement user authentication and authorisation to secure access to marking time data. +- Ensure that only authorised users (tutors and unit chairs) can perform CRUD operations on marking + session records. + +## 4. Background Jobs/Triggers + +### 4.1 Calculation of Marking Time Totals + +- Develop background jobs or database triggers to calculate and update total marking time for each + tutor and student. +- The system should automatically update marking time totals when new marking session records are + added or modified. + +## 5. Data Integrity and Validation + +### 5.1 Data Integrity Constraints + +- Implement data integrity constraints to ensure the accuracy and consistency of data. +- Enforce rules such as referential integrity and data type validation to maintain data quality. + +## 6. Non-Functional Requirements + +### 6.1 Performance Optimization + +- Optimize database queries and operations to ensure fast data retrieval, even as the volume of + marking time records grows. +- Implement caching mechanisms to reduce query load and enhance system performance. + +### 6.2 Security Measures + +- Implement necessary security measures to protect marking time data and prevent unauthorized + access. +- Use encryption to secure sensitive data, such as user credentials. + +### 6.3 Compatibility + +- Ensure compatibility with the frontend and other system components. +- Verify that the API endpoints work seamlessly with modern web browsers and other clients. + +## 7. Testing Strategy + +### 7.1 Unit Testing + +- Develop comprehensive unit tests for API endpoints, database interactions, and background jobs to + ensure the correctness and reliability of backend components. + +### 7.2 Integration Testing + +- Perform integration testing to verify the seamless integration of backend components with the + frontend and other system modules. + +## 8. Deployment Plan + +### 8.1 Deployment Environment + +- Deploy the backend of the "Tutor Times" feature to the production environment of OnTrack. + +### 8.2 Deployment Process + +- Follow a systematic deployment process to release backend updates, including version control and + continuous integration practices. + +## 9. Conclusion + +This design document provides a detailed plan for the backend implementation of the "Tutor Times" +feature in OnTrack. It covers the architectural aspects, data models, API design, security measures, +testing strategies, and deployment plans. By following this design, we ensure the reliable and +efficient operation of the "Tutor Times" feature, enhancing the user experience for tutors and +students. + +## 10. Appendices + +- Include any additional information, diagrams, or references that support the design document. diff --git a/docs/Splashkit/Applications/Tutorials and Research/Tutorial Proposals/Tutorial Markdowns/Getting Started With SplashKit Database.md b/docs/Splashkit/Applications/Tutorials and Research/Tutorial Proposals/Tutorial Markdowns/Getting Started With SplashKit Database.md new file mode 100644 index 000000000..64eb84773 --- /dev/null +++ b/docs/Splashkit/Applications/Tutorials and Research/Tutorial Proposals/Tutorial Markdowns/Getting Started With SplashKit Database.md @@ -0,0 +1,318 @@ +# Getting Started With SplashKit Database + +## Introduction + +### What is SplashKit Database? + +SplashKit has a database library that allows you to create or load databases and perform queries on +them. These databases are stored in database files, and with functions from the SplashKit library, +we can query and manipulate the database. + +### Usage + +You may have learned the use of database, which is for storing information. On SplashKit, you may +want to use database to store information of different users who have access to the game, such as +levels, high score, or save files. You may also want to use databases when creating data heavy +games, e.g., to store information about all the different items, skills, weapons, etc. available in +game. + +## Opening Database in SplashKit + +### Database + +Accessed databases are stored in the `Database` object. + +### Open Database + +`Open Database` is the function used to access or create a database file. If the filename used in +the parameter is an existing database, it will retrieve and access the file. Otherwise, it will +create a new database file with the provided filename. + +Syntax in C++: + +``` +database open_database(string name, string filename) +``` + +### Has Database + +`Has Database` is a boolean fuction used to check if the database with the given name has been +loaded into the program, and return either true or false accordingly. + +Syntax in C++: + +``` +bool has_database(string name) +``` + +### Database Named + +`Database Named` is a function that retrieves the database that has been opened with +`Open Database`. This is useful when you want to use the database without storing it into a +variable. + +Syntax in C++: + +``` +database database_named(string name) +``` + +### Free Database + +After you have finished using your database, you should free the resource using `Free Database`. +There are two versions of the function, one where you use the database object as the parameter, and +one where you use the name of the database for the parameter. + +Syntax in C++: + +``` +void free_database(database db_to_close) +``` + +``` +void free_database(string name_of_db_to_close) +``` + +### Free All Databases + +Another way of freeing all databases at once is using the `Free All Databases` function. + +Syntax in C++: + +``` +void free_all_databases() +``` + +### Demonstration + +``` +int main() +{ + // Open database named "test" from a file named "test_database" + open_database("test", "test_database"); + + // Check if database has been loaded + if (has_database("test")) + { + // Store database to a variable x + database x = database_named("test"); + } + + // Free the database since we are done + free_all_databases(); + + // Alternatives + // free_database("test"); + // free_database(x); +} +``` + +## Performing a Query on the Database + +### Query Result + +`Query Result` is another important data type related to database. This is used to store the result +after performing a query on a database. + +### Run Sql + +`Run Sql` performs an sql command to the database and returns the result as a `Query Result`. Either +the database object or the string name can be used to pass the database on to the function. + +Syntax in C++: + +``` +query_result run_sql(database db, string sql) +``` + +``` +query_result run_sql(string database_name, string sql) +``` + +### Query Success + +`Query Success` can be used to check if the most recent query on a `Query Result` was successful or +not. Syntax in C++: + +``` +bool query_success(query_result db_result) +``` + +### Query Column For Boolean + +`Query Column For Boolean` is used to access a column of a `Query Result` which consists of booleans +at the current row (the top row). + +Syntax in C++: + +``` +bool query_column_for_bool(query_result db_result, int col) +``` + +### Query Column For Double + +`Query Column For Double` is similar to the previous function, except it is used when the data type +is double. + +Syntax in C++: + +``` +double query_column_for_double(query_result db_result, int col) +``` + +### Query Column For Integer + +Similar to the previous two functions, this has the same usage except it is for integers. + +Syntax in C++: + +``` +int query_column_for_int(query_result db_result, int col) +``` + +### Query Column For String + +The final query column function performs similarly to the other functions, where it is used for +strings. + +Syntax in C++: + +``` +string query_column_for_string(query_result db_result, int col) +``` + +### Query Type Of Col + +`Query Type Of Col` is used to check what the data type of the column is. This is useful when you +don't know what data types are used in the database. + +Syntax in C++: + +``` +string query_type_of_col(query_result db_result, int col) +``` + +### Rows Changed + +This function is used to check how many rows has been changed on a database the last time a changing +query was performed on the database. + +Syntax in C++: + +``` +int rows_changed(database db) +``` + +### Free Query Result + +Similar to a `Database`, we should free `Query Result` that we have finished using. + +Syntax in C++: + +``` +void free_query_result(query_result query) +``` + +### Free All Query Results + +`Free All Query Results` can be used to free all `Query Results` at once. + +Syntax in C++: + +``` +void free_all_query_results() +``` + +### Demonstration + +``` +int main() +{ + // Open database named "users" with a table "Users" and the collumns "UID", "Name" + open_database("users", "users_database"); + + // Create a query result to store results + query_result result; + int uid; + string name; + + // Perform SQL to add a new user + run_sql("users", "INSERT INTO Users VALUES('001', 'John');"); + + // Now, if rows_changed(database_named("users")); is used, it should return 1. + + // Perform SQL to get the whole table + result = run_sql("users", "SELECT * FROM Users;"); + + // Get the values into variables + uid = query_column_for_integer(result, 0); + name = query_column_for_string(result, 1); + + // Free the resources since we are done + free_all_databases(); + free_all_query_results(); +} +``` + +## Iterating Through a Database + +You may have noticed that the `Query Column` functions only get the data from the first row of the +`Query Result`. This section will show you how to access the other rows, and iterating through the +whole table. + +### Get Next Row + +`Get Next Row` checks if there is a valid row and moves you to the next row of the `Query Result`. +It is a boolean function that will return either true or false depending on whether the next row +exists or not. + +Syntax in C++: + +``` +bool get_next_row(query_result db_result) +``` + +### Has Row + +Syntax in C++: + +``` +bool has_row(query_result db_result) +``` + +### Reset Query Result + +Syntax in C++: + +``` +void reset_query_result(query_result db_result) +``` + +### Demonstration + +Sample data of "test_database": + +Table | ID | | ---- | | 0 | | 1 | | 2 | + +``` +int main() +{ + // Open a database from a file "test_database" which has a table "Table" with the collumn "ID" + open_database("test", "test_database"); + + query_result result = run_sql("test", "SELECT * From Table";); + + // Check if there is a valid row since the table may be empty + if (has_row(result)) + { + do + { + int id = query_column_for_integer(result, 0); // This will return the values 0, 1, and 2 + + } while (get_next_row(result)) // Loop while there is a valid next row + } + + free_all_databases(); + free_all_query_results(); +} +```