const router = require('express').Router(); const { moderationText } = require('./initiatives-ai-agents/moderation.ts'); const { generatePicture } = require('./initiatives-ai-agents/picture.ts'); const { getSupabaseClient } = require('./supabaseClient'); const { getGigaAuth } = require('./get-constants'); async function getGigaKey() { const GIGA_AUTH = await getGigaAuth(); return GIGA_AUTH; } // Обработчик для модерации и создания инициативы router.post('/moderate', async (req, res) => { const GIGA_AUTH = await getGigaKey(); try { const { title, description, building_id, creator_id, target_amount, status } = req.body; if (!title || !description) { res.status(400).json({ error: 'Заголовок и описание обязательны' }); return; } if (!building_id || !creator_id) { res.status(400).json({ error: 'ID дома и создателя обязательны' }); return; } // Валидация статуса, если передан const validStatuses = ['moderation', 'review', 'fundraising', 'approved', 'rejected']; if (status && !validStatuses.includes(status)) { res.status(400).json({ error: `Недопустимый статус. Допустимые значения: ${validStatuses.join(', ')}` }); return; } console.log('Запрос на модерацию:', { title: title.substring(0, 50), description: description.substring(0, 100) }); // Модерация текста (передаем title и description как body) const [comment, fixedText, isApproved] = await moderationText(title, description, GIGA_AUTH); // Если модерация не прошла, возвращаем undefined if (!isApproved) { if (!comment || comment.trim() === '') { console.warn('Обнаружен некорректный результат модерации - пустой комментарий при отклонении'); } res.json({ comment, fixedText, isApproved, initiative: undefined }); return; } // Модерация прошла, генерируем изображение используя заголовок как промпт console.log('Модерация прошла, генерируем изображение с промптом:', title); const imageBuffer = await generatePicture(title, GIGA_AUTH); if (!imageBuffer || imageBuffer.length === 0) { res.status(500).json({ error: 'Получен пустой буфер изображения' }); return; } // Получаем Supabase клиент и создаем имя файла const supabase = getSupabaseClient(); const timestamp = Date.now(); const filename = `image_${creator_id}_${timestamp}.jpg`; // Загружаем изображение в Supabase Storage let uploadResult; let retries = 0; const maxRetries = 5; while (retries < maxRetries) { try { uploadResult = await supabase.storage .from('images') .upload(filename, imageBuffer, { contentType: 'image/jpeg', upsert: true }); if (!uploadResult.error) { break; // Успешная загрузка } retries++; if (retries < maxRetries) { // Ждем перед повторной попыткой await new Promise(resolve => setTimeout(resolve, 1000 * retries)); } } catch (error) { console.warn(`Попытка загрузки ${retries + 1} неудачна (исключение):`, error.message); retries++; if (retries < maxRetries) { // Ждем перед повторной попыткой await new Promise(resolve => setTimeout(resolve, 1000 * retries)); } else { throw error; // Перебрасываем ошибку после всех попыток } } } if (uploadResult?.error) { console.error('Supabase storage error after all retries:', uploadResult.error); res.status(500).json({ error: 'Ошибка при сохранении изображения после нескольких попыток' }); return; } console.log('Изображение успешно загружено в Supabase Storage:', filename); // Получаем публичный URL const { data: urlData } = supabase.storage .from('images') .getPublicUrl(filename); // Определяем статус: если передан в запросе, используем его, иначе 'review' const finalStatus = status || 'review'; // Создаем инициативу в базе данных const { data: initiative, error: initiativeError } = await supabase .from('initiatives') .insert([{ building_id, creator_id, title: fixedText || title, description, status: finalStatus, target_amount: target_amount || null, current_amount: 0, image_url: urlData.publicUrl }]) .select() .single(); if (initiativeError) { console.error('Ошибка создания инициативы:', initiativeError); res.status(500).json({ error: 'Ошибка при создании инициативы', details: initiativeError.message }); return; } console.log('Инициатива успешно создана:', initiative.id); res.json({ comment, fixedText, isApproved, initiative }); } catch (error) { console.error('Error in moderation and initiative creation:', error); res.status(500).json({ error: 'Внутренняя ошибка сервера', details: error.message }); } }); module.exports = router;