Update 3 files

- /api/index.js
- /src/index.js
- /vercel.json
This commit is contained in:
2025-01-03 20:14:34 +00:00
parent 1bd3ceca62
commit b3f1ded394
3 changed files with 52 additions and 161 deletions

3
api/index.js Normal file
View File

@@ -0,0 +1,3 @@
const app = require('../src/index');
module.exports = app;

View File

@@ -7,12 +7,11 @@ const TMDBClient = require('./config/tmdb');
const healthCheck = require('./utils/health'); const healthCheck = require('./utils/health');
const app = express(); const app = express();
const port = process.env.PORT || 3000;
// Определяем базовый URL для документации // Определяем базовый URL для документации
const BASE_URL = process.env.NODE_ENV === 'production' const BASE_URL = process.env.NODE_ENV === 'production'
? 'https://neomovies-api.vercel.app' ? 'https://neomovies-api.vercel.app'
: `http://localhost:${port}`; : 'http://localhost:3000';
// Swagger configuration // Swagger configuration
const swaggerOptions = { const swaggerOptions = {
@@ -30,8 +29,8 @@ const swaggerOptions = {
servers: [ servers: [
{ {
url: BASE_URL, url: BASE_URL,
description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server', description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server'
}, }
], ],
tags: [ tags: [
{ {
@@ -87,127 +86,18 @@ const swaggerOptions = {
description: 'Сообщение об ошибке' description: 'Сообщение об ошибке'
} }
} }
},
Health: {
type: 'object',
properties: {
status: {
type: 'string',
enum: ['healthy', 'unhealthy'],
description: 'Общий статус API'
},
version: {
type: 'string',
description: 'Версия API'
},
uptime: {
type: 'object',
properties: {
seconds: {
type: 'integer',
description: 'Время работы в секундах'
},
formatted: {
type: 'string',
description: 'Отформатированное время работы'
}
}
},
tmdb: {
type: 'object',
properties: {
status: {
type: 'string',
enum: ['ok', 'error'],
description: 'Статус подключения к TMDB'
},
responseTime: {
type: 'integer',
description: 'Время ответа TMDB в мс'
},
error: {
type: 'string',
description: 'Сообщение об ошибке, если есть'
}
}
},
memory: {
type: 'object',
properties: {
heapTotal: {
type: 'integer',
description: 'Общий размер кучи (MB)'
},
heapUsed: {
type: 'integer',
description: 'Использованный размер кучи (MB)'
},
rss: {
type: 'integer',
description: 'Resident Set Size (MB)'
},
memoryUsage: {
type: 'integer',
description: 'Процент использования памяти'
},
system: {
type: 'object',
properties: {
total: {
type: 'integer',
description: 'Общая память системы (MB)'
},
free: {
type: 'integer',
description: 'Свободная память системы (MB)'
},
usage: {
type: 'integer',
description: 'Процент использования системной памяти'
}
}
}
}
},
system: {
type: 'object',
properties: {
platform: {
type: 'string',
description: 'Операционная система'
},
arch: {
type: 'string',
description: 'Архитектура процессора'
},
nodeVersion: {
type: 'string',
description: 'Версия Node.js'
},
cpuUsage: {
type: 'number',
description: 'Загрузка CPU'
}
}
},
timestamp: {
type: 'string',
format: 'date-time',
description: 'Время проверки'
}
}
} }
} }
} }
}, },
apis: [path.join(__dirname, 'routes', '*.js'), path.join(__dirname, 'index.js')] apis: [path.join(__dirname, 'routes', '*.js'), __filename]
}; };
const swaggerDocs = swaggerJsdoc(swaggerOptions); const swaggerDocs = swaggerJsdoc(swaggerOptions);
// CORS configuration // CORS configuration
app.use(cors({ app.use(cors({
origin: true, // Разрешаем все origins в development origin: true,
credentials: true, credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['X-Requested-With', 'Content-Type', 'Authorization', 'Accept'] allowedHeaders: ['X-Requested-With', 'Content-Type', 'Authorization', 'Accept']
@@ -256,21 +146,52 @@ app.use('/movies', require('./routes/movies'));
* content: * content:
* application/json: * application/json:
* schema: * schema:
* $ref: '#/components/schemas/Health' * type: object
* properties:
* status:
* type: string
* enum: [ok, error]
* tmdb:
* type: object
* properties:
* status:
* type: string
* enum: [ok, error]
*/ */
app.get('/health', async (req, res) => { app.get('/health', async (req, res) => {
const health = await healthCheck.getFullHealth(req.tmdb); try {
res.json(health); const health = await healthCheck.getFullHealth(req.tmdb);
res.json(health);
} catch (error) {
res.status(500).json({
status: 'error',
error: error.message
});
}
}); });
// Error handling // Error handling
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
console.error(err.stack); console.error('Error:', err);
res.status(500).json({ error: 'Something went wrong!' }); res.status(500).json({
error: 'Internal Server Error',
message: process.env.NODE_ENV === 'development' ? err.message : undefined
});
}); });
// Start server // Handle 404
app.listen(port, () => { app.use((req, res) => {
console.log(`Server is running on port ${port}`); res.status(404).json({ error: 'Not Found' });
console.log(`Documentation available at https://neomovies-api.vercel.app/api-docs`); });
});
// Export the Express API
module.exports = app;
// Start server only in development
if (process.env.NODE_ENV !== 'production') {
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
console.log(`Documentation available at http://localhost:${port}/api-docs`);
});
}

View File

@@ -2,50 +2,17 @@
"version": 2, "version": 2,
"builds": [ "builds": [
{ {
"src": "src/index.js", "src": "api/index.js",
"use": "@vercel/node" "use": "@vercel/node"
} }
], ],
"routes": [ "routes": [
{
"src": "/api-docs/(.*)",
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
},
"dest": "/src/index.js"
},
{
"src": "/movies/(.*)",
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
},
"dest": "/src/index.js"
},
{
"src": "/health",
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
},
"dest": "/src/index.js"
},
{ {
"src": "/(.*)", "src": "/(.*)",
"headers": { "dest": "/api/index.js"
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
},
"dest": "/src/index.js"
} }
], ],
"env": { "env": {
"NODE_ENV": "production", "NODE_ENV": "production"
"TMDB_ACCESS_TOKEN": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJkOWRlZTY5ZjYzNzYzOGU2MjY5OGZhZGY0ZjhhYTNkYyIsInN1YiI6IjY1OTVkNmM5ODY5ZTc1NzJmOTY1MjZiZiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.Wd_tBYGkAoGPVHq3A5DwV1iLs_eGvH3RRz86ghJTmU8"
} }
} }