{"id":23819825,"url":"https://github.com/kth/kursutveckling-admin-web","last_synced_at":"2025-09-07T02:30:49.420Z","repository":{"id":41220177,"uuid":"175628729","full_name":"KTH/kursutveckling-admin-web","owner":"KTH","description":"En app som ger stöd för att publicera information om kursens utveckling och historik i Kurs- och programkatalogen. Sidan innehåller tjänster för att publicera kursanalyser med kursdata för en specifik kurs.","archived":false,"fork":false,"pushed_at":"2025-08-21T11:34:06.000Z","size":33334,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-08-21T13:29:43.756Z","etag":null,"topics":["blobstorage","kursutveckling","react","react-mobx","reactjs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KTH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-03-14T13:34:22.000Z","updated_at":"2025-08-21T11:34:12.000Z","dependencies_parsed_at":"2023-11-20T12:25:50.103Z","dependency_job_id":"1f2d6a03-7e3f-4aa3-9115-4282810599f0","html_url":"https://github.com/KTH/kursutveckling-admin-web","commit_stats":{"total_commits":646,"total_committers":61,"mean_commits":10.59016393442623,"dds":0.7863777089783281,"last_synced_commit":"3316b41169cf6572261afde98d847741a08f9f56"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/KTH/kursutveckling-admin-web","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fkursutveckling-admin-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fkursutveckling-admin-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fkursutveckling-admin-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fkursutveckling-admin-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KTH","download_url":"https://codeload.github.com/KTH/kursutveckling-admin-web/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fkursutveckling-admin-web/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273987277,"owners_count":25202842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blobstorage","kursutveckling","react","react-mobx","reactjs"],"created_at":"2025-01-02T07:16:03.170Z","updated_at":"2025-09-07T02:30:49.412Z","avatar_url":"https://github.com/KTH.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Welcome to kursutveckling-admin-web 👋\n\n![Version](https://img.shields.io/badge/version-2.0.0-blue.svg?cacheSeconds=2592000)\n![Prerequisite](https://img.shields.io/badge/node-18-blue.svg)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](#)\n\n## Introduction\n\nThe course information project (KIP) is an initiative at KTH that was launched in 2018 to improve the quality and availability of information about KTH:s courses. The background to the project is, among other things, that it was difficult for the student to find information about the courses and even more difficult to compare information about several courses. The reason for the problems is scattered course information in several places and that there is no uniformity or assigned places for the course information. The project takes measures to consolidate course information into two locations and to present the information in a manner that is uniform for KTH. The student should find the right information about the course, depending on their needs. The result of the project is a public course site where the correct course information is collected and presented uniformly. Also, a tool is developed for teachers to enter and publish course information. Eventually, this will lead to the student making better decisions based on their needs, and it will also reduce the burden on teachers and administration regarding questions and support for the student.\n\n**Kursutveckling-admin-web** is\n\n\u003e En app som ger stöd för att publicera information om kursens utveckling i Kurs- och programkatalogen. Sidan innehåller tjänster för att publicera kursanalyser med kursdata för en specifik kurs.\n\nThe app is based on [https://github.com/KTH/node-web](https://github.com/KTH/node-web).\n\n### 🏠 [Homepage](https://github.com/KTH/kursutveckling-admin-web)\n\n## Overview\n\nFirstly, the app has two functions:\n\n- to upload a course analysis and historic course memo pdf files to a blob storage and send course data about it to `kursutveckling-api`.\n- to change a published course data analysis\n- automatic fill in data about course development fetching from kopps-api and kursstatistik api (reading from ladok db)\n\nLater this files and course development data can be found on public pages 'Course development' served by `kursutveckling-web`.\n\nUser can choose several course offerings and edit fetched course data it will be noted that data were changed manually. Pdf files upload to a blob storage while in a database data about file and course offering will be saved with a list of course offerings.\n\n- The app consists of two pages which is used to create a new course development data and to change a published one. To do it user will go through three step: Choose a course offering(s), write data, upload a course analysis pdf file, optionally course memo pdf file (history), review it, save it as a draft or publish it.\n\n```\nlocalhost:3000/kursinfoadmin/kursutveckling/:courseCode\n```\n\n- There is a page called Preview, which is used to show a draft data to a person who gets a link and has other type of teacher rights to access this course, only read rights\n\n```\nlocalhost:3000/kursinfoadmin/kursutveckling/:preview/:id\n```\n\n### API:s\n\nApplication is fetching data from KOPPS-API for:\n\n- Course title\n- Course offerings which are/were active for this course\n\nApplication is fetching data from KURSUTVECKLING-API for:\n\n- Fetch course offerings which have a draft or published version of course data to sort per termin and filter course offerings fetched from KOPPS-API.\n\n- Fetch course data and pdf names for chosen course offerings if user want to change it\n\n- [https://github.com/KTH/kurs-pm-api](https://github.com/KTH/kurs-pm-api)\n\nApplication is fetching data from KURSSTATISTIK-API for:\n\n- Fetch data and calculate result, number of students and so on from LADOK database\n\n- [https://github.com/KTH/kursstatistik-api](https://github.com/KTH/kursstatistik-api)\n\nApplication is fetching data from ug-rest-api:\n\n- Fetch data about course staff (because some information missing in Kopps, f.e., examinators)\n\n- Base authorization who can see which pages\n\n### Related projects\n\n- [https://github.com/KTH/kursutveckling-web](https://github.com/KTH/kursutveckling-web)\n- [https://github.com/KTH/kursutveckling-api](https://github.com/KTH/kursutveckling-api)\n- [https://github.com/KTH/kursstatistik-api](https://github.com/KTH/kursstatistik-api)\n- [https://gita.sys.kth.se/Infosys/ugcache](https://gita.sys.kth.se/Infosys/ugcache)\n\nWe must try to make changes that affect the template projects in the template projects themselves.\n\n- [https://github.com/KTH/node-web](https://github.com/KTH/node-web)\n\n## Prerequisites\n\n- node 18\n\n### Blob storage. Generate Shared access signature\n\n- blob container (STORAGE_CONTAINER_NAME) `kursutveckling-blob-container`\n- Allowed permissions: _Read, Write, Create_\n\nWhile images uploads directly to a blob container located in a cloud in the storage account, f.e., `kursinfostoragestage`, the name of uploaded image will be saved in `kurs-pm-api`.\nTo connect to blob storage, the Shared access signature is used to limit what can be done by using this signature, f.e., only read, or write and which services. In stage environment keys were generated on base of key2.\nFor each service generated a separate Shared access signature and saved(f.e., SAS-REF-blob-service-sas-url-kursutveckling-admin-web) in standard key vault.\n\nIt requires package `\"@azure/storage-blob\": \"^12.2.1\"`. Further to parse a file between client and server, you need to have npm package `body-parser`. More details in `server/blobStorage.js`.\n\n#### Blob storage. Generate Shared access signature\n\nTo generate it, go to a storage account, f.e., `kursinfostoragestage`, choose Shared Access signature and choose:\n\n- Allowed services: _Blob_\n- Allowed resource types: _Object_\n- Allowed permissions: _Read, Write, Create_\n- Start and expiry date/time\n- HTTPS only\n- Signing key: key1 or key2\n\nAfter a generation of a key, copy **Blob service SAS URL** and save it in a standard key vault and set **Expiration Date**.\nLater you will use it as a _BLOB_SERVICE_SAS_URL_ in secrets together with a name of blob container STORAGE_CONTAINER_NAME\n\n### Secrets for Development\n\nSecrets during local development are ALWAYS stored in a `.env`-file in the root of your project. This file should be in .gitignore.\n\nIMPORTANT: In Prod env, save URL:s in docker file but secrets in secrets.env\n\n```\nKOPPS_URI=https://api-r.referens.sys.kth.se/api/kopps/v2/?defaultTimeout=5000\nKURSUTVECKLING_API_URI=http://localhost:3003/api/kurs-pm [check api port]\nAPI_KEY=[secret key to connect to kursutveckling-api]\nKURSSTATISTIK_API_URI=https://localhost:[api port]/api/kursstatistik?defaultTimeout=100000\nKURSSTATISTIK_API_KEY=[secret key to connect to kursstatistik-api]\nSESSION_SECRET=[something random]\nSESSION_KEY=kursutveckling-admin-web.pid\nOIDC_APPLICATION_ID=\u003cFROM ADFS\u003e\nOIDC_CLIENT_SECRET=\u003cFROM ADFS\u003e\nOIDC_TOKEN_SECRET=\u003cRandom string\u003e\nREDIS_URI=[connection string to redis, for cache]\nBLOB_SERVICE_SAS_URL=[f.e., https://kursinfostoragestage.blob.core.windows.net/[params]\u0026spr=https\u0026sig=[generated signature]]\nSTORAGE_CONTAINER_NAME=kursutveckling-blob-container\n/*If you want to start your server on another port, add the following two variables, else use default ones from serversettings.js*/\nSERVER_PORT=[your port for the server]\nSERVER_HOST_URL=http://localhost:[SERVER_PORT]\nLOGGING_LEVEL=DEBUG [only for dev env]\n/* Connection Properties of UG Rest Api to fetch names of course staff */\nUG_REST_AUTH_API_TOKEN_URI=https://\u003cLOGIN_HOST\u003e/adfs/\nUG_REST_AUTH_CLIENT_ID=\u003cFROM AZURE KEYVAULT\u003e\nUG_REST_AUTH_CLIENT_SECRET=\u003cFROM AZURE KEYVAULT\u003e\nUG_REST_API_URI=https://\u003cUG_URL\u003e\nUG_REST_API_SUBSCRIPTION_KEY=\u003cFROM AZURE INTEGRAL OR KEYVAULT\u003e\n```\n\nThese settings are also available in an `env.in` file.\n\n### Install\n\nFirst time you might need to use options `--ignore-scripts` because of npm resolutions:\n\n```sh\nnpm install --ignore-scripts\n```\n\nor\n\n```sh\nnpm install\n\n```\n\nYou might need to install as well:\n\n```sh\nnpm install cross-env\nnpm install concurrently\n```\n\n### Usage\n\nStart the service on [http://localhost:3000/kursinfoadmin/kursutveckling/:courseCode](http://localhost:3000/kursinfoadmin/kursutveckling/:courseCode).\n\n```sh\nnpm run start-dev\n```\n\n### Debug in Visual Studio Code\n\nIt's possible to use debugging options available in Visual Studio Code\nAdd a file `launch.json` to `.vscode` directory :\n\n- _Microsoft_\n\n```json\n{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"type\": \"node\",\n      \"request\": \"launch\",\n      \"name\": \"Debug kursutveckling-admin-web\",\n      \"program\": \"${workspaceFolder}\\\\app.js\",\n      \"envFile\": \"${workspaceFolder}\\\\.env\",\n      \"env\": {\n        \"NODE_ENV\": \"development\"\n      }\n    }\n  ]\n}\n```\n\n- _Mac, Unix and so on_\n\n```json\n{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"type\": \"node\",\n      \"request\": \"launch\",\n      \"name\": \"Debug kursutveckling-admin-web\",\n      \"program\": \"${workspaceFolder}/app.js\",\n      \"envFile\": \"${workspaceFolder}/.env\",\n      \"env\": {\n        \"NODE_ENV\": \"development\"\n      }\n    }\n  ]\n}\n```\n\n## Run tests\n\n```sh\nnpm run test\n```\n\n## Use 🐳\n\n`API_KEY` in `docker-compose.yml` is configured for a local kurs-pm-api, and might as well be changed to kurs-pm-api in ref.\n\n```sh\ndocker-compose up\n```\n\n## Customizations\n\n### Handlebar Templates\n\n_Update 2021-03-12: Dependency to `kth-node-build-commons` has since been removed altogether._\n\n\u003e Paths in the app have been altered, so the use of _Handlebar_ templates has been customized. The files `errorLayout.handlebars` and `error.handlebars` were copied from `kth-node-build-commons`. This meant that the script `move-handlebars` could be removed from `package.json`. In `errorLayout.handlebars` the path for `vendor.js` was customized, and in `error.handlebars` the reference to `errorModule.js` was removed altogether.\n\n## Author\n\n👤 **KTH**\n\n- Website: https://kth.github.io/\n- Github: [@KTH](https://github.com/KTH)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkth%2Fkursutveckling-admin-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkth%2Fkursutveckling-admin-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkth%2Fkursutveckling-admin-web/lists"}