import express from 'express'; import cors from 'cors'; import dotenv from 'dotenv'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { GoogleGenerativeAI } from '@google/generative-ai'; import { getPromptForActivity } from './prompts.js'; dotenv.config(); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); const port = 3001; app.use(cors()); app.use(express.json()); // Initialize Gemini API const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY || ''); // ============================================ // GALLERY STORAGE - Recent 6 generations // ============================================ const GALLERY_FILE = path.join(__dirname, 'gallery.json'); const MAX_GALLERY_SIZE = 6; // Load gallery from file function loadGallery() { try { if (fs.existsSync(GALLERY_FILE)) { const data = fs.readFileSync(GALLERY_FILE, 'utf8'); return JSON.parse(data); } } catch (error) { console.error('Error loading gallery:', error); } return []; } // Save gallery to file function saveGallery(gallery) { try { fs.writeFileSync(GALLERY_FILE, JSON.stringify(gallery, null, 2)); } catch (error) { console.error('Error saving gallery:', error); } } // Add item to gallery (keeps only recent 6) function addToGallery(item) { const gallery = loadGallery(); // Add new item at the beginning gallery.unshift({ ...item, id: Date.now(), createdAt: new Date().toISOString() }); // Keep only the most recent 6 while (gallery.length > MAX_GALLERY_SIZE) { gallery.pop(); } saveGallery(gallery); return gallery; } // ============================================ // API ENDPOINTS // ============================================ // Get recent gallery items app.get('/api/gallery', (req, res) => { try { const gallery = loadGallery(); res.json(gallery); } catch (error) { console.error('Gallery fetch error:', error); res.status(500).json({ error: 'Failed to fetch gallery' }); } }); app.post('/api/surprise', async (req, res) => { try { if (!process.env.GEMINI_API_KEY) { return res.status(500).json({ error: 'Missing API Key' }); } const model = genAI.getGenerativeModel({ model: "gemini-2.5-pro" }); const prompt = ` Generate ONE creative, fun, specific theme for a children's worksheet (e.g. "Space-Rex Coding", "Underwater Hamster Tea Party"). Pick a random age between 3 and 7. Pick a random activity type from: coloring, numbers, writing, find-way, counting. Return JSON ONLY: { "theme": "string", "age": number, "section": "string" } `; const result = await model.generateContent(prompt); const text = result.response.text(); const jsonStr = text.replace(/```json/g, '').replace(/```/g, '').trim(); res.json(JSON.parse(jsonStr)); } catch (error) { console.error('Surprise error:', error); res.status(500).json({ error: 'Failed' }); } }); app.post('/api/generate', async (req, res) => { try { const { theme, age, sections } = req.body; console.log('Received generation request:', { theme, age, sections }); if (!process.env.GEMINI_API_KEY) { console.warn('Missing GEMINI_API_KEY'); return res.status(500).json({ error: 'Server configuration error: Missing API Key' }); } const model = genAI.getGenerativeModel({ model: "gemini-2.5-pro" }); // Get the activity-specific prompt for the first section const activityType = sections[0] || 'coloring'; const prompt = getPromptForActivity(activityType, theme, age); console.log(`Using specialized prompt for activity: ${activityType}`); const result = await model.generateContent(prompt); const response = await result.response; const text = response.text(); // Cleanup markdown code blocks if present const jsonStr = text.replace(/```json/g, '').replace(/```/g, '').trim(); const data = JSON.parse(jsonStr); if (!data.title || !data.sections || !Array.isArray(data.sections)) { throw new Error('Invalid generation format'); } // Save to gallery const galleryItem = { ...data, age, activityType }; addToGallery(galleryItem); console.log('Added to gallery, current size:', loadGallery().length); res.json(data); } catch (error) { console.error('Generation error:', error); res.status(500).json({ error: 'Failed to generate content' }); } }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });