auto commit
This commit is contained in:
parent
b0732f3f46
commit
675197902e
145
fems-api/src/middleware/checkContractStatus.middleware.js
Normal file
145
fems-api/src/middleware/checkContractStatus.middleware.js
Normal file
@ -0,0 +1,145 @@
|
||||
// src/middleware/checkContractStatus.middleware.js
|
||||
const { Contract, Company } = require("../models");
|
||||
const { Op } = require("sequelize");
|
||||
const logger = require("../config/logger");
|
||||
|
||||
class ContractStatusChecker {
|
||||
async checkSubscriptionStatus(companyId) {
|
||||
try {
|
||||
// 회사 정보 조회
|
||||
const company = await Company.findOne({
|
||||
where: {
|
||||
id: companyId,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!company) {
|
||||
return {
|
||||
isValid: false,
|
||||
reason: "COMPANY_NOT_FOUND",
|
||||
message: "회사 정보를 찾을 수 없습니다.",
|
||||
};
|
||||
}
|
||||
|
||||
// 활성 계약 조회
|
||||
const activeContract = await Contract.findOne({
|
||||
where: {
|
||||
companyId,
|
||||
status: "active",
|
||||
startDate: { [Op.lte]: new Date() },
|
||||
endDate: { [Op.gt]: new Date() },
|
||||
},
|
||||
order: [["endDate", "DESC"]],
|
||||
});
|
||||
|
||||
if (!activeContract) {
|
||||
return {
|
||||
isValid: false,
|
||||
reason: "NO_ACTIVE_CONTRACT",
|
||||
companyName: company.name,
|
||||
message: "유효한 계약이 없습니다.",
|
||||
};
|
||||
}
|
||||
|
||||
// 계약 만료 임박 확인 (30일 이내)
|
||||
const daysUntilExpiry = Math.ceil(
|
||||
(new Date(activeContract.endDate) - new Date()) / (1000 * 60 * 60 * 24)
|
||||
);
|
||||
|
||||
return {
|
||||
isValid: true,
|
||||
companyName: company.name,
|
||||
contractInfo: {
|
||||
contractNumber: activeContract.contractNumber,
|
||||
startDate: activeContract.startDate,
|
||||
endDate: activeContract.endDate,
|
||||
remainingDays: daysUntilExpiry,
|
||||
status: activeContract.status,
|
||||
warning:
|
||||
daysUntilExpiry <= 30
|
||||
? {
|
||||
type: "EXPIRING_SOON",
|
||||
message: `계약이 ${daysUntilExpiry}일 후 만료됩니다.`,
|
||||
}
|
||||
: null,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error("Contract status check failed:", {
|
||||
companyId,
|
||||
error: error.message,
|
||||
});
|
||||
|
||||
return {
|
||||
isValid: false,
|
||||
reason: "CHECK_FAILED",
|
||||
message: "계약 상태 확인 중 오류가 발생했습니다.",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 미들웨어로 사용할 경우
|
||||
async checkSubscription(req, res, next) {
|
||||
try {
|
||||
const status = await this.checkSubscriptionStatus(req.params.companyId);
|
||||
|
||||
if (!status.isValid) {
|
||||
return res.status(403).json({
|
||||
error: "Invalid subscription",
|
||||
...status,
|
||||
});
|
||||
}
|
||||
|
||||
// 상태 정보를 요청 객체에 저장
|
||||
req.subscriptionStatus = status;
|
||||
next();
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 계약 만료 예정인 회사들 조회
|
||||
async getExpiringContracts(warningDays = 30) {
|
||||
try {
|
||||
const expiringDate = new Date();
|
||||
expiringDate.setDate(expiringDate.getDate() + warningDays);
|
||||
|
||||
const contracts = await Contract.findAll({
|
||||
where: {
|
||||
status: "active",
|
||||
endDate: {
|
||||
[Op.between]: [new Date(), expiringDate],
|
||||
},
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: Company,
|
||||
where: { isActive: true },
|
||||
attributes: ["id", "name", "email"],
|
||||
},
|
||||
],
|
||||
order: [["endDate", "ASC"]],
|
||||
});
|
||||
|
||||
return contracts.map((contract) => ({
|
||||
companyId: contract.Company.id,
|
||||
companyName: contract.Company.name,
|
||||
companyEmail: contract.Company.email,
|
||||
contractNumber: contract.contractNumber,
|
||||
endDate: contract.endDate,
|
||||
remainingDays: Math.ceil(
|
||||
(new Date(contract.endDate) - new Date()) / (1000 * 60 * 60 * 24)
|
||||
),
|
||||
}));
|
||||
} catch (error) {
|
||||
logger.error("Failed to get expiring contracts:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 싱글톤 인스턴스 생성
|
||||
const contractStatusChecker = new ContractStatusChecker();
|
||||
|
||||
module.exports = contractStatusChecker;
|
@ -7,7 +7,7 @@ const MQTTService = require("./services/mqtt.service");
|
||||
const SensorDataModel = require("./models/SensorData");
|
||||
const createDataController = require("./controllers/data.controller");
|
||||
const logger = require("./utils/logger");
|
||||
const config = require("./config");
|
||||
const config = require("./config/config");
|
||||
|
||||
async function bootstrap() {
|
||||
try {
|
||||
@ -47,7 +47,7 @@ async function bootstrap() {
|
||||
app.use("/api/v1/data", createDataController(pool, redis));
|
||||
|
||||
// 서버 시작
|
||||
const port = config.port || 3000;
|
||||
const port = config.port || 3004;
|
||||
app.listen(port, () => {
|
||||
logger.info(`Realtime backend server running on port ${port}`);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user