diff --git a/assignment-db-service/app.js b/assignment-db-service/app.js index f35f6d8..16699b8 100644 --- a/assignment-db-service/app.js +++ b/assignment-db-service/app.js @@ -28,6 +28,7 @@ async function encryptPassword(password) { //function to conver req.body to assignment async function convertToAssignment(req) { + console.log("Converting request body to assignment object..."); const { campid, programid, @@ -41,22 +42,39 @@ async function convertToAssignment(req) { instructorid } = req.body; + console.log("Request body fields:", { + campid, + programid, + studentname, + snakegameid, + appname, + qrcodenumber, + description, + assignmenturl, + password, + instructorid + }); + const hashPassword = await encryptPassword(req.body.password); - return { - campid: parseInt(campid), - programid: parseInt(programid), - studentname: studentname, - snakegameid: snakegameid, - appname: appname, - qrcodenumber: parseInt(qrcodenumber), - description: description, - // originalfile: originalfile, - // editablefile: editablefile, - assignmenturl: assignmenturl, - passwordhash: hashPassword, - instructorid: parseInt(instructorid), - }; + console.log("Password hash generated:", hashPassword); + + const assignment = { + campid: campid ? parseInt(campid) : null, + programid: programid ? parseInt(programid) : null, + studentname: studentname || null, + snakegameid: snakegameid || null, + appname: appname || null, + qrcodenumber: qrcodenumber ? parseInt(qrcodenumber) : null, + description: description || null, + assignmenturl: assignmenturl || null, + passwordhash: hashPassword || null, + instructorid: instructorid ? parseInt(instructorid) : null, + }; + + console.log("Converted assignment object:", assignment); + + return assignment; } // Create Assignment @@ -88,6 +106,7 @@ app.get("/assignments/instructor/:instructorId", async (req, res) => { console.log("InstructorID:", instructorId); const assignments = await prisma.assignments.findMany({ where: { instructorid: parseInt(instructorId) }, + orderBy: { assignmentid: 'asc' }, }); if (assignments.length === 0) { @@ -121,15 +140,51 @@ app.get("/assignments/:qrNumber", async (req, res) => { } }); +//get assignment by appname +app.get("/assignments/appname/:appName", async (req, res) => { + try { + const { appName } = req.params; + const assignments = await prisma.assignments.findMany({ + where: { appname: appName }, + }); + + if (assignments.length === 0) { + return res.status(404).json({ message: "No assignments found" }); + } + + res.json(assignments); + } catch (err) { + console.error("Error fetching assignments:", err.message); + res.status(500).json({ error: err.message }); + } +}); + // Update Assignment app.put("/assignments/:id", async (req, res) => { try { const { id } = req.params; const assignment = await convertToAssignment(req); + const existingAssignment = await prisma.assignments.findUnique({ + where: { assignmentid: parseInt(id) }, + }); + + if (!existingAssignment) { + return res.status(404).json({ message: "Assignment not found" }); + } + + // Update only the fields that are provided in the request body + Object.keys(assignment).forEach((key) => { + if (assignment[key]) { + existingAssignment[key] = assignment[key]; + } + }); + + console.log("Existing Assignment before update:", existingAssignment); + const updatedAssignment = await prisma.assignments.update({ where: { assignmentid: parseInt(id) }, - data: assignment, + data: existingAssignment, }); res.json({ diff --git a/assignment-db-service/prisma/schema.prisma b/assignment-db-service/prisma/schema.prisma index 5cf5df5..4d1a053 100644 --- a/assignment-db-service/prisma/schema.prisma +++ b/assignment-db-service/prisma/schema.prisma @@ -14,8 +14,8 @@ model assignments { programid Int? studentname String? snakegameid String? - qrcodenumber Int @unique - appname String @unique + qrcodenumber Int? @unique + appname String? @unique description String? passwordhash String? // store bcrypt hash assignmenturl String? diff --git a/assignment-service/package-lock.json b/assignment-service/package-lock.json index c14f56e..d8dba1c 100644 --- a/assignment-service/package-lock.json +++ b/assignment-service/package-lock.json @@ -160,6 +160,21 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/aws-sdk": { "version": "2.1692.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1692.0.tgz", @@ -341,6 +356,24 @@ "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -539,6 +572,23 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -864,6 +914,21 @@ } } }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/form-data": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", @@ -1069,6 +1134,18 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -1238,6 +1315,18 @@ "node": ">=8" } }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1819,6 +1908,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -2125,6 +2223,23 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "license": "ISC" }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -2502,8 +2617,19 @@ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "license": "MIT", "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/wide-align": { diff --git a/assignment-service/routes/InstructorRouter.js b/assignment-service/routes/InstructorRouter.js index 9cd23d6..51d9394 100644 --- a/assignment-service/routes/InstructorRouter.js +++ b/assignment-service/routes/InstructorRouter.js @@ -4,27 +4,6 @@ const axios = require("axios"); const multer = require("multer"); const FormData = require("form-data"); -const fs = require('fs'); -const path = require('path'); -const AWS = require('aws-sdk'); - -// const { -// COMMON_BUCKET, -// AWS_ACCESS_KEY_ID, -// AWS_SECRET_ACCESS_KEY, -// AWS_ENDPOINT_URL_S3, -// AWS_REGION, -// } = process.env; - -// Log environment variables for debugging -// console.log('--- ENV START ---'); -// console.log('COMMON_BUCKET: ', COMMON_BUCKET); -// console.log('AWS_ACCESS_KEY_ID: ', AWS_ACCESS_KEY_ID ? '(found)' : '(NOT SET)'); -// console.log('AWS_SECRET_ACCESS_KEY:', AWS_SECRET_ACCESS_KEY ? '(found)' : '(NOT SET)'); -// console.log('AWS_ENDPOINT_URL_S3: ', AWS_ENDPOINT_URL_S3); -// console.log('AWS_REGION: ', AWS_REGION); -// console.log('--- ENV END ---'); - const DB_ASSIGNMENT_SERVICE_URL = process.env.DB_ASSIGNMENT_SERVICE_URL || "http://localhost:3000"; @@ -33,14 +12,6 @@ const DEPLOY_API_URL = process.env.DEPLOY_API_URL || "http://localhost:3600"; console.log("DB_ASSIGNMENT_SERVICE_URL:", DB_ASSIGNMENT_SERVICE_URL); console.log("DEPLOY_API_URL:", DEPLOY_API_URL); - -// const s3 = new AWS.S3({ -// endpoint: AWS_ENDPOINT_URL_S3, -// region: AWS_REGION, -// credentials: new AWS.Credentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), -// s3ForcePathStyle: true -// }); - // Use memory storage to keep file in RAM const upload = multer({ storage: multer.memoryStorage() }); @@ -65,17 +36,6 @@ intructorRouter.post( ); console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data); - // Upload the file to the S3 bucket - // console.log('Uploading notebook to S3'); - // const key = `${assignmentData.appname}/notebooks/${Date.now()}-notebook.ipynb`; - // console.log('S3 key:', key); - // await s3.putObject({ - // Bucket: COMMON_BUCKET, - // Key: key, - // Body: file.buffer, - // ContentType: 'application/json' - // }).promise(); - // call upload api to upload the file to S3 console.log("Uploading file to:", `${DEPLOY_API_URL}/${assignmentData.appname}/upload`); const uploadResponse = await axios.post(`${DEPLOY_API_URL}/${assignmentData.appname}/upload`, { @@ -126,12 +86,11 @@ intructorRouter.get( // if (req.isAuthenticated()) { try { const instructorId = req.params.id; - console.log("Fetching assignments for instructorId:", instructorId); - // const instructorId = req.user.userid; // Assuming req.user contains the authenticated user + // console.log("Fetching assignments for instructorId:", instructorId); const response = await axios.get( `${DB_ASSIGNMENT_SERVICE_URL}/assignments/instructor/${instructorId}` ); - console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data); + // console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data); res.status(response.status).json(response.data); } catch (error) { res.status(error.response?.status || 500).json({ error: error.message }); @@ -145,17 +104,23 @@ intructorRouter.get( // This endpoint is for instructors to update an assignment intructorRouter.put( "/update/:id", + upload.none(), // No file upload for this endpoint // passport.authenticate("jwt", { session: false }), async (req, res) => { try { const assignmentId = req.params.id; + console.log("Updating assignment with ID:", assignmentId); + console.log("Request body:", req.body); const response = await axios.put( `${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`, req.body ); + + console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data); res.status(response.status).json(response.data); } catch (error) { + console.error("Error updating assignment:", error.message); res.status(error.response?.status || 500).json({ error: error.message }); } } diff --git a/assignment-service/server.js b/assignment-service/server.js index 7c408ee..b20c3eb 100644 --- a/assignment-service/server.js +++ b/assignment-service/server.js @@ -71,4 +71,4 @@ app.get("/notebook/:appName", async (req, res) => { }); const port = process.env.NODE_PORT || 8080; -app.listen(port, "::", () => console.log(`Listening on :::${port}...`)); +app.listen({ port: port, host: '::', ipv6Only: false }, () => console.log(`Listening on ${port}...`));