changemaker.lite/api/dist/media-server.js

117 lines
5.4 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fastify_1 = __importDefault(require("fastify"));
const cors_1 = __importDefault(require("@fastify/cors"));
const multipart_1 = __importDefault(require("@fastify/multipart"));
const env_1 = require("./config/env");
const logger_1 = require("./utils/logger");
const videos_routes_1 = require("./modules/media/routes/videos.routes");
const video_streaming_routes_1 = require("./modules/media/routes/video-streaming.routes");
const reactions_routes_1 = require("./modules/media/routes/reactions.routes");
const public_media_routes_1 = require("./modules/media/routes/public-media.routes");
const comments_routes_1 = require("./modules/media/routes/comments.routes");
const upload_routes_1 = require("./modules/media/routes/upload.routes");
const video_actions_routes_1 = require("./modules/media/routes/video-actions.routes");
const video_schedule_routes_1 = require("./modules/media/routes/video-schedule.routes");
const video_tracking_routes_1 = require("./modules/media/routes/video-tracking.routes");
const video_schedule_queue_service_1 = require("./services/video-schedule-queue.service");
// Add BigInt serialization support for Prisma BigInt fields
// This converts BigInt values to strings when JSON.stringify() is called
BigInt.prototype.toJSON = function () {
return this.toString();
};
const fastify = (0, fastify_1.default)({
logger: {
level: env_1.env.NODE_ENV === 'production' ? 'info' : 'debug',
},
maxParamLength: 500,
trustProxy: true,
});
// Graceful shutdown handler
process.on('SIGTERM', async () => {
logger_1.logger.info('SIGTERM received, shutting down gracefully...');
await video_schedule_queue_service_1.videoScheduleQueueService.close();
fastify.close(() => {
logger_1.logger.info('Media API server closed');
process.exit(0);
});
});
// Global error handlers
process.on('unhandledRejection', (reason, promise) => {
logger_1.logger.error('Unhandled Promise Rejection in Media API', { reason: JSON.stringify(reason), promise: JSON.stringify(promise) });
});
process.on('uncaughtException', (error) => {
logger_1.logger.error('Uncaught Exception in Media API', { error: error instanceof Error ? error.message : JSON.stringify(error) });
fastify.close(() => {
process.exit(1);
});
});
// Start server
const start = async () => {
try {
// CORS configuration
const allowedOrigins = env_1.env.CORS_ORIGINS.split(',').map(o => o.trim());
await fastify.register(cors_1.default, {
origin: (origin, cb) => {
// Allow requests with no origin (mobile apps, curl, etc.)
if (!origin) {
cb(null, true);
return;
}
// Check if origin is in allowed list
if (allowedOrigins.includes(origin)) {
cb(null, true);
}
else {
cb(new Error('CORS not allowed'), false);
}
},
credentials: true,
});
// Multipart support for file uploads (10GB limit)
await fastify.register(multipart_1.default, {
limits: {
fileSize: env_1.env.MAX_UPLOAD_SIZE_GB * 1024 * 1024 * 1024,
},
});
// Health check
fastify.get('/health', async () => {
return {
status: 'ok',
timestamp: new Date().toISOString(),
service: 'media-api'
};
});
// Register routes
await fastify.register(videos_routes_1.videosRoutes, { prefix: '/api/videos' });
await fastify.register(video_streaming_routes_1.videoStreamingRoutes, { prefix: '/api/videos' });
await fastify.register(upload_routes_1.uploadRoutes, { prefix: '/api/videos' });
await fastify.register(video_actions_routes_1.videoActionsRoutes, { prefix: '/api/videos' });
await fastify.register(video_schedule_routes_1.videoScheduleRoutes, { prefix: '/api/videos' });
await fastify.register(video_tracking_routes_1.videoTrackingRoutes, { prefix: '/api/track' });
await fastify.register(reactions_routes_1.reactionsRoutes, { prefix: '/api/reactions' });
await fastify.register(public_media_routes_1.publicMediaRoutes, { prefix: '/api/media' });
await fastify.register(comments_routes_1.commentsRoutes, { prefix: '/api/media' });
// TODO: Add more routes
// await fastify.register(jobsRoutes, { prefix: '/api/jobs' });
const port = env_1.env.MEDIA_API_PORT;
const host = '0.0.0.0';
await fastify.listen({ port, host });
logger_1.logger.info(`Media API listening on http://${host}:${port}`);
// Start video schedule queue worker
video_schedule_queue_service_1.videoScheduleQueueService.startWorker();
logger_1.logger.info('Video schedule queue worker initialized');
if (env_1.env.ENABLE_MEDIA_FEATURES !== 'true') {
logger_1.logger.warn('Media features are disabled (ENABLE_MEDIA_FEATURES=false)');
}
}
catch (err) {
logger_1.logger.error('Media API startup error', { error: err instanceof Error ? err.message : JSON.stringify(err) });
process.exit(1);
}
};
start();
//# sourceMappingURL=media-server.js.map