Spaces:
Sleeping
Sleeping
import express from 'express'; | |
import cors from 'cors'; | |
import cron from 'node-cron'; | |
import { initializeDatabase, refreshData, searchByName } from './database.js'; | |
// --- Константы --- | |
const PORT = process.env.PORT || 7860; | |
const API_VERSION = "1.4"; | |
// --- Настройка приложения Express --- | |
const app = express(); | |
app.use(cors()); | |
app.use(express.json()); | |
let isReady = false; | |
// --- Middleware для проверки готовности --- | |
app.use((req, res, next) => { | |
if (!isReady && req.path !== '/health') { | |
return res.status(503).json({ message: 'Сервис временно недоступен, идет инициализация данных.', statusCode: 503 }); | |
} | |
next(); | |
}); | |
// --- API Эндпоинты --- | |
app.get('/health', (req, res) => { | |
res.status(200).json({ status: isReady ? 'UP' : 'DOWN', message: isReady ? 'Сервис готов к работе' : 'Идет инициализация' }); | |
}); | |
app.get(`/v${API_VERSION}/movie/search`, async (req, res) => { | |
const { query, page, limit } = req.query; | |
if (!query) { | |
return res.status(400).json({ message: 'Параметр "query" является обязательным.', statusCode: 400 }); | |
} | |
const pageNum = parseInt(page, 10) || 1; | |
const limitNum = Math.min(parseInt(limit, 10) || 10, 250); | |
try { | |
const { docs, total } = await searchByName(query, pageNum, limitNum); | |
const pages = Math.ceil(total / limitNum); | |
res.json({ docs, total, limit: limitNum, page: pageNum, pages }); | |
} catch (e) { | |
console.error(`Ошибка при поиске по запросу "${query}":`, e); | |
res.status(500).json({ message: 'Внутренняя ошибка сервера при поиске.', error: e.message }); | |
} | |
}); | |
// --- Логика запуска сервера --- | |
(async () => { | |
try { | |
// ИСПРАВЛЕНИЕ: Получаем объект 'db' после инициализации. | |
const db = await initializeDatabase(); | |
const needsRebuild = process.argv.includes('--rebuild-index'); | |
// ИСПРАВЛЕНИЕ: Используем полученный 'db' для запроса. | |
const result = await db.get('SELECT COUNT(*) as count FROM movies'); | |
const moviesCount = result.count; | |
if (needsRebuild || moviesCount === 0) { | |
if (needsRebuild) console.log('Обнаружен флаг --rebuild-index. Запуск принудительной переиндексации.'); | |
if (moviesCount === 0) console.log('База данных пуста. Запуск первоначальной загрузки.'); | |
await refreshData(); | |
} else { | |
console.log(`В базе уже есть ${moviesCount} фильмов. Запуск в штатном режиме.`); | |
} | |
isReady = true; | |
console.log('✅ Сервис готов к приему запросов!'); | |
app.listen(PORT, () => { | |
console.log(`🚀 Сервер поиска запущен на порту ${PORT}`); | |
console.log(`URL для поиска: http://localhost:${PORT}/v${API_VERSION}/movie/search`); | |
}); | |
cron.schedule('0 3 * * *', async () => { | |
console.log('Начало планового ежедневного обновления данных...'); | |
isReady = false; | |
try { | |
await refreshData(); | |
} catch (error) { | |
console.error('Критическая ошибка во время планового обновления:', error); | |
} | |
isReady = true; | |
console.log('Плановое обновление завершено. Сервис снова готов к работе.'); | |
}, { scheduled: true, timezone: "Europe/Moscow" }); | |
} catch (e) { | |
console.error("❌ Критическая ошибка при запуске сервера:", e); | |
process.exit(1); | |
} | |
})(); | |