From a16435b021fb889ab6d98da9c2eab804b0cbc7de Mon Sep 17 00:00:00 2001 From: Karma Riuk Date: Wed, 7 May 2025 13:05:15 +0200 Subject: [PATCH] added routes to sumbit the answers --- package.json | 3 +- src/routes/answers.js | 112 ++++++++++++++++++++++++++++++++++++++++++ src/routes/index.js | 4 ++ src/utils/errors.js | 6 +++ 4 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/routes/answers.js create mode 100644 src/utils/errors.js diff --git a/package.json b/package.json index 04454db..061361d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "dependencies": { "express": "^4.18.2", "cors": "^2.8.5", - "dotenv": "^16.3.1" + "dotenv": "^16.3.1", + "multer": "^1.4.5-lts.1" }, "devDependencies": { "nodemon": "^3.0.2", diff --git a/src/routes/answers.js b/src/routes/answers.js new file mode 100644 index 0000000..99e3b5c --- /dev/null +++ b/src/routes/answers.js @@ -0,0 +1,112 @@ +import { Router } from 'express'; +import multer from 'multer'; +import { InvalidJsonFormatError } from '../utils/errors.js'; + +const router = Router(); + +// Configure multer for file uploads +const upload = multer({ + storage: multer.memoryStorage(), + limits: { + fileSize: 200 * 1024 * 1024, // 200MB limit, since the comement gen is 147MB (deflated) + }, + fileFilter: (_req, file, cb) => { + // Accept only JSON files + if (file.mimetype === 'application/json') { + cb(null, true); + } else { + cb(new Error('Only JSON files are allowed')); + } + } +}); + +// Helper function to validate JSON format +const validateJsonFormat = (data) => { + try { + const parsed = JSON.parse(data); + // Check if it's an object + if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) { + throw new InvalidJsonFormatError("Submitted json doesn't contain an object"); + } + // Check if all values are strings + if (!Object.values(parsed).every(value => typeof value === 'string')) { + throw new InvalidJsonFormatError("Submitted json object must only be str -> str. Namely id -> comment"); + } + return parsed; + } catch (error) { + if (error instanceof InvalidJsonFormatError) { + throw error; + } + throw new InvalidJsonFormatError('Invalid JSON format'); + } +}; + +router.post('/submit/comments', upload.single('file'), async (req, res) => { + try { + if (!req.file) { + return res.status(400).json({ error: 'No file uploaded' }); + } + + const fileContent = req.file.buffer.toString(); + let validatedData; + + try { + validatedData = validateJsonFormat(fileContent); + } catch (error) { + if (error instanceof InvalidJsonFormatError) { + return res.status(400).json({ + error: 'Invalid JSON format', + message: error.message + }); + } + throw error; + } + + // TODO: Save the file or process it further + // For now, just return success + res.status(200).json({ + message: 'Answer submitted successfully', + data: validatedData + }); + + } catch (error) { + console.error('Error processing submission:', error); + res.status(500).json({ error: 'Error processing submission' }); + } +}); + +router.post('/submit/refinement', upload.single('file'), async (req, res) => { + try { + if (!req.file) { + return res.status(400).json({ error: 'No file uploaded' }); + } + + const fileContent = req.file.buffer.toString(); + let validatedData; + + try { + validatedData = validateJsonFormat(fileContent); + } catch (error) { + if (error instanceof InvalidJsonFormatError) { + return res.status(400).json({ + error: 'Invalid JSON format', + message: error.message + }); + } + throw error; + } + + // TODO: Save the file or process it further + // For now, just return success + res.status(200).json({ + message: 'Answer submitted successfully', + data: validatedData + }); + + } catch (error) { + console.error('Error processing submission:', error); + res.status(500).json({ error: 'Error processing submission' }); + } +}); + +export default router; diff --git a/src/routes/index.js b/src/routes/index.js index 507f994..da876e2 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,5 +1,6 @@ import { Router } from 'express'; import datasetRoutes from './datasets.js'; +import answerRoutes from './answers.js'; const router = Router(); @@ -16,4 +17,7 @@ router.get('/api/hello', (_req, res) => { // Dataset routes router.use('/datasets', datasetRoutes); +// Answer submission routes +router.use('/answers', answerRoutes); + export default router; diff --git a/src/utils/errors.js b/src/utils/errors.js new file mode 100644 index 0000000..b416da5 --- /dev/null +++ b/src/utils/errors.js @@ -0,0 +1,6 @@ +export class InvalidJsonFormatError extends Error { + constructor(message = 'JSON must be an object mapping strings to strings') { + super(message); + this.name = 'InvalidJsonFormatError'; + } +} \ No newline at end of file