mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 20:35:23 +02:00
84 lines
3.7 KiB
TypeScript
84 lines
3.7 KiB
TypeScript
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|||
|
|
|
||
|
|
const SYSTEM_INSTRUCTION = `
|
||
|
|
You are an expert Key Account Manager (KAM) and Senior Sales Strategist for "Craze Analytix".
|
||
|
|
Your specialty is analyzing retail data, advertising performance, and market trends to provide high-level strategic recommendations.
|
||
|
|
|
||
|
|
You have access to a detailed report of the currently filtered sales and advertising data.
|
||
|
|
The data includes Sell Out (€), Units Sold, Product Lines, Customer Markets, Seasonality (Monthly Trends), and Growth/Decline metrics.
|
||
|
|
|
||
|
|
Your objective:
|
||
|
|
1. **Analyze**: Deeply study the provided data according to the user's specific query.
|
||
|
|
2. **Opinion**: Provide expert opinions on the health of the business, product performance, or market position.
|
||
|
|
3. **Recommendations**: Give actionable, professional advice to improve sales, ROAS, stock health, or market share.
|
||
|
|
|
||
|
|
Guidelines:
|
||
|
|
- Maintain a professional, consultative, and business-driven tone (KAM style).
|
||
|
|
- Always justify your recommendations with specific numbers from the data.
|
||
|
|
- If asked about "Trends" or "Seasonality", look at the Monthly Seasonality section.
|
||
|
|
- If asked about "Growth" or "Decline", look at the Top/Bottom Movers sections.
|
||
|
|
- When comparing metrics, calculate variances or ratios if relevant (e.g. Sales vs Ads growth).
|
||
|
|
- Format your response with clear headers and bullet points for readability.
|
||
|
|
- Respond in the same language as the user's question (e.g., if they ask in Spanish, answer in Spanish).
|
||
|
|
`;
|
||
|
|
|
||
|
|
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||
|
|
// CORS headers
|
||
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||
|
|
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
||
|
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
||
|
|
|
||
|
|
if (req.method === 'OPTIONS') {
|
||
|
|
return res.status(200).end();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (req.method !== 'POST') {
|
||
|
|
return res.status(405).json({ error: 'Method not allowed' });
|
||
|
|
}
|
||
|
|
|
||
|
|
const apiKey = process.env.GEMINI_API_KEY || process.env.API_KEY;
|
||
|
|
|
||
|
|
if (!apiKey) {
|
||
|
|
console.error('[ask-gemini] GEMINI_API_KEY is not set in environment variables');
|
||
|
|
return res.status(500).json({ error: 'API Key is not configured on the server. Please add GEMINI_API_KEY to Vercel Environment Variables.' });
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const { question, context } = req.body;
|
||
|
|
|
||
|
|
if (!question || !context) {
|
||
|
|
return res.status(400).json({ error: 'Missing question or context in request body' });
|
||
|
|
}
|
||
|
|
|
||
|
|
// Call Gemini API directly via REST (no SDK needed server-side)
|
||
|
|
const geminiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`;
|
||
|
|
|
||
|
|
const response = await fetch(geminiUrl, {
|
||
|
|
method: 'POST',
|
||
|
|
headers: { 'Content-Type': 'application/json' },
|
||
|
|
body: JSON.stringify({
|
||
|
|
system_instruction: {
|
||
|
|
parts: [{ text: SYSTEM_INSTRUCTION }]
|
||
|
|
},
|
||
|
|
contents: [{
|
||
|
|
parts: [{ text: `Context Data:\n${context}\n\nUser Question: ${question}` }]
|
||
|
|
}]
|
||
|
|
})
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
const errorData = await response.text();
|
||
|
|
console.error('[ask-gemini] Gemini API error:', response.status, errorData);
|
||
|
|
throw new Error(`Gemini API error: ${response.status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const data = await response.json();
|
||
|
|
const text = data?.candidates?.[0]?.content?.parts?.[0]?.text || "I couldn't generate a response.";
|
||
|
|
|
||
|
|
res.status(200).json({ response: text });
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error('[ask-gemini] Error:', error);
|
||
|
|
res.status(500).json({ error: error.message || 'An unexpected error occurred' });
|
||
|
|
}
|
||
|
|
}
|