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 };