From 0f6c5b181ec9534f88c5a021a61fcc2a605fb1a9 Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Thu, 26 Jan 2023 11:16:45 +0100 Subject: [PATCH 1/9] feat: Add new api urls but this is only for updating the db, not need to merge into master --- server/controllers/memoDataCtrl.js | 55 ++++++++++++++++++ server/server.js | 6 +- swagger.json | 92 ++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) diff --git a/server/controllers/memoDataCtrl.js b/server/controllers/memoDataCtrl.js index 8c58edd..0844834 100644 --- a/server/controllers/memoDataCtrl.js +++ b/server/controllers/memoDataCtrl.js @@ -73,6 +73,44 @@ async function getDraftByEndPoint(req, res) { } } +async function putMemoByMemoEndPointAndCourseCodeAndSemester(req, res) { + // STEP 2 EDITING: USE IT IN A SECOND STEP + try { + const memoObj = req.body + const { courseCode, memoEndPoint, semester } = req.params + + const dbResponse = [] + + const draftExist = await dbOneDocument.fetchMemoByMemoEndpointAndCourseCodeAndSemester( + memoEndPoint, + courseCode, + semester + ) + + if (draftExist) { + log.info( + 'memo draft already exists,' + memoEndPoint + ' so it will be updated (object id ' + draftExist._id + ')' + ) + dbResponse.push( + await dbOneDocument.updateMemoByMemoEndPointAndCourseCodeAndSemester( + memoEndPoint, + courseCode, + semester, + memoObj + ) + ) + } else { + log.debug('no memo draft was found to update with id: ', memoEndPoint) + } + + log.info('dbResponse length', dbResponse.length, { memoEndPoint }) + res.status(201).json(dbResponse) + } catch (error) { + log.error('Error in while trying to putMemoById', { error }) + return error + } +} + async function putDraftByEndPoint(req, res) { // STEP 2 EDITING: USE IT IN A SECOND STEP try { @@ -172,6 +210,21 @@ async function createDraftByMemoEndPoint(req, res) { } } +async function getAllMemosByCourseCode(req, res) { + // TODO: ADD FETCHING USED COURSE ROUNDS (DRAFTS + PUBLISHED) + const { courseCode } = req.params + log.info('getAllMemosByCourseCode: Received request for memo for course:', { courseCode }) + try { + const dbResponse = await dbArrayOfDocument.getAllMemosByCourse(courseCode) + + res.json(dbResponse || []) + log.info('getAllMemosByCourseCode: Responded to request for memo:', { courseCode }) + } catch (err) { + log.error('getAllMemosByCourseCode: Failed request for memo, error:', { err }) + return err + } +} + async function getAllMemosByCourseCodeAndType(req, res) { // TODO: ADD FETCHING USED COURSE ROUNDS (DRAFTS + PUBLISHED) const { courseCode, type } = req.params @@ -259,10 +312,12 @@ module.exports = { createDraftByMemoEndPoint, getDraftByEndPoint, getPublishedMemoByEndPoint, + getAllMemosByCourseCode, getAllMemosByCourseCodeAndType, getMemosStartingFromPrevSemester, getCourseSemesterUsedRounds, deleteDraftByMemoEndPoint, postNewVersionOfPublishedMemo, putDraftByEndPoint, + putMemoByMemoEndPointAndCourseCodeAndSemester, } diff --git a/server/server.js b/server/server.js index 01e6cf5..9c16341 100644 --- a/server/server.js +++ b/server/server.js @@ -1,7 +1,7 @@ 'use strict' -const server = require('@kth/server') const path = require('path') +const server = require('@kth/server') // Load .env file in development mode const nodeEnv = process.env.NODE_ENV && process.env.NODE_ENV.toLowerCase() @@ -143,8 +143,8 @@ addPaths( const authByApiKey = passport.authenticate('apikey', { session: false }) // Application specific API enpoints -const { CourseMemo, MixedWebAndPdfMemosList } = require('./controllers') const { ApiRouter } = require('kth-node-express-routing') +const { CourseMemo, MixedWebAndPdfMemosList } = require('./controllers') const apiRoute = ApiRouter(authByApiKey) const paths = getPaths() @@ -158,12 +158,14 @@ apiRoute.register(paths.api.getMemoVersion, CourseMemo.getMemoVersion) // step 2 // Get one draft | update it apiRoute.register(paths.api.getDraftByEndPoint, CourseMemo.getDraftByEndPoint) // step 2: editor, fetch data apiRoute.register(paths.api.updateCreatedDraft, CourseMemo.putDraftByEndPoint) // step 2: editor, fast update +apiRoute.register(paths.api.updatedMemoById, CourseMemo.putMemoByMemoEndPointAndCourseCodeAndSemester) // step 1: choose action, new draft, or copied draft from published memo (same memoEndPoint) apiRoute.register(paths.api.createDraftByMemoEndPoint, CourseMemo.createDraftByMemoEndPoint) apiRoute.register(paths.api.copyFromAPublishedMemo, CourseMemo.createDraftByMemoEndPoint) // // GET ARRAY OF MEMOS BY TYPE AND COURSE CODE +apiRoute.register(paths.api.getAllMemosByCourseCode, CourseMemo.getAllMemosByCourseCode) apiRoute.register(paths.api.getAllMemosByCourseCodeAndType, CourseMemo.getAllMemosByCourseCodeAndType) apiRoute.register(paths.api.getCourseSemesterUsedRounds, CourseMemo.getCourseSemesterUsedRounds) // step 1: to show up which rounds already taken apiRoute.register(paths.api.getMemosStartingFromPrevYearSemester, CourseMemo.getMemosStartingFromPrevSemester) // step 1: to show up which rounds already taken diff --git a/swagger.json b/swagger.json index 1ab6a70..1a416b7 100644 --- a/swagger.json +++ b/swagger.json @@ -230,6 +230,62 @@ ] } }, + "/v1/memo/{memoEndPoint}/{courseCode}/{semester}": { + "put": { + "operationId": "updatedMemoById", + "summary": "The memo is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", + "description": "Saves a course memo document descriptive data in the database per course and term, and per chosen {key: value}", + "parameters": [ + { + "name": "memoEndPoint", + "in": "path", + "description": "memoEndpoint is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, + { + "name": "courseCode", + "in": "path", + "description": "courseCode is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, + { + "name": "semester", + "in": "path", + "description": "semester is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, + { + "name": "roundCourseMemoData", + "in": "body", + "description": "Data with course code, semester and rounds to create first draft", + "required": true, + "schema": { + "$ref": "#/definitions/MemoData" + } + } + ], + "tags": ["v1"], + "responses": { + "200": { + "description": "A successful save" + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "security": [ + { + "api_key": ["write"] + } + ] + } + }, "/v1/memo/course/{courseCode}/memoEndPoint/{memoEndPoint}/version/{version}": { "get": { "operationId": "getMemoVersion", @@ -331,6 +387,42 @@ ] } }, + "/v1/memos/{courseCode}/": { + "get": { + "operationId": "getAllMemosByCourseCode", + "summary": "Get all course memos documents fetched by this course code", + "description": "Gets some form of data that only requires read access", + "parameters": [ + { + "name": "courseCode", + "in": "path", + "description": "Course code, ex, SF1624", + "required": true, + "type": "string" + } + ], + "tags": ["v1"], + "responses": { + "200": { + "description": "The requested data", + "schema": { + "$ref": "#/definitions/MemoDataListForCourseCode" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "security": [ + { + "api_key": ["read"] + } + ] + } + }, "/v1/memo/{memoEndPoint}": { "get": { "operationId": "getPublishedMemoByEndPoint", From 240751ad08160c4e46366276d6577d731eda4f8e Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Thu, 26 Jan 2023 11:17:10 +0100 Subject: [PATCH 2/9] feat: Add applicationCodes instead of ladokRoundId --- server/lib/dbDataById.js | 34 ++++++++++++++++++++++++++++++++- server/lib/dbSeveralDocument.js | 20 +++++++++++++++++-- server/models/mainMemoModel.js | 6 ++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/server/lib/dbDataById.js b/server/lib/dbDataById.js index 2ac1351..8b8731e 100644 --- a/server/lib/dbDataById.js +++ b/server/lib/dbDataById.js @@ -12,6 +12,13 @@ async function fetchMemoByEndPointAndStatus(memoEndPoint, status) { const memo = await CourseMemo.findOne({ memoEndPoint, status }) // courseCode return memo } +// No need to merge this method to master. This is only for updating old memos +async function fetchMemoByMemoEndpointAndCourseCodeAndSemester(memoEndPoint, courseCode, semester) { + if (!memoEndPoint && !courseCode && !semester) throw new Error('MemoEndPoint, courseCode and semester must be set') + log.debug('Fetching memo based on ', { memoEndPoint, courseCode, semester }) + const memo = await CourseMemo.findOne({ memoEndPoint, courseCode, semester }) + return memo +} async function getMemoVersion(courseCode, memoEndPoint, version) { if (!courseCode) throw new Error('courseCode must be set') @@ -34,7 +41,7 @@ async function storeNewCourseMemoData(data) { // ***** USED TO POST NEW COURSE MEMO FIRST DRAFT if (!data) throw new Error('Trying to post empty/innacurate data in storeNewCourseMemoData') else { - if (!data.courseCode || !data.semester || !data.ladokRoundIds) + if (!data.courseCode || !data.semester || !data.applicationCodes) throw new Error('Trying to post data without courseCode or semester or ladokRoundsIds in storeNewCourseMemoData') data.lastChangeDate = new Date() const doc = new CourseMemo(data) @@ -43,6 +50,29 @@ async function storeNewCourseMemoData(data) { return result } } +// No need to merge this method to master. This is only for updating old memos +async function updateMemoByMemoEndPointAndCourseCodeAndSemester(memoEndPoint, courseCode, semester, data) { + // UPPDATERA DRAFT GENOM memoEndPoint + if (data) { + log.debug('Update of existing memo: ', { data }) + + const resultAfterUpdate = await CourseMemo.findOneAndUpdate( + { memoEndPoint, courseCode, semester }, + { $set: data }, + { maxTimeMS: 100, new: true, useFindAndModify: false } + ) + if (resultAfterUpdate && resultAfterUpdate.version) { + log.debug('Updated draft: ', { + version: resultAfterUpdate.version, + memoEndPoint: resultAfterUpdate.memoEndPoint, + id: resultAfterUpdate.id, + applicationCodes: resultAfterUpdate.applicationCodes, + }) + } + return resultAfterUpdate + } + log.debug('No roundCourseMemoData found for updating it with new data', { data }) +} async function updateMemoByEndPointAndStatus(memoEndPoint, data, status) { // UPPDATERA DRAFT GENOM memoEndPoint @@ -73,6 +103,8 @@ module.exports = { getMemoVersion, fetchMemoByEndPointAndStatus, storeNewCourseMemoData, + updateMemoByMemoEndPointAndCourseCodeAndSemester, updateMemoByEndPointAndStatus, removeCourseMemoDataById, + fetchMemoByMemoEndpointAndCourseCodeAndSemester, } diff --git a/server/lib/dbSeveralDocument.js b/server/lib/dbSeveralDocument.js index cc1d367..a99509c 100644 --- a/server/lib/dbSeveralDocument.js +++ b/server/lib/dbSeveralDocument.js @@ -17,6 +17,21 @@ function logInCaseOfPossibleLimit(doc = [], matchingParameters = {}) { return } +// No need to merge this method to master. This is only for updating old memos +async function getAllMemosByCourse(courseCode) { + if (!courseCode) throw new Error('courseCode must be set') + const matchingParameters = { courseCode } + + log.debug('Fetching all courseMemos for ', matchingParameters) + const doc = await CourseMemo.find({ courseCode }) + // CourseMemo.find({ courseCode, status }) + if (doc) log.debug('Done fetching memos total: ', doc.length, ', for: ', matchingParameters) + + logInCaseOfPossibleLimit(doc, matchingParameters) + + return doc +} + async function getAllMemosByStatus(courseCode, status) { if (!courseCode) throw new Error('courseCode must be set') const matchingParameters = { courseCode, status } @@ -62,8 +77,8 @@ async function getCourseSemesterUsedRounds(courseCode, semester) { const finalObj = { usedRoundsThisSemester: [], } - await webBasedMemos.map(({ ladokRoundIds }) => finalObj.usedRoundsThisSemester.push(...ladokRoundIds)) - await dbMigratedPdfs.map(({ koppsRoundId }) => finalObj.usedRoundsThisSemester.push(...koppsRoundId)) + await webBasedMemos.map(({ applicationCodes }) => finalObj.usedRoundsThisSemester.push(...applicationCodes)) + await dbMigratedPdfs.map(({ applicationCodes }) => finalObj.usedRoundsThisSemester.push(...applicationCodes)) log.debug('Successfully got used round ids for', { courseCode, @@ -170,6 +185,7 @@ async function getMemosFromPrevSemester(courseCode, fromSemester) { } module.exports = { + getAllMemosByCourse, getAllMemosByStatus, getCourseSemesterUsedRounds, getFirstMemosBySemesterAndStatus, diff --git a/server/models/mainMemoModel.js b/server/models/mainMemoModel.js index a2a7985..556bb11 100644 --- a/server/models/mainMemoModel.js +++ b/server/models/mainMemoModel.js @@ -28,6 +28,12 @@ const schema = mongoose.Schema({ trim: true, required: [true, 'Enter course rounds'], }, + applicationCodes: { + type: Array, + items: String, + trim: true, + required: [true, 'Enter course application codes'], + }, lastChangeDate: { type: String, default: new Date(), From 47b110cddc9e73a29197a1b1b49ac13934eb5f76 Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Thu, 26 Jan 2023 14:28:44 +0100 Subject: [PATCH 3/9] feat: Add status, memoName and version to fetch query --- server/controllers/memoDataCtrl.js | 18 +++++++++----- server/lib/dbDataById.js | 39 ++++++++++++++++++++++++------ server/server.js | 5 +++- swagger.json | 23 +++++++++++++++++- 4 files changed, 69 insertions(+), 16 deletions(-) diff --git a/server/controllers/memoDataCtrl.js b/server/controllers/memoDataCtrl.js index 0844834..b0edcf6 100644 --- a/server/controllers/memoDataCtrl.js +++ b/server/controllers/memoDataCtrl.js @@ -73,18 +73,21 @@ async function getDraftByEndPoint(req, res) { } } -async function putMemoByMemoEndPointAndCourseCodeAndSemester(req, res) { +async function putMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion(req, res) { // STEP 2 EDITING: USE IT IN A SECOND STEP try { const memoObj = req.body - const { courseCode, memoEndPoint, semester } = req.params + const { courseCode, memoEndPoint, semester, memoName, status, version } = req.params const dbResponse = [] - const draftExist = await dbOneDocument.fetchMemoByMemoEndpointAndCourseCodeAndSemester( + const draftExist = await dbOneDocument.fetchMemoByMemoEndpointMemoNameAndStatusCourseCodeAndSemesterAndVersion( + memoName, memoEndPoint, courseCode, - semester + semester, + status, + version ) if (draftExist) { @@ -92,10 +95,13 @@ async function putMemoByMemoEndPointAndCourseCodeAndSemester(req, res) { 'memo draft already exists,' + memoEndPoint + ' so it will be updated (object id ' + draftExist._id + ')' ) dbResponse.push( - await dbOneDocument.updateMemoByMemoEndPointAndCourseCodeAndSemester( + await dbOneDocument.updateMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion( + memoName, memoEndPoint, courseCode, semester, + status, + version, memoObj ) ) @@ -319,5 +325,5 @@ module.exports = { deleteDraftByMemoEndPoint, postNewVersionOfPublishedMemo, putDraftByEndPoint, - putMemoByMemoEndPointAndCourseCodeAndSemester, + putMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion, } diff --git a/server/lib/dbDataById.js b/server/lib/dbDataById.js index 8b8731e..aec08f0 100644 --- a/server/lib/dbDataById.js +++ b/server/lib/dbDataById.js @@ -13,10 +13,22 @@ async function fetchMemoByEndPointAndStatus(memoEndPoint, status) { return memo } // No need to merge this method to master. This is only for updating old memos -async function fetchMemoByMemoEndpointAndCourseCodeAndSemester(memoEndPoint, courseCode, semester) { - if (!memoEndPoint && !courseCode && !semester) throw new Error('MemoEndPoint, courseCode and semester must be set') - log.debug('Fetching memo based on ', { memoEndPoint, courseCode, semester }) - const memo = await CourseMemo.findOne({ memoEndPoint, courseCode, semester }) +async function fetchMemoByMemoEndpointMemoNameAndStatusCourseCodeAndSemesterAndVersion( + memoName, + memoEndPoint, + courseCode, + semester, + status, + version +) { + if (!memoEndPoint && !courseCode && !semester && !status && !version) + throw new Error('MemoEndPoint, courseCode, status, semester and version must be set') + log.debug('Fetching memo based on ', { memoEndPoint, courseCode, semester, memoName, status }) + const memo = await CourseMemo.findOne( + memoName + ? { memoName, version, memoEndPoint, courseCode, semester, status } + : { version, memoEndPoint, courseCode, semester, status } + ) return memo } @@ -51,13 +63,23 @@ async function storeNewCourseMemoData(data) { } } // No need to merge this method to master. This is only for updating old memos -async function updateMemoByMemoEndPointAndCourseCodeAndSemester(memoEndPoint, courseCode, semester, data) { +async function updateMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion( + memoName, + memoEndPoint, + courseCode, + semester, + status, + version, + data +) { // UPPDATERA DRAFT GENOM memoEndPoint if (data) { log.debug('Update of existing memo: ', { data }) const resultAfterUpdate = await CourseMemo.findOneAndUpdate( - { memoEndPoint, courseCode, semester }, + memoName + ? { memoEndPoint, courseCode, semester, memoName, status, version } + : { memoEndPoint, courseCode, semester, status, version }, { $set: data }, { maxTimeMS: 100, new: true, useFindAndModify: false } ) @@ -65,6 +87,7 @@ async function updateMemoByMemoEndPointAndCourseCodeAndSemester(memoEndPoint, co log.debug('Updated draft: ', { version: resultAfterUpdate.version, memoEndPoint: resultAfterUpdate.memoEndPoint, + memoName: resultAfterUpdate.memoName, id: resultAfterUpdate.id, applicationCodes: resultAfterUpdate.applicationCodes, }) @@ -103,8 +126,8 @@ module.exports = { getMemoVersion, fetchMemoByEndPointAndStatus, storeNewCourseMemoData, - updateMemoByMemoEndPointAndCourseCodeAndSemester, + updateMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion, updateMemoByEndPointAndStatus, removeCourseMemoDataById, - fetchMemoByMemoEndpointAndCourseCodeAndSemester, + fetchMemoByMemoEndpointMemoNameAndStatusCourseCodeAndSemesterAndVersion, } diff --git a/server/server.js b/server/server.js index 9c16341..372568f 100644 --- a/server/server.js +++ b/server/server.js @@ -158,7 +158,10 @@ apiRoute.register(paths.api.getMemoVersion, CourseMemo.getMemoVersion) // step 2 // Get one draft | update it apiRoute.register(paths.api.getDraftByEndPoint, CourseMemo.getDraftByEndPoint) // step 2: editor, fetch data apiRoute.register(paths.api.updateCreatedDraft, CourseMemo.putDraftByEndPoint) // step 2: editor, fast update -apiRoute.register(paths.api.updatedMemoById, CourseMemo.putMemoByMemoEndPointAndCourseCodeAndSemester) +apiRoute.register( + paths.api.updatedMemoById, + CourseMemo.putMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion +) // step 1: choose action, new draft, or copied draft from published memo (same memoEndPoint) apiRoute.register(paths.api.createDraftByMemoEndPoint, CourseMemo.createDraftByMemoEndPoint) diff --git a/swagger.json b/swagger.json index 1a416b7..7052a9c 100644 --- a/swagger.json +++ b/swagger.json @@ -230,12 +230,19 @@ ] } }, - "/v1/memo/{memoEndPoint}/{courseCode}/{semester}": { + "/v1/memo/{memoName}/{memoEndPoint}/{courseCode}/{semester}/{status}/{version}": { "put": { "operationId": "updatedMemoById", "summary": "The memo is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", "description": "Saves a course memo document descriptive data in the database per course and term, and per chosen {key: value}", "parameters": [ + { + "name": "memoName", + "in": "path", + "description": "memoName is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, { "name": "memoEndPoint", "in": "path", @@ -257,6 +264,20 @@ "required": true, "type": "string" }, + { + "name": "status", + "in": "path", + "description": "status is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, + { + "name": "version", + "in": "path", + "description": "status is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, { "name": "roundCourseMemoData", "in": "body", From db971cd30b7787997be17fd4e5d1bcfb5fe2db97 Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Thu, 26 Jan 2023 16:33:39 +0100 Subject: [PATCH 4/9] fix: Change to update by id --- server/controllers/memoDataCtrl.js | 35 ++++++--------------------- server/lib/dbDataById.js | 38 ++++++----------------------- server/server.js | 5 +--- swagger.json | 39 ++---------------------------- 4 files changed, 19 insertions(+), 98 deletions(-) diff --git a/server/controllers/memoDataCtrl.js b/server/controllers/memoDataCtrl.js index b0edcf6..6cb3949 100644 --- a/server/controllers/memoDataCtrl.js +++ b/server/controllers/memoDataCtrl.js @@ -73,43 +73,24 @@ async function getDraftByEndPoint(req, res) { } } -async function putMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion(req, res) { +async function putMemoById(req, res) { // STEP 2 EDITING: USE IT IN A SECOND STEP try { const memoObj = req.body - const { courseCode, memoEndPoint, semester, memoName, status, version } = req.params + const { _id } = req.params const dbResponse = [] - const draftExist = await dbOneDocument.fetchMemoByMemoEndpointMemoNameAndStatusCourseCodeAndSemesterAndVersion( - memoName, - memoEndPoint, - courseCode, - semester, - status, - version - ) + const draftExist = await dbOneDocument.fetchMemoById(_id) if (draftExist) { - log.info( - 'memo draft already exists,' + memoEndPoint + ' so it will be updated (object id ' + draftExist._id + ')' - ) - dbResponse.push( - await dbOneDocument.updateMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion( - memoName, - memoEndPoint, - courseCode, - semester, - status, - version, - memoObj - ) - ) + log.info('memo draft already exists,' + _id + ' so it will be updated (object id ' + draftExist._id + ')') + dbResponse.push(await dbOneDocument.updateMemoById(_id, memoObj)) } else { - log.debug('no memo draft was found to update with id: ', memoEndPoint) + log.debug('no memo draft was found to update with id: ', _id) } - log.info('dbResponse length', dbResponse.length, { memoEndPoint }) + log.info('dbResponse length', dbResponse.length, { _id }) res.status(201).json(dbResponse) } catch (error) { log.error('Error in while trying to putMemoById', { error }) @@ -325,5 +306,5 @@ module.exports = { deleteDraftByMemoEndPoint, postNewVersionOfPublishedMemo, putDraftByEndPoint, - putMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion, + putMemoById, } diff --git a/server/lib/dbDataById.js b/server/lib/dbDataById.js index aec08f0..acde1a9 100644 --- a/server/lib/dbDataById.js +++ b/server/lib/dbDataById.js @@ -13,22 +13,10 @@ async function fetchMemoByEndPointAndStatus(memoEndPoint, status) { return memo } // No need to merge this method to master. This is only for updating old memos -async function fetchMemoByMemoEndpointMemoNameAndStatusCourseCodeAndSemesterAndVersion( - memoName, - memoEndPoint, - courseCode, - semester, - status, - version -) { - if (!memoEndPoint && !courseCode && !semester && !status && !version) - throw new Error('MemoEndPoint, courseCode, status, semester and version must be set') - log.debug('Fetching memo based on ', { memoEndPoint, courseCode, semester, memoName, status }) - const memo = await CourseMemo.findOne( - memoName - ? { memoName, version, memoEndPoint, courseCode, semester, status } - : { version, memoEndPoint, courseCode, semester, status } - ) +async function fetchMemoById(_id) { + if (!_id) throw new Error('Id must be set') + log.debug('Fetching memo based on ', { _id }) + const memo = await CourseMemo.findOne({ _id }) return memo } @@ -63,23 +51,13 @@ async function storeNewCourseMemoData(data) { } } // No need to merge this method to master. This is only for updating old memos -async function updateMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion( - memoName, - memoEndPoint, - courseCode, - semester, - status, - version, - data -) { +async function updateMemoById(_id, data) { // UPPDATERA DRAFT GENOM memoEndPoint if (data) { log.debug('Update of existing memo: ', { data }) const resultAfterUpdate = await CourseMemo.findOneAndUpdate( - memoName - ? { memoEndPoint, courseCode, semester, memoName, status, version } - : { memoEndPoint, courseCode, semester, status, version }, + { _id }, { $set: data }, { maxTimeMS: 100, new: true, useFindAndModify: false } ) @@ -126,8 +104,8 @@ module.exports = { getMemoVersion, fetchMemoByEndPointAndStatus, storeNewCourseMemoData, - updateMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion, + updateMemoById, updateMemoByEndPointAndStatus, removeCourseMemoDataById, - fetchMemoByMemoEndpointMemoNameAndStatusCourseCodeAndSemesterAndVersion, + fetchMemoById, } diff --git a/server/server.js b/server/server.js index 372568f..e5b3a69 100644 --- a/server/server.js +++ b/server/server.js @@ -158,10 +158,7 @@ apiRoute.register(paths.api.getMemoVersion, CourseMemo.getMemoVersion) // step 2 // Get one draft | update it apiRoute.register(paths.api.getDraftByEndPoint, CourseMemo.getDraftByEndPoint) // step 2: editor, fetch data apiRoute.register(paths.api.updateCreatedDraft, CourseMemo.putDraftByEndPoint) // step 2: editor, fast update -apiRoute.register( - paths.api.updatedMemoById, - CourseMemo.putMemoByMemoEndPointAndMemoNameAndStatusAndCourseCodeAndSemesterAndVersion -) +apiRoute.register(paths.api.updatedMemoById, CourseMemo.putMemoById) // step 1: choose action, new draft, or copied draft from published memo (same memoEndPoint) apiRoute.register(paths.api.createDraftByMemoEndPoint, CourseMemo.createDraftByMemoEndPoint) diff --git a/swagger.json b/swagger.json index 7052a9c..b9dd5ee 100644 --- a/swagger.json +++ b/swagger.json @@ -230,54 +230,19 @@ ] } }, - "/v1/memo/{memoName}/{memoEndPoint}/{courseCode}/{semester}/{status}/{version}": { + "/v1/memo/{_id}": { "put": { "operationId": "updatedMemoById", "summary": "The memo is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", "description": "Saves a course memo document descriptive data in the database per course and term, and per chosen {key: value}", "parameters": [ { - "name": "memoName", + "name": "_id", "in": "path", "description": "memoName is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", "required": true, "type": "string" }, - { - "name": "memoEndPoint", - "in": "path", - "description": "memoEndpoint is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", - "required": true, - "type": "string" - }, - { - "name": "courseCode", - "in": "path", - "description": "courseCode is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", - "required": true, - "type": "string" - }, - { - "name": "semester", - "in": "path", - "description": "semester is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", - "required": true, - "type": "string" - }, - { - "name": "status", - "in": "path", - "description": "status is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", - "required": true, - "type": "string" - }, - { - "name": "version", - "in": "path", - "description": "status is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", - "required": true, - "type": "string" - }, { "name": "roundCourseMemoData", "in": "body", From f5cb579bcbf9abdd4f27e2175e149739aed0f632 Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Fri, 3 Feb 2023 15:13:57 +0100 Subject: [PATCH 5/9] feat: Add api to update pdf files --- server/controllers/memoDataCtrl.js | 37 ++++--- server/controllers/storedMemoPdfsCtrl.js | 39 +++++++ server/lib/dbDataById.js | 60 ++++++++--- server/lib/dbSeveralDocument.js | 20 ++-- server/models/mainMemoModel.js | 2 +- server/models/storedMemoPdfsModel.js | 5 + server/server.js | 9 +- swagger.json | 130 ++++++++++++++++++++--- 8 files changed, 244 insertions(+), 58 deletions(-) diff --git a/server/controllers/memoDataCtrl.js b/server/controllers/memoDataCtrl.js index 6cb3949..8d9d455 100644 --- a/server/controllers/memoDataCtrl.js +++ b/server/controllers/memoDataCtrl.js @@ -73,24 +73,28 @@ async function getDraftByEndPoint(req, res) { } } -async function putMemoById(req, res) { +async function putApplicationCodesInMemo(req, res) { // STEP 2 EDITING: USE IT IN A SECOND STEP try { - const memoObj = req.body - const { _id } = req.params + const applicationCodes = req.body + const { memoEndPoint, status, courseCode, ladokRoundIds, semester } = req.params const dbResponse = [] - const draftExist = await dbOneDocument.fetchMemoById(_id) + const draftExist = await dbOneDocument.fetchMemo({ memoEndPoint, status, courseCode, ladokRoundIds, semester }) if (draftExist) { - log.info('memo draft already exists,' + _id + ' so it will be updated (object id ' + draftExist._id + ')') - dbResponse.push(await dbOneDocument.updateMemoById(_id, memoObj)) + log.info( + 'memo draft already exists,' + memoEndPoint + ' so it will be updated (object id ' + draftExist._id + ')' + ) + dbResponse.push( + await dbOneDocument.updateMemo({ memoEndPoint, status, courseCode, ladokRoundIds }, applicationCodes) + ) } else { - log.debug('no memo draft was found to update with id: ', _id) + log.debug('no memo draft was found to update with memoEndPoint: ', memoEndPoint) } - log.info('dbResponse length', dbResponse.length, { _id }) + log.info('dbResponse length', dbResponse.length, { memoEndPoint }) res.status(201).json(dbResponse) } catch (error) { log.error('Error in while trying to putMemoById', { error }) @@ -197,17 +201,16 @@ async function createDraftByMemoEndPoint(req, res) { } } -async function getAllMemosByCourseCode(req, res) { - // TODO: ADD FETCHING USED COURSE ROUNDS (DRAFTS + PUBLISHED) - const { courseCode } = req.params - log.info('getAllMemosByCourseCode: Received request for memo for course:', { courseCode }) +// No need to merge +async function getAllMemos(req, res) { + log.info('getAllMemos: Received request for memo') try { - const dbResponse = await dbArrayOfDocument.getAllMemosByCourse(courseCode) + const dbResponse = await dbArrayOfDocument.getAllMemos() res.json(dbResponse || []) - log.info('getAllMemosByCourseCode: Responded to request for memo:', { courseCode }) + log.info('getAllMemos: Responded to request for memo') } catch (err) { - log.error('getAllMemosByCourseCode: Failed request for memo, error:', { err }) + log.error('getAllMemos: Failed request for memo, error:', { err }) return err } } @@ -299,12 +302,12 @@ module.exports = { createDraftByMemoEndPoint, getDraftByEndPoint, getPublishedMemoByEndPoint, - getAllMemosByCourseCode, + getAllMemos, getAllMemosByCourseCodeAndType, getMemosStartingFromPrevSemester, getCourseSemesterUsedRounds, deleteDraftByMemoEndPoint, postNewVersionOfPublishedMemo, putDraftByEndPoint, - putMemoById, + putApplicationCodesInMemo, } diff --git a/server/controllers/storedMemoPdfsCtrl.js b/server/controllers/storedMemoPdfsCtrl.js index fb920ef..d9e5635 100644 --- a/server/controllers/storedMemoPdfsCtrl.js +++ b/server/controllers/storedMemoPdfsCtrl.js @@ -4,6 +4,7 @@ const log = require('@kth/log') const { StoredMemoPdfsModel } = require('../models/storedMemoPdfsModel') +const dbOneDocument = require('../lib/dbDataById') async function getStoredMemoPdfListByCourseCode(req, res) { if (!req.params.courseCode) throw new Error('courseCode must be set') @@ -55,6 +56,18 @@ async function fetchAll() { return migrated } +async function fetchAllMemoFiles(req, res) { + try { + log.debug('Fetching all migrated courseMemos ') + const migrated = await StoredMemoPdfsModel.find({}) + log.info('Length of data in db', migrated.length) + res.json(migrated || []) + } catch (error) { + log.error('Error in while trying to get all migrating memos files ', { error }) + return error + } +} + // /count async function checkLength(req, res) { try { @@ -68,7 +81,33 @@ async function checkLength(req, res) { } } +async function updateStoredPdfMemoWithApplicationCodes(req, res) { + try { + const applicationCodes = req.body + const { _id } = req.params + + const dbResponse = [] + + const draftExist = await dbOneDocument.fetchMemoFileById(_id) + + if (draftExist) { + log.info('memo file already exists,' + _id + ' so it will be updated (object id ' + draftExist._id + ')') + dbResponse.push(await dbOneDocument.updateMemoFile(_id, applicationCodes)) + } else { + log.debug('no memo file was found to update with Id: ', _id) + } + + log.info('dbResponse length', dbResponse.length, { _id }) + res.status(201).json(dbResponse) + } catch (error) { + log.error('Error in while trying to update memo file with application codes', { error }) + return error + } +} + module.exports = { collectionLength: checkLength, getStoredMemoPdfListByCourseCode, + fetchAllMemoFiles, + updateStoredPdfMemoWithApplicationCodes, } diff --git a/server/lib/dbDataById.js b/server/lib/dbDataById.js index acde1a9..f9c545a 100644 --- a/server/lib/dbDataById.js +++ b/server/lib/dbDataById.js @@ -2,6 +2,7 @@ /* eslint-disable no-underscore-dangle */ const log = require('@kth/log') const { CourseMemo } = require('../models/mainMemoModel') +const { StoredMemoPdfsModel } = require('../models/storedMemoPdfsModel') /* ****** */ /* ANY BY STATUS AND MemoEndPoint */ @@ -13,11 +14,19 @@ async function fetchMemoByEndPointAndStatus(memoEndPoint, status) { return memo } // No need to merge this method to master. This is only for updating old memos -async function fetchMemoById(_id) { - if (!_id) throw new Error('Id must be set') - log.debug('Fetching memo based on ', { _id }) - const memo = await CourseMemo.findOne({ _id }) - return memo +async function fetchMemo(memo) { + if (!memo) throw new Error('Memo must be set') + log.debug('Fetching memo based on ', memo) + const doc = await CourseMemo.findOne(memo) + return doc +} + +// No need to merge this method to master. This is only for updating old memos +async function fetchMemoFileById(Id) { + if (!Id) throw new Error('Id must be set') + log.debug('Fetching memo based on ', Id) + const doc = await StoredMemoPdfsModel.findById(Id) + return doc } async function getMemoVersion(courseCode, memoEndPoint, version) { @@ -51,13 +60,13 @@ async function storeNewCourseMemoData(data) { } } // No need to merge this method to master. This is only for updating old memos -async function updateMemoById(_id, data) { +async function updateMemo(memo, data) { // UPPDATERA DRAFT GENOM memoEndPoint - if (data) { - log.debug('Update of existing memo: ', { data }) + if (memo) { + log.debug('Update of existing memo: ', { memo }) const resultAfterUpdate = await CourseMemo.findOneAndUpdate( - { _id }, + memo, { $set: data }, { maxTimeMS: 100, new: true, useFindAndModify: false } ) @@ -72,7 +81,32 @@ async function updateMemoById(_id, data) { } return resultAfterUpdate } - log.debug('No roundCourseMemoData found for updating it with new data', { data }) + log.debug('No roundCourseMemoData found for updating it with new data', { memo }) +} + +// No need to merge this method to master. This is only for updating old memos +async function updateMemoFile(_id, data) { + // UPPDATERA DRAFT GENOM memoEndPoint + if (_id) { + log.debug('Update of existing memo: ', { _id }) + + const resultAfterUpdate = await StoredMemoPdfsModel.findByIdAndUpdate( + _id, + { $set: data }, + { maxTimeMS: 100, new: true, useFindAndModify: false } + ) + if (resultAfterUpdate && resultAfterUpdate.id) { + log.debug('Updated draft: ', { + id: resultAfterUpdate.id, + koppsRoundId: resultAfterUpdate.koppsRoundId, + semester: resultAfterUpdate.semester, + courseCode: resultAfterUpdate.courseCode, + applicationCode: resultAfterUpdate.applicationCode, + }) + } + return resultAfterUpdate + } + log.debug('No roundCourseMemoFileData found for updating it with new data', { _id }) } async function updateMemoByEndPointAndStatus(memoEndPoint, data, status) { @@ -104,8 +138,10 @@ module.exports = { getMemoVersion, fetchMemoByEndPointAndStatus, storeNewCourseMemoData, - updateMemoById, + updateMemo, updateMemoByEndPointAndStatus, removeCourseMemoDataById, - fetchMemoById, + fetchMemo, + fetchMemoFileById, + updateMemoFile, } diff --git a/server/lib/dbSeveralDocument.js b/server/lib/dbSeveralDocument.js index a99509c..9d5b389 100644 --- a/server/lib/dbSeveralDocument.js +++ b/server/lib/dbSeveralDocument.js @@ -18,18 +18,12 @@ function logInCaseOfPossibleLimit(doc = [], matchingParameters = {}) { } // No need to merge this method to master. This is only for updating old memos -async function getAllMemosByCourse(courseCode) { - if (!courseCode) throw new Error('courseCode must be set') - const matchingParameters = { courseCode } - - log.debug('Fetching all courseMemos for ', matchingParameters) - const doc = await CourseMemo.find({ courseCode }) - // CourseMemo.find({ courseCode, status }) - if (doc) log.debug('Done fetching memos total: ', doc.length, ', for: ', matchingParameters) - - logInCaseOfPossibleLimit(doc, matchingParameters) - - return doc +async function getAllMemos() { + log.debug('Fetching all courseMemos') + const allDocuments = await CourseMemo.find() + if (allDocuments) log.debug('Done fetching memos total: ', allDocuments.length) + logInCaseOfPossibleLimit(allDocuments) + return allDocuments } async function getAllMemosByStatus(courseCode, status) { @@ -185,7 +179,7 @@ async function getMemosFromPrevSemester(courseCode, fromSemester) { } module.exports = { - getAllMemosByCourse, + getAllMemos, getAllMemosByStatus, getCourseSemesterUsedRounds, getFirstMemosBySemesterAndStatus, diff --git a/server/models/mainMemoModel.js b/server/models/mainMemoModel.js index 556bb11..5dff29e 100644 --- a/server/models/mainMemoModel.js +++ b/server/models/mainMemoModel.js @@ -1,7 +1,7 @@ 'use strict' -const combinedMemoData = require('./combinedMemoData') const mongoose = require('mongoose') +const combinedMemoData = require('./combinedMemoData') const schema = mongoose.Schema({ // _id: mongoose.Schema.Types.ObjectId, diff --git a/server/models/storedMemoPdfsModel.js b/server/models/storedMemoPdfsModel.js index eff5e68..fceb672 100644 --- a/server/models/storedMemoPdfsModel.js +++ b/server/models/storedMemoPdfsModel.js @@ -49,6 +49,11 @@ const schema = mongoose.Schema({ type: Array, default: [], }, + applicationCode: { + type: String, + trim: true, + default: '', + }, }) const StoredMemoPdfsModel = mongoose.model('MemoFile', schema) diff --git a/server/server.js b/server/server.js index e5b3a69..642b7d2 100644 --- a/server/server.js +++ b/server/server.js @@ -158,14 +158,14 @@ apiRoute.register(paths.api.getMemoVersion, CourseMemo.getMemoVersion) // step 2 // Get one draft | update it apiRoute.register(paths.api.getDraftByEndPoint, CourseMemo.getDraftByEndPoint) // step 2: editor, fetch data apiRoute.register(paths.api.updateCreatedDraft, CourseMemo.putDraftByEndPoint) // step 2: editor, fast update -apiRoute.register(paths.api.updatedMemoById, CourseMemo.putMemoById) +apiRoute.register(paths.api.updatedMemoWithApplicationCodes, CourseMemo.putApplicationCodesInMemo) // step 1: choose action, new draft, or copied draft from published memo (same memoEndPoint) apiRoute.register(paths.api.createDraftByMemoEndPoint, CourseMemo.createDraftByMemoEndPoint) apiRoute.register(paths.api.copyFromAPublishedMemo, CourseMemo.createDraftByMemoEndPoint) // // GET ARRAY OF MEMOS BY TYPE AND COURSE CODE -apiRoute.register(paths.api.getAllMemosByCourseCode, CourseMemo.getAllMemosByCourseCode) +apiRoute.register(paths.api.getAllMemos, CourseMemo.getAllMemos) apiRoute.register(paths.api.getAllMemosByCourseCodeAndType, CourseMemo.getAllMemosByCourseCodeAndType) apiRoute.register(paths.api.getCourseSemesterUsedRounds, CourseMemo.getCourseSemesterUsedRounds) // step 1: to show up which rounds already taken apiRoute.register(paths.api.getMemosStartingFromPrevYearSemester, CourseMemo.getMemosStartingFromPrevSemester) // step 1: to show up which rounds already taken @@ -179,7 +179,12 @@ server.use('/', apiRoute.getRouter()) apiRoute.register(paths.api.deleteDraftByMemoEndPoint, CourseMemo.deleteDraftByMemoEndPoint) // Get list of stored pdf files for kursinfo-web (migrated from kurs-pm-api) +apiRoute.register(paths.api.getStoredMemoPdfList, StoredMemoPdf.fetchAllMemoFiles) apiRoute.register(paths.api.getStoredMemoPdfListByCourseCode, StoredMemoPdf.getStoredMemoPdfListByCourseCode) +apiRoute.register( + paths.api.updateStoredPdfMemoWithApplicationCodes, + StoredMemoPdf.updateStoredPdfMemoWithApplicationCodes +) // Get list of stored pdf files together with web-based memos all published for kurs-pm-web (migrated from kurs-pm-api) apiRoute.register( paths.api.getPdfAndWebMemosListByCourseCode, diff --git a/swagger.json b/swagger.json index b9dd5ee..f0b1491 100644 --- a/swagger.json +++ b/swagger.json @@ -230,19 +230,89 @@ ] } }, - "/v1/memo/{_id}": { + "/v1/memo/file/{_id}": { "put": { - "operationId": "updatedMemoById", - "summary": "The memo is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", + "operationId": "updateStoredPdfMemoWithApplicationCodes", + "summary": "The draft is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", "description": "Saves a course memo document descriptive data in the database per course and term, and per chosen {key: value}", "parameters": [ { "name": "_id", "in": "path", - "description": "memoName is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "description": "_id is used to keep all versions under the same endpoint, unique for memo for one kursomgång. Unchangeable enpoint to display it in url (for bookmarks) and keep track on versions change", + "required": true, + "type": "string" + }, + { + "name": "memoFileData", + "in": "body", + "description": "Data with course code, semester and rounds to create first draft", + "required": true, + "schema": { + "$ref": "#/definitions/MemoData" + } + } + ], + "tags": ["v1"], + "responses": { + "200": { + "description": "A successful save" + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "security": [ + { + "api_key": ["write"] + } + ] + } + }, + "/v1/memo/{courseCode}/{ladokRoundIds}/{semester}/{memoEndPoint}/{status}": { + "put": { + "operationId": "updatedMemoWithApplicationCodes", + "summary": "The memo is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", + "description": "Saves a course memo document descriptive data in the database per course and term, and per chosen {key: value}", + "parameters": [ + { + "name": "courseCode", + "in": "path", + "description": "courseCode of the memo draft to delete course memo data", + "required": true, + "type": "string" + }, + { + "name": "status", + "in": "path", + "description": "status of the memo draft to delete course memo data", + "required": true, + "type": "string" + }, + { + "name": "semester", + "in": "path", + "description": "semester of the memo draft to delete course memo data", + "required": true, + "type": "string" + }, + { + "name": "status", + "in": "path", + "description": "status of the memo draft to delete course memo data", "required": true, "type": "string" }, + { + "name": "ladokRoundIds", + "in": "path", + "description": "ladokRoundIds of the memo draft to delete course memo data", + "required": true, + "type": "Array" + }, { "name": "roundCourseMemoData", "in": "body", @@ -373,19 +443,12 @@ ] } }, - "/v1/memos/{courseCode}/": { + "/v1/memos/all": { "get": { - "operationId": "getAllMemosByCourseCode", + "operationId": "getAllMemos", "summary": "Get all course memos documents fetched by this course code", "description": "Gets some form of data that only requires read access", "parameters": [ - { - "name": "courseCode", - "in": "path", - "description": "Course code, ex, SF1624", - "required": true, - "type": "string" - } ], "tags": ["v1"], "responses": { @@ -485,6 +548,47 @@ ] } }, + "/v1/pdfCourseMemoFilesList": { + "get": { + "operationId": "getStoredMemoPdfList", + "summary": "Get a list of course memos stored as pdf files (integrated from kurs-pm-api) used by kursinfo-web", + "description": "Gets course memos for rounds in a course. Memos stored as pdfs in kursinfo storage (not generated)", + "parameters": [ + ], + "tags": ["v1"], + "responses": { + "200": { + "description": "The requested data", + "schema": { + "$ref": "#/definitions/MemoPdfFilesList" + } + }, + "400": { + "description": "Bad Request, something with the request is invalid", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "404": { + "description": "No organization or user matched the Ids", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "security": [ + { + "api_key": ["read"] + } + ] + } + }, "/v1/pdfCourseMemoFilesList/{courseCode}/{semester}": { "get": { "operationId": "getStoredMemoPdfListByCourseCode", From 56335847cd1da264c760848d6de9e6bc8b390cd3 Mon Sep 17 00:00:00 2001 From: samtal Date: Mon, 6 Feb 2023 10:50:55 +0100 Subject: [PATCH 6/9] update: add applicationcode --- server/controllers/mixedWebAndPdfMemosCtrl.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/server/controllers/mixedWebAndPdfMemosCtrl.js b/server/controllers/mixedWebAndPdfMemosCtrl.js index 1c3f134..e6a6b3c 100644 --- a/server/controllers/mixedWebAndPdfMemosCtrl.js +++ b/server/controllers/mixedWebAndPdfMemosCtrl.js @@ -158,12 +158,22 @@ async function _formPrioritizedMemosByCourseRounds(courseCode, pdfMemos, webBase const miniMemos = {} // firstly fetch web-based await webBasedMemos.forEach( - ({ ladokRoundIds, memoEndPoint, memoCommonLangAbbr, memoName, semester, version, lastChangeDate }) => { + ({ + ladokRoundIds, + memoEndPoint, + memoCommonLangAbbr, + memoName, + semester, + version, + lastChangeDate, + applicationCodes, + }) => { if (!semester) return if (!miniMemos[semester]) miniMemos[semester] = {} ladokRoundIds.forEach(roundId => { miniMemos[semester][roundId] = { courseCode, + applicationCodes, ladokRoundIds, semester, memoEndPoint, @@ -186,6 +196,7 @@ async function _formPrioritizedMemosByCourseRounds(courseCode, pdfMemos, webBase lastChangeDate = pdfMemoUploadDate, previousFileList, semester, + applicationCode, }) => { if (!semester) return if (!koppsRoundId) return @@ -193,6 +204,7 @@ async function _formPrioritizedMemosByCourseRounds(courseCode, pdfMemos, webBase if (!miniMemos[semester][koppsRoundId]) { miniMemos[semester][koppsRoundId] = { courseCode, + applicationCodes: [applicationCode], courseMemoFileName, ladokRoundIds: [koppsRoundId], lastChangeDate, From 164c09e5f16576bad6f8b5e686c34ae173853f2e Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Mon, 6 Feb 2023 11:09:08 +0100 Subject: [PATCH 7/9] fix: Fixed unique record problem --- server/controllers/memoDataCtrl.js | 9 ++++++--- server/lib/dbDataById.js | 3 +++ swagger.json | 19 ++++++------------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/server/controllers/memoDataCtrl.js b/server/controllers/memoDataCtrl.js index 8d9d455..4efaed1 100644 --- a/server/controllers/memoDataCtrl.js +++ b/server/controllers/memoDataCtrl.js @@ -76,8 +76,8 @@ async function getDraftByEndPoint(req, res) { async function putApplicationCodesInMemo(req, res) { // STEP 2 EDITING: USE IT IN A SECOND STEP try { - const applicationCodes = req.body - const { memoEndPoint, status, courseCode, ladokRoundIds, semester } = req.params + const { applicationCodes, ladokRoundIds } = req.body + const { memoEndPoint, status, courseCode, semester } = req.params const dbResponse = [] @@ -88,7 +88,10 @@ async function putApplicationCodesInMemo(req, res) { 'memo draft already exists,' + memoEndPoint + ' so it will be updated (object id ' + draftExist._id + ')' ) dbResponse.push( - await dbOneDocument.updateMemo({ memoEndPoint, status, courseCode, ladokRoundIds }, applicationCodes) + await dbOneDocument.updateMemo( + { memoEndPoint, status, courseCode, ladokRoundIds, semester }, + { applicationCodes } + ) ) } else { log.debug('no memo draft was found to update with memoEndPoint: ', memoEndPoint) diff --git a/server/lib/dbDataById.js b/server/lib/dbDataById.js index f9c545a..2fa9dc6 100644 --- a/server/lib/dbDataById.js +++ b/server/lib/dbDataById.js @@ -77,6 +77,9 @@ async function updateMemo(memo, data) { memoName: resultAfterUpdate.memoName, id: resultAfterUpdate.id, applicationCodes: resultAfterUpdate.applicationCodes, + semester: resultAfterUpdate.semester, + courseCode: resultAfterUpdate.courseCode, + ladokRoundIds: resultAfterUpdate.ladokRoundIds, }) } return resultAfterUpdate diff --git a/swagger.json b/swagger.json index f0b1491..1e9f569 100644 --- a/swagger.json +++ b/swagger.json @@ -272,7 +272,7 @@ ] } }, - "/v1/memo/{courseCode}/{ladokRoundIds}/{semester}/{memoEndPoint}/{status}": { + "/v1/memo/{courseCode}/{semester}/{memoEndPoint}/{status}": { "put": { "operationId": "updatedMemoWithApplicationCodes", "summary": "The memo is already in database. Update some of its properties, f.e., only text for examinations, for fast and often update", @@ -281,42 +281,35 @@ { "name": "courseCode", "in": "path", - "description": "courseCode of the memo draft to delete course memo data", + "description": "courseCode of the memo draft to update course memo data", "required": true, "type": "string" }, { "name": "status", "in": "path", - "description": "status of the memo draft to delete course memo data", + "description": "status of the memo draft to update course memo data", "required": true, "type": "string" }, { "name": "semester", "in": "path", - "description": "semester of the memo draft to delete course memo data", + "description": "semester of the memo draft to update course memo data", "required": true, "type": "string" }, { "name": "status", "in": "path", - "description": "status of the memo draft to delete course memo data", + "description": "status of the memo draft to update course memo data", "required": true, "type": "string" }, - { - "name": "ladokRoundIds", - "in": "path", - "description": "ladokRoundIds of the memo draft to delete course memo data", - "required": true, - "type": "Array" - }, { "name": "roundCourseMemoData", "in": "body", - "description": "Data with course code, semester and rounds to create first draft", + "description": "Data with applicationCodes and rounds to update first draft", "required": true, "schema": { "$ref": "#/definitions/MemoData" From f547f48e5d009ac513445246796edd1d4c9d714e Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Wed, 8 Feb 2023 12:56:11 +0100 Subject: [PATCH 8/9] fix: Remove duplicate path --- swagger.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swagger.json b/swagger.json index 1e9f569..688657d 100644 --- a/swagger.json +++ b/swagger.json @@ -300,9 +300,9 @@ "type": "string" }, { - "name": "status", + "name": "memoEndPoint", "in": "path", - "description": "status of the memo draft to update course memo data", + "description": "memoEndPoint of the memo draft to update course memo data", "required": true, "type": "string" }, From e3f1b064096fb169b45c20d7bbc74e4e3c0e6021 Mon Sep 17 00:00:00 2001 From: Rao-Sabahat-Ali Date: Wed, 8 Feb 2023 12:59:11 +0100 Subject: [PATCH 9/9] fix: Change applicationCodes to applicationCode --- server/lib/dbSeveralDocument.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/dbSeveralDocument.js b/server/lib/dbSeveralDocument.js index 9d5b389..b6ae26f 100644 --- a/server/lib/dbSeveralDocument.js +++ b/server/lib/dbSeveralDocument.js @@ -72,7 +72,7 @@ async function getCourseSemesterUsedRounds(courseCode, semester) { usedRoundsThisSemester: [], } await webBasedMemos.map(({ applicationCodes }) => finalObj.usedRoundsThisSemester.push(...applicationCodes)) - await dbMigratedPdfs.map(({ applicationCodes }) => finalObj.usedRoundsThisSemester.push(...applicationCodes)) + await dbMigratedPdfs.map(({ applicationCode }) => finalObj.usedRoundsThisSemester.push(...applicationCode)) log.debug('Successfully got used round ids for', { courseCode,