2025-08-21 09:41:46 +09:00
|
|
|
import "dotenv/config";
|
|
|
|
|
import express from "express";
|
|
|
|
|
import cors from "cors";
|
|
|
|
|
import helmet from "helmet";
|
|
|
|
|
import compression from "compression";
|
|
|
|
|
import rateLimit from "express-rate-limit";
|
|
|
|
|
import config from "./config/environment";
|
|
|
|
|
import { logger } from "./utils/logger";
|
|
|
|
|
import { errorHandler } from "./middleware/errorHandler";
|
|
|
|
|
|
|
|
|
|
// 라우터 임포트
|
|
|
|
|
import authRoutes from "./routes/authRoutes";
|
|
|
|
|
import adminRoutes from "./routes/adminRoutes";
|
2025-08-21 14:47:07 +09:00
|
|
|
import multilangRoutes from "./routes/multilangRoutes";
|
2025-08-25 14:08:08 +09:00
|
|
|
import tableManagementRoutes from "./routes/tableManagementRoutes";
|
2025-09-01 11:48:12 +09:00
|
|
|
import screenManagementRoutes from "./routes/screenManagementRoutes";
|
2025-09-02 11:30:19 +09:00
|
|
|
import commonCodeRoutes from "./routes/commonCodeRoutes";
|
2025-09-04 14:23:35 +09:00
|
|
|
import dynamicFormRoutes from "./routes/dynamicFormRoutes";
|
2025-08-21 09:41:46 +09:00
|
|
|
// import userRoutes from './routes/userRoutes';
|
|
|
|
|
// import menuRoutes from './routes/menuRoutes';
|
|
|
|
|
|
|
|
|
|
const app = express();
|
|
|
|
|
|
|
|
|
|
// 기본 미들웨어
|
|
|
|
|
app.use(helmet());
|
|
|
|
|
app.use(compression());
|
|
|
|
|
app.use(express.json({ limit: "10mb" }));
|
|
|
|
|
app.use(express.urlencoded({ extended: true, limit: "10mb" }));
|
|
|
|
|
|
2025-09-04 16:29:57 +09:00
|
|
|
// CORS 설정 - environment.ts에서 이미 올바른 형태로 처리됨
|
2025-08-21 09:41:46 +09:00
|
|
|
app.use(
|
|
|
|
|
cors({
|
2025-09-04 16:29:57 +09:00
|
|
|
origin: config.cors.origin, // 이미 배열 또는 boolean으로 처리됨
|
|
|
|
|
credentials: config.cors.credentials,
|
2025-08-21 09:41:46 +09:00
|
|
|
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
2025-09-04 15:20:26 +09:00
|
|
|
allowedHeaders: [
|
|
|
|
|
"Content-Type",
|
|
|
|
|
"Authorization",
|
|
|
|
|
"X-Requested-With",
|
|
|
|
|
"Accept",
|
|
|
|
|
"Origin",
|
|
|
|
|
"Access-Control-Request-Method",
|
|
|
|
|
"Access-Control-Request-Headers",
|
|
|
|
|
],
|
|
|
|
|
preflightContinue: false,
|
|
|
|
|
optionsSuccessStatus: 200,
|
2025-08-21 09:41:46 +09:00
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Rate Limiting (개발 환경에서는 완화)
|
|
|
|
|
const limiter = rateLimit({
|
|
|
|
|
windowMs: 1 * 60 * 1000, // 1분
|
|
|
|
|
max: config.nodeEnv === "development" ? 1000 : 100, // 개발환경에서는 1000, 운영환경에서는 100
|
|
|
|
|
message: {
|
|
|
|
|
error: "너무 많은 요청이 발생했습니다. 잠시 후 다시 시도해주세요.",
|
|
|
|
|
},
|
|
|
|
|
skip: (req) => {
|
|
|
|
|
// 헬스 체크는 Rate Limiting 제외
|
|
|
|
|
return req.path === "/health";
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
app.use("/api/", limiter);
|
|
|
|
|
|
|
|
|
|
// 헬스 체크 엔드포인트
|
|
|
|
|
app.get("/health", (req, res) => {
|
|
|
|
|
res.status(200).json({
|
|
|
|
|
status: "OK",
|
|
|
|
|
timestamp: new Date().toISOString(),
|
|
|
|
|
uptime: process.uptime(),
|
|
|
|
|
environment: config.nodeEnv,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// API 라우터
|
|
|
|
|
app.use("/api/auth", authRoutes);
|
|
|
|
|
app.use("/api/admin", adminRoutes);
|
2025-08-21 14:47:07 +09:00
|
|
|
app.use("/api/multilang", multilangRoutes);
|
2025-08-25 14:08:08 +09:00
|
|
|
app.use("/api/table-management", tableManagementRoutes);
|
2025-09-01 11:48:12 +09:00
|
|
|
app.use("/api/screen-management", screenManagementRoutes);
|
2025-09-02 11:30:19 +09:00
|
|
|
app.use("/api/common-codes", commonCodeRoutes);
|
2025-09-04 14:23:35 +09:00
|
|
|
app.use("/api/dynamic-form", dynamicFormRoutes);
|
2025-08-21 09:41:46 +09:00
|
|
|
// app.use('/api/users', userRoutes);
|
|
|
|
|
// app.use('/api/menus', menuRoutes);
|
|
|
|
|
|
|
|
|
|
// 404 핸들러
|
|
|
|
|
app.use("*", (req, res) => {
|
|
|
|
|
res.status(404).json({
|
|
|
|
|
success: false,
|
|
|
|
|
message: "요청한 리소스를 찾을 수 없습니다.",
|
|
|
|
|
path: req.originalUrl,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 에러 핸들러
|
|
|
|
|
app.use(errorHandler);
|
|
|
|
|
|
|
|
|
|
// 서버 시작
|
|
|
|
|
const PORT = config.port;
|
2025-09-04 15:20:26 +09:00
|
|
|
const HOST = config.host;
|
2025-08-21 09:41:46 +09:00
|
|
|
|
2025-09-04 15:20:26 +09:00
|
|
|
app.listen(PORT, HOST, () => {
|
|
|
|
|
logger.info(`🚀 Server is running on ${HOST}:${PORT}`);
|
2025-08-21 09:41:46 +09:00
|
|
|
logger.info(`📊 Environment: ${config.nodeEnv}`);
|
2025-09-04 15:20:26 +09:00
|
|
|
logger.info(`🔗 Health check: http://${HOST}:${PORT}/health`);
|
|
|
|
|
logger.info(`🌐 External access: http://39.117.244.52:${PORT}/health`);
|
2025-08-21 09:41:46 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default app;
|