diff --git a/server.js b/server.js index f87576f..67194d0 100644 --- a/server.js +++ b/server.js @@ -634,7 +634,7 @@ app.post('/upload', requireAuth, upload.single('noteFile'), async (req, res) => console.log('Response sent, starting async processing...'); // Process document asynchronously - processDocumentAsync(fileInfo, req.session.userId); + processDocumentAsync(fileInfo, req.session.userId, req.session); } catch (error) { console.error('Upload error:', error); @@ -647,13 +647,24 @@ app.post('/upload', requireAuth, upload.single('noteFile'), async (req, res) => }); // Async function to process document and upsert to Flowise using FormData -async function processDocumentAsync(fileInfo, userId) { +async function processDocumentAsync(fileInfo, userId, session) { try { console.log('=== DOCUMENT PROCESSING START (FormData) ==='); console.log(`Starting document processing for: ${fileInfo.originalName}`); console.log(`File path: ${fileInfo.path}`); console.log(`File size: ${fileInfo.size} bytes`); console.log(`User ID: ${userId}`); + console.log(`Session ID in processing: ${session.id || 'undefined'}`); + + // Find the file in the session to update it by reference + const sessionFile = session.uploadedFiles.find(f => f.id === fileInfo.id); + if (!sessionFile) { + console.error('File not found in session:', fileInfo.id); + console.error('Available files in session:', session.uploadedFiles.map(f => ({ id: f.id, name: f.originalName }))); + return; + } + + console.log('Found session file for update:', { id: sessionFile.id, name: sessionFile.originalName, currentStatus: sessionFile.status }); // Create document metadata const documentMetadata = { @@ -668,7 +679,7 @@ async function processDocumentAsync(fileInfo, userId) { console.log('Document metadata:', documentMetadata); // Initialize processing result - fileInfo.processingResult = { + sessionFile.processingResult = { totalChunks: 1, // FormData uploads are single operations successfulChunks: 0, failedChunks: 0, @@ -683,41 +694,71 @@ async function processDocumentAsync(fileInfo, userId) { console.log('FormData upsert result:', upsertResult); - // Update file info with processing results - fileInfo.status = upsertResult.success ? 'processed' : 'failed'; - fileInfo.processingProgress = null; // Clear progress when done - fileInfo.processingResult = { + // Update session file with processing results + sessionFile.status = upsertResult.success ? 'processed' : 'failed'; + sessionFile.processingProgress = null; // Clear progress when done + sessionFile.processingResult = { totalChunks: upsertResult.totalChunks, successfulChunks: upsertResult.successfulChunks, failedChunks: upsertResult.failedChunks, processedAt: new Date().toISOString(), - startedAt: fileInfo.processingResult.startedAt, - duration: Date.now() - new Date(fileInfo.processingResult.startedAt).getTime(), + startedAt: sessionFile.processingResult.startedAt, + duration: Date.now() - new Date(sessionFile.processingResult.startedAt).getTime(), method: 'formdata' }; if (upsertResult.errors.length > 0) { - fileInfo.processingErrors = upsertResult.errors; - console.log(`Processing errors for ${fileInfo.originalName}:`, upsertResult.errors); + sessionFile.processingErrors = upsertResult.errors; + console.log(`Processing errors for ${sessionFile.originalName}:`, upsertResult.errors); } - console.log(`Document processing completed for: ${fileInfo.originalName}`); + console.log(`Document processing completed for: ${sessionFile.originalName}`); console.log(`Result: FormData upload ${upsertResult.success ? 'successful' : 'failed'}`); + console.log(`Updated session file status to: ${sessionFile.status}`); + + // Verify the session file was updated + console.log('Session file after update:', { id: sessionFile.id, name: sessionFile.originalName, status: sessionFile.status }); + console.log('All session files after update:', session.uploadedFiles.map(f => ({ id: f.id, name: f.originalName, status: f.status }))); + + // Force session save since we modified it in an async context + session.save((err) => { + if (err) { + console.error('Error saving session after document processing:', err); + } else { + console.log('Session saved successfully after document processing'); + } + }); // Log final upsert verification console.log('Final FormData upsert verification:', { documentStore: `${FLOWISE_BASE_URL}/api/v1/document-store/${FLOWISE_DOCUMENT_STORE_ID}`, - documentId: fileInfo.id, - fileName: fileInfo.originalName, - success: upsertResult.success + documentId: sessionFile.id, + fileName: sessionFile.originalName, + success: upsertResult.success, + finalStatus: sessionFile.status }); } catch (error) { console.error(`Error processing document ${fileInfo.originalName}:`, error); - fileInfo.status = 'failed'; - fileInfo.processingError = error.message; - fileInfo.processingResult = fileInfo.processingResult || {}; - fileInfo.processingResult.failedAt = new Date().toISOString(); + + // Find the file in the session to update it with error + const sessionFile = session.uploadedFiles.find(f => f.id === fileInfo.id); + if (sessionFile) { + sessionFile.status = 'failed'; + sessionFile.processingError = error.message; + sessionFile.processingResult = sessionFile.processingResult || {}; + sessionFile.processingResult.failedAt = new Date().toISOString(); + console.log(`Updated session file status to: ${sessionFile.status} due to error`); + + // Force session save since we modified it in an async context + session.save((err) => { + if (err) { + console.error('Error saving session after processing error:', err); + } else { + console.log('Session saved successfully after processing error'); + } + }); + } } } @@ -806,34 +847,115 @@ app.post('/api/revise', requireAuth, async (req, res) => { }); app.get('/chat', requireAuth, (req, res) => { + // Initialize chat history if it doesn't exist + if (!req.session.chatHistory) { + req.session.chatHistory = []; + } + res.render('chat', { - title: 'Chat with EduCat AI' + title: 'Chat with EduCat AI', + chatHistory: req.session.chatHistory }); }); app.post('/api/chat', requireAuth, async (req, res) => { try { - const { message, history } = req.body; + const { message } = req.body; - // Call Flowise API for chat + // Initialize chat history in session if it doesn't exist + if (!req.session.chatHistory) { + req.session.chatHistory = []; + } + + console.log('Chat message received:', message); + console.log('Current chat history length:', req.session.chatHistory.length); + + // Call Flowise API for chat with session history const response = await axios.post(`${FLOWISE_API_URL}/${FLOWISE_CHATFLOW_ID}`, { question: message, - history: history || [] + history: req.session.chatHistory }); + const aiResponse = response.data.text || response.data.answer || 'No response received'; + + // Add the conversation to session history + req.session.chatHistory.push({ + human: message, + ai: aiResponse + }); + + // Save session explicitly since we modified it + req.session.save((err) => { + if (err) { + console.error('Error saving chat session:', err); + } + }); + + console.log('Updated chat history length:', req.session.chatHistory.length); + res.json({ success: true, - response: response.data.text || response.data.answer || 'No response received' + response: aiResponse }); } catch (error) { console.error('Chat error:', error); res.status(500).json({ + success: false, error: 'Failed to get chat response', details: error.message }); } }); +// Get chat history from session +app.get('/api/chat/history', requireAuth, (req, res) => { + try { + const chatHistory = req.session.chatHistory || []; + console.log('Chat history requested, returning', chatHistory.length, 'messages'); + + res.json({ + success: true, + history: chatHistory + }); + } catch (error) { + console.error('Error getting chat history:', error); + res.status(500).json({ + success: false, + error: 'Failed to get chat history', + details: error.message + }); + } +}); + +// Clear chat history +app.delete('/api/chat/history', requireAuth, (req, res) => { + try { + req.session.chatHistory = []; + req.session.save((err) => { + if (err) { + console.error('Error clearing chat session:', err); + return res.status(500).json({ + success: false, + error: 'Failed to clear chat history' + }); + } + + console.log('Chat history cleared for user:', req.session.userId); + res.json({ + success: true, + message: 'Chat history cleared' + }); + }); + } catch (error) { + console.error('Error clearing chat history:', error); + res.status(500).json({ + success: false, + error: 'Failed to clear chat history', + details: error.message + }); + } +}); + app.get('/dashboard', requireAuth, (req, res) => { const files = req.session.uploadedFiles || []; res.render('dashboard', { @@ -921,6 +1043,12 @@ app.get('/api/files/:fileId/status', requireAuth, async (req, res) => { const files = req.session.uploadedFiles || []; const file = files.find(f => f.id === fileId); + console.log(`Status requested for file ${fileId}`); + console.log(`Session ID: ${req.session.id || req.sessionID}`); + console.log(`User ID: ${req.session.userId}`); + console.log(`Files in session:`, files.map(f => ({ id: f.id, name: f.originalName, status: f.status }))); + console.log(`Found file:`, file ? { id: file.id, name: file.originalName, status: file.status } : 'Not found'); + if (!file) { return res.status(404).json({ success: false, error: 'File not found' }); } @@ -969,7 +1097,7 @@ app.post('/api/files/:fileId/retry', requireAuth, async (req, res) => { file.processingErrors = null; // Start processing asynchronously - processDocumentAsync(file, req.session.userId); + processDocumentAsync(file, req.session.userId, req.session); res.json({ success: true, @@ -989,6 +1117,8 @@ app.post('/api/files/:fileId/retry', requireAuth, async (req, res) => { app.get('/api/files/status/all', requireAuth, async (req, res) => { try { const files = req.session.uploadedFiles || []; + console.log('Status check requested for session files:', files.map(f => ({ id: f.id, name: f.originalName, status: f.status }))); + const statusSummary = files.map(file => ({ id: file.id, originalName: file.originalName, @@ -1010,6 +1140,8 @@ app.get('/api/files/status/all', requireAuth, async (req, res) => { files: statusSummary }; + console.log('Returning status summary:', summary); + res.json({ success: true, summary: summary diff --git a/views/chat.ejs b/views/chat.ejs index dfbc85c..156b7c1 100644 --- a/views/chat.ejs +++ b/views/chat.ejs @@ -5,23 +5,16 @@