Skip to content

Commit

Permalink
Merge branch 'dev' into #527-account-delete
Browse files Browse the repository at this point in the history
  • Loading branch information
kmc7468 committed Feb 5, 2025
2 parents 4308335 + 7dd683f commit b3d5071
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
54 changes: 54 additions & 0 deletions src/schedules/autoSettlement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { Express } from "express";
import { emitChatEvent } from "@/modules/socket";
import { userModel, roomModel } from "@/modules/stores/mongo";
import logger from "@/modules/logger";

const MS_PER_MINUTE = 60000;

// 탑승자가 1명인 상태로 탑승 시간이 지난 방에 대해서 정산 완료 처리
const autoSettlement = (app: Express) => async () => {
try {
const io = app.get("io");
const expiredDate = new Date(Date.now() - 60 * MS_PER_MINUTE).toISOString();
const arrivalDate = new Date(Date.now()).toISOString();
const candidateRooms = await roomModel.find({
$and: [
{ time: { $gte: expiredDate } },
{ time: { $lte: arrivalDate } },
{ "part.0": { $exists: true }, "part.1": { $exists: false } },
{ "part.0.settlementStatus": { $nin: ["paid", "sent"] } }, // "sent"의 경우 로직상 불가능 하지만, 문서화 측면에서 의도적으로 남겨두었음.
],
});

await Promise.all(
candidateRooms.map(async ({ _id: roomId, part }) => {
const user = await userModel.findById(part![0].user._id);
// 정산 채팅을 보냅니다.
await emitChatEvent(io, {
roomId: roomId.toString(),
type: "settlement",
content: user!.id,
authorId: user!._id.toString(),
time: null,
});

// 1명의 참여자만 존재하는 room에 대하여 정산 완료 처리.
await roomModel.findByIdAndUpdate(roomId, {
["part.0.settlementStatus"]: "paid",
settlementTotal: 1,
});

// Atomic update로 각 Room을 한번에 제거 및 추가함.
// 아토믹하게 처리하지 않을 경우 각 Promise가 동일한 user의 여러 ongoingRoom 또는 doneRoom을 동시에 수정하여 경합조건이 발생할 수 있음에 유의.
await userModel.findByIdAndUpdate(user!._id, {
$pull: { ongoingRoom: roomId },
$push: { doneRoom: roomId },
});
})
);
} catch (err) {
logger.error(err);
}
};

export default autoSettlement;
5 changes: 3 additions & 2 deletions src/schedules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import notifyAfterArrival from "./notifyAfterArrival";
import updateMajorTaxiFare from "./updateMajorTaxiFare";
import updateMinorTaxiFare from "./updateMinorTaxiFare";
import deleteUserInfo from "./deleteUserInfo";
import autoSettlement from "./autoSettlement";

const registerSchedules = (app: Express) => {
cron.schedule("*/5 * * * *", notifyBeforeDepart(app));
cron.schedule("*/10 * * * *", notifyAfterArrival(app));
cron.schedule("0 0 1 * *", deleteUserInfo);
cron.schedule("1,11,21,31,41,51 * * * *", autoSettlement(app));

if (naverMap.apiId && naverMap.apiKey) {
cron.schedule("0,30 * * * * ", updateMajorTaxiFare(app));
cron.schedule("0 18 * * *", updateMinorTaxiFare(app));
}

cron.schedule("0 0 1 * *", deleteUserInfo);
};

export default registerSchedules;
1 change: 1 addition & 0 deletions src/services/rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ const searchHandler = async (req, res) => {

const searchByUserHandler = async (req, res) => {
try {
// lean()이 적용된 user를 response에 반환해줘야 하기 때문에 user를 한 번 더 지정한다.
const user = await userModel
.findOne({ _id: req.userOid, withdraw: false })
.populate({
Expand Down

0 comments on commit b3d5071

Please sign in to comment.