221 lines
5.3 KiB
JavaScript
221 lines
5.3 KiB
JavaScript
const { Feedback, Message, User, sequelize } = require('../models');
|
|
const { Op } = require('sequelize');
|
|
const logger = require('../utils/logger');
|
|
|
|
const submitFeedback = async (req, res) => {
|
|
try {
|
|
const { messageId, feedbackType, rating, comment, correctedContent } = req.body;
|
|
const userId = req.user.userId;
|
|
|
|
// Validate feedback type
|
|
const validTypes = ['positive', 'negative', 'correction', 'suggestion'];
|
|
if (!validTypes.includes(feedbackType)) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Invalid feedback type'
|
|
});
|
|
}
|
|
|
|
// Validate rating if provided
|
|
if (rating && (rating < 1 || rating > 5)) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Rating must be between 1 and 5'
|
|
});
|
|
}
|
|
|
|
// Verify message exists if messageId provided
|
|
if (messageId) {
|
|
const message = await Message.findByPk(messageId);
|
|
if (!message) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
error: 'Message not found'
|
|
});
|
|
}
|
|
}
|
|
|
|
const feedback = await Feedback.create({
|
|
user_id: userId,
|
|
message_id: messageId,
|
|
feedback_type: feedbackType,
|
|
rating,
|
|
comment,
|
|
corrected_content: correctedContent,
|
|
is_processed: false
|
|
});
|
|
|
|
logger.info(`Feedback submitted: ${feedback.id} by user ${userId}`);
|
|
|
|
res.status(201).json({
|
|
success: true,
|
|
data: { feedback }
|
|
});
|
|
} catch (error) {
|
|
logger.error('Submit feedback error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Internal server error'
|
|
});
|
|
}
|
|
};
|
|
|
|
const getFeedback = async (req, res) => {
|
|
try {
|
|
const { feedbackId } = req.params;
|
|
|
|
const feedback = await Feedback.findByPk(feedbackId, {
|
|
include: [
|
|
{
|
|
model: User,
|
|
attributes: ['id', 'email', 'first_name', 'last_name']
|
|
},
|
|
{
|
|
model: Message,
|
|
attributes: ['id', 'content', 'role']
|
|
}
|
|
]
|
|
});
|
|
|
|
if (!feedback) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
error: 'Feedback not found'
|
|
});
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
data: { feedback }
|
|
});
|
|
} catch (error) {
|
|
logger.error('Get feedback error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Internal server error'
|
|
});
|
|
}
|
|
};
|
|
|
|
const getFeedbackList = async (req, res) => {
|
|
try {
|
|
const { page = 1, limit = 10, feedbackType, isProcessed, userId } = req.query;
|
|
|
|
const whereClause = {};
|
|
if (feedbackType) whereClause.feedback_type = feedbackType;
|
|
if (isProcessed !== undefined) whereClause.is_processed = isProcessed === 'true';
|
|
if (userId) whereClause.user_id = userId;
|
|
|
|
const feedback = await Feedback.findAndCountAll({
|
|
where: whereClause,
|
|
include: [
|
|
{
|
|
model: User,
|
|
attributes: ['id', 'email', 'first_name', 'last_name']
|
|
},
|
|
{
|
|
model: Message,
|
|
attributes: ['id', 'content', 'role']
|
|
}
|
|
],
|
|
order: [['created_at', 'DESC']],
|
|
limit: parseInt(limit),
|
|
offset: (parseInt(page) - 1) * parseInt(limit)
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
feedback: feedback.rows,
|
|
pagination: {
|
|
page: parseInt(page),
|
|
limit: parseInt(limit),
|
|
total: feedback.count,
|
|
pages: Math.ceil(feedback.count / parseInt(limit))
|
|
}
|
|
}
|
|
});
|
|
} catch (error) {
|
|
logger.error('Get feedback list error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Internal server error'
|
|
});
|
|
}
|
|
};
|
|
|
|
const processFeedback = async (req, res) => {
|
|
try {
|
|
const { feedbackId } = req.params;
|
|
const { processingNotes } = req.body;
|
|
|
|
const feedback = await Feedback.findByPk(feedbackId);
|
|
|
|
if (!feedback) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
error: 'Feedback not found'
|
|
});
|
|
}
|
|
|
|
await feedback.update({
|
|
is_processed: true,
|
|
processing_notes: processingNotes
|
|
});
|
|
|
|
logger.info(`Feedback processed: ${feedbackId}`);
|
|
|
|
res.json({
|
|
success: true,
|
|
data: { feedback }
|
|
});
|
|
} catch (error) {
|
|
logger.error('Process feedback error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Internal server error'
|
|
});
|
|
}
|
|
};
|
|
|
|
const getFeedbackStats = async (req, res) => {
|
|
try {
|
|
const stats = await Feedback.findAll({
|
|
attributes: [
|
|
'feedback_type',
|
|
[sequelize.fn('COUNT', sequelize.col('id')), 'count'],
|
|
[sequelize.fn('AVG', sequelize.col('rating')), 'avg_rating']
|
|
],
|
|
group: ['feedback_type'],
|
|
raw: true
|
|
});
|
|
|
|
const totalFeedback = await Feedback.count();
|
|
const processedFeedback = await Feedback.count({ where: { is_processed: true } });
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
stats,
|
|
total: totalFeedback,
|
|
processed: processedFeedback,
|
|
unprocessed: totalFeedback - processedFeedback
|
|
}
|
|
});
|
|
} catch (error) {
|
|
logger.error('Get feedback stats error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Internal server error'
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
submitFeedback,
|
|
getFeedback,
|
|
getFeedbackList,
|
|
processFeedback,
|
|
getFeedbackStats
|
|
};
|