UNPKG

@tiledesk/tiledesk-server

Version:
269 lines (229 loc) 8.15 kB
const express = require('express'); const router = express.Router(); const { Namespace, UnansweredQuestion } = require('../models/kb_setting'); var winston = require('../config/winston'); // Add a new unanswered question router.post('/', async (req, res) => { try { const { namespace, question, request_id, sender } = req.body; const id_project = req.projectid; if (!namespace || !question) { return res.status(400).json({ success: false, error: "Missing required parameters: namespace and question" }); } // Check if namespace belongs to project const isValidNamespace = await validateNamespace(id_project, namespace); if (!isValidNamespace) { return res.status(403).json({ success: false, error: "Not allowed. The namespace does not belong to the current project." }); } const unansweredQuestion = new UnansweredQuestion({ id_project, namespace, question, request_id, sender }); const savedQuestion = await unansweredQuestion.save(); res.status(200).json(savedQuestion); } catch (error) { winston.error('Error adding unanswered question:', error); res.status(500).json({ success: false, error: "Error adding unanswered question" }); } }); // Get all unanswered questions for a namespace router.get('/:namespace', async (req, res) => { try { const { namespace } = req.params; const id_project = req.projectid; if (!namespace) { return res.status(400).json({ success: false, error: "Missing required parameter: namespace" }); } // Check if namespace belongs to project const isValidNamespace = await validateNamespace(id_project, namespace); if (!isValidNamespace) { return res.status(403).json({ success: false, error: "Not allowed. The namespace does not belong to the current project." }); } const page = parseInt(req.query.page) || 0; const limit = parseInt(req.query.limit) || 20; const sortField = req.query.sortField || 'createdAt'; const direction = parseInt(req.query.direction) || -1; const filter = { id_project, namespace }; let projection = undefined; if (req.query.search) { filter.$text = { $search: req.query.search }; // Add score to projection if it's a text search projection = { score: { $meta: "textScore" } }; } let sortObj; if (projection && projection.score) { sortObj = { score: { $meta: "textScore" } }; } else { sortObj = { [sortField]: direction }; } const questions = await UnansweredQuestion.find(filter, projection) .sort(sortObj) .skip(page * limit) .limit(limit); const count = await UnansweredQuestion.countDocuments(filter); res.status(200).json({ count, questions, query: { page, limit, sortField, direction, search: req.query.search || undefined } }); } catch (error) { winston.error('Error getting unanswered questions:', error); res.status(500).json({ success: false, error: "Error getting unanswered questions" }); } }); // Delete a specific unanswered question router.delete('/:id', async (req, res) => { try { const { id } = req.params; const id_project = req.projectid; const deleted = await UnansweredQuestion.findOneAndDelete({ _id: id, id_project }); if (!deleted) { return res.status(404).json({ success: false, error: "Question not found" }); } res.status(200).json({ success: true, message: "Question deleted successfully" }); } catch (error) { winston.error('Error deleting unanswered question:', error); res.status(500).json({ success: false, error: "Error deleting unanswered question" }); } }); // Delete all unanswered questions for a namespace router.delete('/namespace/:namespace', async (req, res) => { try { const { namespace } = req.params; const id_project = req.projectid; // Check if namespace belongs to project const isValidNamespace = await validateNamespace(id_project, namespace); if (!isValidNamespace) { return res.status(403).json({ success: false, error: "Not allowed. The namespace does not belong to the current project." }); } const result = await UnansweredQuestion.deleteMany({ id_project, namespace }); res.status(200).json({ success: true, count: result.deletedCount, message: "All questions deleted successfully" }); } catch (error) { winston.error('Error deleting unanswered questions:', error); res.status(500).json({ success: false, error: "Error deleting unanswered questions" }); } }); // Update an unanswered question router.put('/:id', async (req, res) => { try { const { id } = req.params; const { question } = req.body; const id_project = req.projectid; if (!question) { return res.status(400).json({ success: false, error: "Missing required parameter: question" }); } const updatedQuestion = await UnansweredQuestion.findOneAndUpdate( { _id: id, id_project }, { question }, { new: true } ); if (!updatedQuestion) { return res.status(404).json({ success: false, error: "Question not found" }); } res.status(200).json(updatedQuestion); } catch (error) { winston.error('Error updating unanswered question:', error); res.status(500).json({ success: false, error: "Error updating unanswered question" }); } }); // Count unanswered questions for a namespace router.get('/count/:namespace', async (req, res) => { try { const { namespace } = req.params; const id_project = req.projectid; if (!namespace) { return res.status(400).json({ success: false, error: "Missing required parameter: namespace" }); } // Check if namespace belongs to project const isValidNamespace = await validateNamespace(id_project, namespace); if (!isValidNamespace) { return res.status(403).json({ success: false, error: "Not allowed. The namespace does not belong to the current project." }); } const count = await UnansweredQuestion.countDocuments({ id_project, namespace }); res.status(200).json({ count }); } catch (error) { winston.error('Error counting unanswered questions:', error); res.status(500).json({ success: false, error: "Error counting unanswered questions" }); } }); // Helper function to validate namespace async function validateNamespace(id_project, namespace_id) { try { const namespace = await Namespace.findOne({ id_project: id_project, id: namespace_id }); return !!namespace; // return true if namespace exists, false otherwise } catch (err) { winston.error("validate namespace error: ", err); throw err; } } module.exports = router;