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 SensorDataModel = require("./models/SensorData");
|
||||||
const createDataController = require("./controllers/data.controller");
|
const createDataController = require("./controllers/data.controller");
|
||||||
const logger = require("./utils/logger");
|
const logger = require("./utils/logger");
|
||||||
const config = require("./config");
|
const config = require("./config/config");
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
try {
|
try {
|
||||||
@ -47,7 +47,7 @@ async function bootstrap() {
|
|||||||
app.use("/api/v1/data", createDataController(pool, redis));
|
app.use("/api/v1/data", createDataController(pool, redis));
|
||||||
|
|
||||||
// 서버 시작
|
// 서버 시작
|
||||||
const port = config.port || 3000;
|
const port = config.port || 3004;
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
logger.info(`Realtime backend server running on port ${port}`);
|
logger.info(`Realtime backend server running on port ${port}`);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user