79 lines
2.4 KiB
JavaScript
79 lines
2.4 KiB
JavaScript
import express from 'express';
|
|
import cors from 'cors';
|
|
import dotenv from 'dotenv';
|
|
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
|
|
dotenv.config();
|
|
|
|
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 || '');
|
|
|
|
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-flash" });
|
|
|
|
const prompt = `
|
|
Create educational worksheet metadata for a ${age}-year-old.
|
|
Theme: ${theme}
|
|
Sections: ${sections.join(', ')}
|
|
|
|
Return ONLY a valid JSON object.
|
|
|
|
STRICT SVG REQUIREMENTS:
|
|
1. Viewbox: '0 0 500 500'.
|
|
2. Style: Black stroke (#000000), white fill (#ffffff), no gradients/filters.
|
|
3. Pathing: All paths must be CLOSED and colorable. Use smooth curves.
|
|
4. Completeness: DO NOT TRUNCATE. Ensure the SVG code is 100% complete and valid XML.
|
|
5. Age-Appropriateness:
|
|
- For 3-4: Use 8px strokes, bold outlines, and 'toddler-friendly' shapes (huge circles, squares).
|
|
- For 5-7: Use 3px strokes, add interior textures (scales, leaves, stars), and more realistic proportions.
|
|
|
|
JSON Structure:
|
|
{
|
|
"title": "Title",
|
|
"subtitle": "Subtitle",
|
|
"sections": [
|
|
{
|
|
"id": "id",
|
|
"type": "coloring|writing|numbers",
|
|
"content_svg": "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500'>...</svg>"
|
|
}
|
|
]
|
|
}
|
|
|
|
CRITICAL: The 'content_svg' string must use SINGLE QUOTES for all XML attributes to prevent JSON parsing errors.
|
|
`;
|
|
|
|
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);
|
|
|
|
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}`);
|
|
});
|