import axios from 'axios'; import { GoogleGenAI } from '@google/genai'; import prisma from '../database.js'; // Import Prisma client // --- Environment Variables --- const { MANTIS_API_KEY, MANTIS_API_ENDPOINT, GOOGLE_API_KEY } = process.env; // --- Mantis Summarizer Setup --- const ai = GOOGLE_API_KEY ? new GoogleGenAI({ apiKey: GOOGLE_API_KEY, }) : null; const usernameMap = { 'credmore': 'Cameron Redmore', 'dgibson': 'Dane Gibson', 'egzibovskis': 'Ed Gzibovskis', 'ascotney': 'Amanda Scotney', 'gclough': 'Garry Clough', 'slee': 'Sarah Lee', 'dwalker': 'Dave Walker', 'askaith': 'Amy Skaith', 'dpotter': 'Danny Potter', 'msmart': 'Michael Smart', // Add other usernames as needed }; async function getMantisTickets() { if (!MANTIS_API_ENDPOINT || !MANTIS_API_KEY) { throw new Error("Mantis API endpoint or key not configured in environment variables."); } const url = `${MANTIS_API_ENDPOINT}/issues?project_id=1&page_size=50&select=id,summary,description,created_at,updated_at,reporter,notes`; const headers = { 'Authorization': `${MANTIS_API_KEY}`, 'Accept': 'application/json', 'Content-Type': 'application/json', }; try { const response = await axios.get(url, { headers }); const tickets = response.data.issues.filter((ticket) => { const ticketDate = new Date(ticket.updated_at); const thresholdDate = new Date(); const currentDay = thresholdDate.getDay(); // Sunday = 0, Monday = 1, ... // Go back 4 days if Monday (to include Fri, Sat, Sun), otherwise 2 days const daysToSubtract = currentDay === 1 ? 4 : 2; thresholdDate.setDate(thresholdDate.getDate() - daysToSubtract); thresholdDate.setHours(0, 0, 0, 0); // Start of the day return ticketDate >= thresholdDate; }).map((ticket) => { return { id: ticket.id, summary: ticket.summary, description: ticket.description, created_at: ticket.created_at, updated_at: ticket.updated_at, reporter: usernameMap[ticket.reporter?.username] || ticket.reporter?.name || 'Unknown Reporter', // Safer access notes: (ticket.notes ? ticket.notes.filter((note) => { const noteDate = new Date(note.created_at); const thresholdDate = new Date(); const currentDay = thresholdDate.getDay(); const daysToSubtract = currentDay === 1 ? 4 : 2; thresholdDate.setDate(thresholdDate.getDate() - daysToSubtract); thresholdDate.setHours(0, 0, 0, 0); // Start of the day return noteDate >= thresholdDate; }) : []).map((note) => { const reporter = usernameMap[note.reporter?.username] || note.reporter?.name || 'Unknown Reporter'; // Safer access return { reporter, created_at: note.created_at, text: note.text, }; }), }; }); return tickets; } catch (error) { console.error("Error fetching Mantis tickets:", error.message); // Check if it's an Axios error and provide more details if (axios.isAxiosError(error)) { console.error("Axios error details:", error.response?.status, error.response?.data); throw new Error(`Failed to fetch Mantis tickets: ${error.response?.statusText || error.message}`); } throw new Error(`Failed to fetch Mantis tickets: ${error.message}`); } } // --- Mantis Summary Logic (Exported) --- // export async function generateAndStoreMantisSummary() { console.log('Attempting to generate and store Mantis summary...'); if (!ai) { console.error('Google AI API key not configured. Skipping summary generation.'); return; } try { // Get the prompt from the database settings using Prisma const setting = await prisma.setting.findUnique({ where: { key: 'mantisPrompt' }, select: { value: true } }); const promptTemplate = setting?.value; if (!promptTemplate) { console.error('Mantis prompt not found in database settings (key: mantisPrompt). Skipping summary generation.'); return; } const tickets = await getMantisTickets(); let summaryText; if (tickets.length === 0) { summaryText = "No Mantis tickets updated recently."; console.log('No recent Mantis tickets found.'); } else { console.log(`Found ${tickets.length} recent Mantis tickets. Generating summary...`); let prompt = promptTemplate.replaceAll("$DATE", new Date().toISOString().split('T')[0]); prompt = prompt.replaceAll("$MANTIS_TICKETS", JSON.stringify(tickets, null, 2)); const response = await ai.models.generateContent({ "model": "gemini-2.5-flash-preview-04-17", "contents": prompt, config: { temperature: 0 } }); summaryText = response.text; console.log('Mantis summary generated successfully by AI.'); } // Store the summary in the database using Prisma upsert const today = new Date(); today.setUTCHours(0, 0, 0, 0); // Use UTC start of day for consistency await prisma.mantisSummary.upsert({ where: { summaryDate: today }, update: { summaryText: summaryText, // generatedAt is updated automatically by @default(now()) }, create: { summaryDate: today, summaryText: summaryText, }, }); console.log(`Mantis summary for ${today.toISOString().split('T')[0]} stored/updated in the database.`); } catch (error) { console.error("Error during Mantis summary generation/storage:", error); } } export async function generateTodaysSummary() { console.log('Triggering Mantis summary generation via generateTodaysSummary...'); try { await generateAndStoreMantisSummary(); return { success: true, message: 'Summary generation process initiated.' }; } catch (error) { console.error('Error occurred within generateTodaysSummary while calling generateAndStoreMantisSummary:', error); throw new Error('Failed to initiate Mantis summary generation.'); } }