Spaces:
Sleeping
Sleeping
import express from 'express'; | |
import cors from 'cors'; | |
import cron from 'node-cron'; | |
import { | |
initializeDatabase, | |
refreshData, | |
getMovieById, | |
getRandomMovie, | |
getMovies | |
} from './database.js'; | |
const PORT = process.env.PORT || 7860; | |
const APP_VERSION = "1.4"; | |
const app = express(); | |
app.use(cors()); | |
app.use(express.json()); | |
let isReady = false; | |
app.use((req, res, next) => { | |
if (!isReady && req.path !== '/health') { // Добавим health-check эндпоинт, который работает всегда | |
return res.status(503).json({ message: 'Сервис временно недоступен, база данных инициализируется.', statusCode: 503 }); | |
} | |
next(); | |
}); | |
app.get('/health', (req, res) => { | |
res.status(200).json({ status: isReady ? 'UP' : 'DOWN', message: isReady ? 'Сервис готов' : 'Идет инициализация' }); | |
}); | |
app.get(`/v${APP_VERSION}/movie`, async (req, res) => { | |
try { | |
const { page, limit, sortField, sortType, ...filters } = req.query; | |
const options = { | |
pagination: { page: parseInt(page, 10) || 1, limit: parseInt(limit, 10) || 10 }, | |
sorting: { field: sortField, type: sortType }, | |
filters: filters | |
}; | |
const { docs, total } = await getMovies(options); | |
const pages = options.pagination.limit > 0 ? Math.ceil(total / options.pagination.limit) : 0; | |
res.json({ docs, total, limit: options.pagination.limit, page: options.pagination.page, pages }); | |
} catch (e) { | |
console.error("Ошибка в эндпоинте /movie:", e); | |
res.status(500).json({ message: 'Ошибка сервера при обработке запроса', error: e.message }); | |
} | |
}); | |
app.get(`/v${APP_VERSION}/movie/random`, async (req, res) => { | |
try { | |
const movie = await getRandomMovie(); | |
if (movie) res.json(movie); | |
else res.status(404).json({ message: 'Не удалось найти случайный фильм', statusCode: 404 }); | |
} catch (e) { | |
console.error("Ошибка в эндпоинте /movie/random:", e); | |
res.status(500).json({ message: 'Ошибка сервера', error: e.message }); | |
} | |
}); | |
app.get(`/v${APP_VERSION}/movie/:id`, async (req, res) => { | |
const id = parseInt(req.params.id, 10); | |
if (isNaN(id)) return res.status(400).json({ message: 'Некорректный ID', statusCode: 400 }); | |
try { | |
const movie = await getMovieById(id); | |
if (movie) res.json(movie); | |
else res.status(404).json({ message: 'Фильм не найден', statusCode: 404 }); | |
} catch (e) { | |
console.error(`Ошибка в эндпоинте /movie/${id}:`, e); | |
res.status(500).json({ message: 'Ошибка сервера', error: e.message }); | |
} | |
}); | |
(async () => { | |
try { | |
// Запускаем инициализацию, но не ждем ее завершения, чтобы сервер мог запуститься | |
initializeDatabase().then(() => { | |
isReady = true; | |
console.log("--- База данных готова к работе! ---"); | |
}).catch(err => { | |
console.error("Критическая ошибка инициализации базы данных:", err); | |
process.exit(1); | |
}); | |
app.listen(PORT, () => { | |
console.log(`Сервер основного API запущен на порту ${PORT}. Ожидание инициализации базы данных...`); | |
}); | |
cron.schedule('0 0 */3 * *', async () => { | |
console.log('Запуск планового обновления данных...'); | |
isReady = false; | |
await refreshData(); | |
isReady = true; | |
console.log('Плановое обновление завершено.'); | |
}, { scheduled: true, timezone: "Europe/Moscow" }); | |
} catch (e) { | |
console.error("Не удалось запустить сервер:", e); | |
process.exit(1); | |
} | |
})(); | |