From 1e1a83f381650be829cb5dac3b67c52a507a28a0 Mon Sep 17 00:00:00 2001 From: Dongwon Choi Date: Mon, 12 Feb 2024 17:12:08 +0000 Subject: [PATCH 1/9] Fix: change commitPayment and commitSettlement --- src/routes/docs/rooms.js | 20 ++++++++++---------- src/routes/rooms.js | 11 ++++++----- src/services/rooms.js | 18 +++++++++--------- test/services/rooms.js | 14 +++++++------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/routes/docs/rooms.js b/src/routes/docs/rooms.js index 3292b127..53ebbd5f 100644 --- a/src/routes/docs/rooms.js +++ b/src/routes/docs/rooms.js @@ -678,11 +678,11 @@ roomsDocs[`${apiPrefix}/searchByUser`] = { }, }; -roomsDocs[`${apiPrefix}/commitPayment`] = { +roomsDocs[`${apiPrefix}/commitSettlement`] = { post: { tags: [tag], - summary: "방 결제 처리", - description: `해당 방에 요청을 보낸 유저를 결제자로 처리합니다.
+ summary: "방 정산 요청 처리", + description: `해당 방에 요청을 보낸 유저를 결제자로 처리하여, 다른 유저들에게 정산을 요청합니다.
이미 출발한 방에 대해서만 요청을 처리합니다.
방의 \`part\` 배열에서 요청을 보낸 유저의 \`isSettlement\` 속성은 \`paid\`로 설정됩니다.
나머지 유저들의 \`isSettlement\` 속성을 \`send-required\`로 설정합니다.`, @@ -726,7 +726,7 @@ roomsDocs[`${apiPrefix}/commitPayment`] = { }, }, example: { - error: "Rooms/:id/commitPayment : cannot find settlement info", + error: "Rooms/:id/commitSettlement : cannot find settlement info", }, }, }, @@ -744,7 +744,7 @@ roomsDocs[`${apiPrefix}/commitPayment`] = { }, }, example: { - error: "Rooms/:id/commitPayment : internal server error", + error: "Rooms/:id/commitSettlement : internal server error", }, }, }, @@ -753,11 +753,11 @@ roomsDocs[`${apiPrefix}/commitPayment`] = { }, }; -roomsDocs[`${apiPrefix}/commitSettlement`] = { +roomsDocs[`${apiPrefix}/commitPayment`] = { post: { tags: [tag], - summary: "방 정산 완료 처리", - description: `해당 방에 요청을 보낸 유저를 정산 완료로 처리합니다.
+ summary: "방 송금 처리", + description: `해당 방에 요청을 보낸 유저를 송금을 완료한 정산 완료로 처리합니다.
방의 \`part\` 배열에서 요청을 보낸 유저의 \`isSettlement\` 속성은 \`send-required\`에서 \`sent\`로 변경합니다.
방의 참여한 유저들이 모두 정산완료를 하면 방의 \`isOver\` 속성이 \`true\`로 변경되며, 과거 방으로 취급됩니다.`, requestBody: { @@ -800,7 +800,7 @@ roomsDocs[`${apiPrefix}/commitSettlement`] = { }, }, example: { - error: "Rooms/:id/settlement : cannot find settlement info", + error: "Rooms/:id/commitPayment : cannot find settlement info", }, }, }, @@ -818,7 +818,7 @@ roomsDocs[`${apiPrefix}/commitSettlement`] = { }, }, example: { - error: "Rooms/:id/settlement : internal server error", + error: "Rooms/:id/commitPayment : internal server error", }, }, }, diff --git a/src/routes/rooms.js b/src/routes/rooms.js index be1c3f59..bfba96f7 100644 --- a/src/routes/rooms.js +++ b/src/routes/rooms.js @@ -78,19 +78,20 @@ router.post( // 로그인된 사용자의 모든 방들을 반환한다. router.get("/searchByUser", roomHandlers.searchByUserHandler); +// 해당 방에 요청을 보낸 유저의 정산을 처리한다. router.post( - "/commitPayment", + "/commitSettlement", body("roomId").isMongoId(), validator, - roomHandlers.commitPaymentHandler + roomHandlers.commitSettlementHandler ); -// 해당 룸의 요청을 보낸 유저의 정산을 완료로 처리한다. +// 해당 방에 요청을 보낸 유저의 송금을 처리한다. router.post( - "/commitSettlement", + "/commitPayment", body("roomId").isMongoId(), validator, - roomHandlers.settlementHandler + roomHandlers.commitPaymentHandler ); // json으로 수정할 값들을 받아 방의 정보를 수정합니다. diff --git a/src/services/rooms.js b/src/services/rooms.js index a2562c67..2228e29d 100644 --- a/src/services/rooms.js +++ b/src/services/rooms.js @@ -428,7 +428,7 @@ const searchByUserHandler = async (req, res) => { } }; -const commitPaymentHandler = async (req, res) => { +const commitSettlementHandler = async (req, res) => { try { const user = await userModel.findOne({ id: req.userId }); const { roomId } = req.body; @@ -462,7 +462,7 @@ const commitPaymentHandler = async (req, res) => { if (!roomObject) { return res.status(404).json({ - error: "Rooms/:id/commitPayment : cannot find settlement info", + error: "Rooms/:id/commitSettlement : cannot find settlement info", }); } @@ -475,7 +475,7 @@ const commitPaymentHandler = async (req, res) => { if (userOngoingRoomIndex === -1) { await user.save(); return res.status(500).json({ - error: "Rooms/:id/settlement : internal server error", + error: "Rooms/:id/commitSettlement : internal server error", }); } user.ongoingRoom.splice(userOngoingRoomIndex, 1); @@ -507,12 +507,12 @@ const commitPaymentHandler = async (req, res) => { } catch (err) { logger.error(err); res.status(500).json({ - error: "Rooms/:id/commitPayment : internal server error", + error: "Rooms/:id/commitSettlement : internal server error", }); } }; -const settlementHandler = async (req, res) => { +const commitPaymentHandler = async (req, res) => { try { const { roomId } = req.body; const user = await userModel.findOne({ id: req.userId }); @@ -540,7 +540,7 @@ const settlementHandler = async (req, res) => { if (!roomObject) { return res.status(404).json({ - error: "Rooms/:id/settlement : cannot find settlement info", + error: "Rooms/:id/commitPayment : cannot find settlement info", }); } @@ -553,7 +553,7 @@ const settlementHandler = async (req, res) => { if (userOngoingRoomIndex === -1) { await user.save(); return res.status(500).json({ - error: "Rooms/:id/settlement : internal server error", + error: "Rooms/:id/commitPayment : internal server error", }); } user.ongoingRoom.splice(userOngoingRoomIndex, 1); @@ -585,7 +585,7 @@ const settlementHandler = async (req, res) => { } catch (err) { logger.error(err); res.status(500).json({ - error: "Rooms/:id/settlement : internal server error", + error: "Rooms/:id/commitPayment : internal server error", }); } }; @@ -679,6 +679,6 @@ module.exports = { searchHandler, searchByUserHandler, commitPaymentHandler, - settlementHandler, + commitSettlementHandler, // editHandler, }; diff --git a/test/services/rooms.js b/test/services/rooms.js index e17ae6af..62d05609 100644 --- a/test/services/rooms.js +++ b/test/services/rooms.js @@ -141,8 +141,8 @@ describe("[rooms] 6.searchByUserHandler", () => { }); // 7. 1분이 지난 후, 정산 정보를 불러옴. 예상과 같은 정보를 불러오는지 확인 -describe("[rooms] 7.commitPaymentHandler", () => { - it("should return information of room and commit payment", async () => { +describe("[rooms] 7.commitsettlementHandler", () => { + it("should return information of room and commit settlement", async () => { const testUser1 = await userModel.findOne({ id: "test1" }); const testRoom = await roomModel.findOne({ name: "test-room" }); let req = httpMocks.createRequest({ @@ -152,7 +152,7 @@ describe("[rooms] 7.commitPaymentHandler", () => { app, }); let res = httpMocks.createResponse(); - await roomsHandlers.commitPaymentHandler(req, res); + await roomsHandlers.commitSettlementHandler(req, res); const resData = res._getData(); expect(resData).to.has.property("name", "test-room"); @@ -161,9 +161,9 @@ describe("[rooms] 7.commitPaymentHandler", () => { }); }); -// 8. 도착 정보를 불러옴. 예상과 같은 정보를 불러오는지 확인 -describe("[rooms] 8.settlementHandler", () => { - it("should return information of room and set settlement", async () => { +// 8. 송금 후 정산 정보를 불러옴. 예상과 같은 정보를 불러오는지 확인 +describe("[rooms] 8.commitPaymentHandler", () => { + it("should return information of room and commit payment", async () => { const testUser2 = await userModel.findOne({ id: "test2" }); const testRoom = await roomModel.findOne({ name: "test-room" }); let req = httpMocks.createRequest({ @@ -172,7 +172,7 @@ describe("[rooms] 8.settlementHandler", () => { app, }); let res = httpMocks.createResponse(); - await roomsHandlers.settlementHandler(req, res); + await roomsHandlers.commitPaymentHandler(req, res); const resData = res._getData(); expect(resData).to.has.property("name", "test-room"); From 1bd982f2f422b2254d2caad98d431876874200f8 Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Tue, 19 Mar 2024 21:04:48 +0900 Subject: [PATCH 2/9] Refactor: validate by zod --- src/routes/docs/schemas/roomsSchema.js | 8 ++++++++ src/routes/rooms.js | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/routes/docs/schemas/roomsSchema.js b/src/routes/docs/schemas/roomsSchema.js index 39dcd8bf..a0af753e 100644 --- a/src/routes/docs/schemas/roomsSchema.js +++ b/src/routes/docs/schemas/roomsSchema.js @@ -31,6 +31,14 @@ roomsZod["room"] = z }) .partial({ settlementTotal: true, isOver: true }); +roomsZod["commitSettlement"] = z.object({ + roomId: z.string().regex(objectId), +}); + +roomsZod["commitPayment"] = z.object({ + roomId: z.string().regex(objectId), +}); + const roomsSchema = zodToSchemaObject(roomsZod); module.exports = { roomsSchema, roomsZod }; diff --git a/src/routes/rooms.js b/src/routes/rooms.js index 566f862f..6345fa6f 100644 --- a/src/routes/rooms.js +++ b/src/routes/rooms.js @@ -1,5 +1,7 @@ const express = require("express"); const { query, body } = require("express-validator"); +const { validateBody } = require("../middlewares/zod"); +const { roomsZod } = require("./docs/schemas/roomsSchema"); const router = express.Router(); const roomHandlers = require("../services/rooms"); @@ -94,16 +96,14 @@ router.get("/searchByUser", roomHandlers.searchByUserHandler); // 해당 방에 요청을 보낸 유저의 정산을 처리한다. router.post( "/commitSettlement", - body("roomId").isMongoId(), - validator, + validateBody(roomsZod.commitSettlement), roomHandlers.commitSettlementHandler ); // 해당 방에 요청을 보낸 유저의 송금을 처리한다. router.post( "/commitPayment", - body("roomId").isMongoId(), - validator, + validateBody(roomsZod.commitPayment), roomHandlers.commitPaymentHandler ); From 295366c46ac8249149c4062061fe253d479d4f95 Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Tue, 26 Mar 2024 23:48:47 +0900 Subject: [PATCH 3/9] Refactor: change settlement and payment --- src/lottery/modules/contracts.js | 6 +++--- src/modules/socket.js | 4 ++-- src/routes/docs/chats.js | 2 +- src/services/rooms.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lottery/modules/contracts.js b/src/lottery/modules/contracts.js index 87a24a84..56188041 100644 --- a/src/lottery/modules/contracts.js +++ b/src/lottery/modules/contracts.js @@ -127,7 +127,7 @@ const completeFirstLoginQuest = async (userId, timestamp) => { * @param {Date} roomObject.time - 출발 시각입니다. * @returns {Promise} * @description 정산 요청 또는 송금이 이루어질 때마다 호출해 주세요. - * @usage rooms - commitPaymentHandler, rooms - settlementHandler + * @usage rooms - commitPaymentHandler, rooms - commitSettlementHandler */ const completePayingAndSendingQuest = async (userId, timestamp, roomObject) => { logger.info( @@ -167,7 +167,7 @@ const completeFirstRoomCreationQuest = async (userId, timestamp) => { * @param {Date} roomObject.time - 출발 시각입니다. * @returns {Promise} * @description 정산 요청이 이루어질 때마다 호출해 주세요. - * @usage rooms - commitPaymentHandler + * @usage rooms - commitSettlementHandler */ const completePayingQuest = async (userId, timestamp, roomObject) => { logger.info( @@ -195,7 +195,7 @@ const completePayingQuest = async (userId, timestamp, roomObject) => { * @param {Date} roomObject.time - 출발 시각입니다. * @returns {Promise} * @description 송금이 이루어질 때마다 호출해 주세요. - * @usage rooms - settlementHandler + * @usage rooms - paymentHandler */ const completeSendingQuest = async (userId, timestamp, roomObject) => { logger.info( diff --git a/src/modules/socket.js b/src/modules/socket.js index 07806ef4..bfdf95af 100644 --- a/src/modules/socket.js +++ b/src/modules/socket.js @@ -83,11 +83,11 @@ const getMessageBody = (type, nickname = "", content = "") => { const suffix = "님이 퇴장하였습니다"; return `${ellipsisedNickname} ${suffix}`; } - case "payment": { + case "settlement": { const suffix = "님이 정산을 시작하였습니다"; return `${ellipsisedNickname} ${suffix}`; } - case "settlement": { + case "payment": { const suffix = "님이 송금을 완료하였습니다"; return `${ellipsisedNickname} ${suffix}`; } diff --git a/src/routes/docs/chats.js b/src/routes/docs/chats.js index 0aaa1c6d..f9107201 100644 --- a/src/routes/docs/chats.js +++ b/src/routes/docs/chats.js @@ -211,7 +211,7 @@ chatsDocs[`${apiPrefix}/send`] = { Chat { roomId: ObjectId, //방의 objectId - type: String, // 메시지 종류 ("text": 일반 메시지, "s3img": S3에 업로드된 이미지, "in": 입장 메시지, "out": 퇴장 메시지, "payment": 결제 메시지, "settlement": 정산 완료 메시지, "account": 계좌 전송 메시지) + type: String, // 메시지 종류 ("text": 일반 메시지, "s3img": S3에 업로드된 이미지, "in": 입장 메시지, "out": 퇴장 메시지, "settlement": 정산 메시지, "payment": 송금 메시지, "account": 계좌 전송 메시지) authorId: ObejctId, //작성자의 objectId content: String, // 메시지 내용 (메시지 종류에 따라 포맷이 상이함) time: String(ISO 8601), // ex) 2024-01-08T01:52:00.000Z diff --git a/src/services/rooms.js b/src/services/rooms.js index 23f9cafb..7d9f5f8d 100644 --- a/src/services/rooms.js +++ b/src/services/rooms.js @@ -616,7 +616,7 @@ const commitSettlementHandler = async (req, res) => { // 결제 채팅을 보냅니다. await emitChatEvent(req.app.get("io"), { roomId, - type: "payment", + type: "settlement", content: user.id, authorId: user._id, }); @@ -694,7 +694,7 @@ const commitPaymentHandler = async (req, res) => { // 정산 채팅을 보냅니다. await emitChatEvent(req.app.get("io"), { roomId, - type: "settlement", + type: "payment", content: user.id, authorId: user._id, }); From 880aa3bf843f0d61215765025e9c49e367ca847c Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Wed, 27 Mar 2024 01:57:40 +0900 Subject: [PATCH 4/9] Add chatPaymentSettlementUpdater.js --- scripts/chatPaymentSettlementUpdater.js | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 scripts/chatPaymentSettlementUpdater.js diff --git a/scripts/chatPaymentSettlementUpdater.js b/scripts/chatPaymentSettlementUpdater.js new file mode 100644 index 00000000..22f2fba3 --- /dev/null +++ b/scripts/chatPaymentSettlementUpdater.js @@ -0,0 +1,37 @@ +// Issue #449-1을 해결하기 위한 DB 마이그레이션 스크립트입니다. +// chat type 중 settlement와 payment를 서로 교체합니다. +// https://github.com/sparcs-kaist/taxi-back/issues/449 + +const { MongoClient } = require("mongodb"); +const { mongo: mongoUrl } = require("../loadenv"); + +const time = Date.now(); + +const client = new MongoClient(mongoUrl); +const db = client.db("taxi"); +const chats = db.collection("chats"); + +async function run() { + try { + for await (const doc of chats.find()) { + // 이미 변환이 완료된 경우에는 Pass합니다. + if (doc.type === "settlement" || doc.type === "payment") { + await chats.findOneAndUpdate( + { _id: doc._id }, + { + $set: { + type: doc.type === "settlement" ? "payment" : "settlement", + }, + } + ); + } + } + } catch (err) { + console.log(err); + } finally { + await client.close(); + } +} +run().then(() => { + console.log("Done!"); +}); From 2c06b1f5ea3e9ea9a4bb162ea22781a6da99c8bc Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Wed, 27 Mar 2024 02:07:01 +0900 Subject: [PATCH 5/9] Fix: paymentHandler to commitPaymentHandler --- src/lottery/modules/contracts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lottery/modules/contracts.js b/src/lottery/modules/contracts.js index 56188041..93d43e23 100644 --- a/src/lottery/modules/contracts.js +++ b/src/lottery/modules/contracts.js @@ -195,7 +195,7 @@ const completePayingQuest = async (userId, timestamp, roomObject) => { * @param {Date} roomObject.time - 출발 시각입니다. * @returns {Promise} * @description 송금이 이루어질 때마다 호출해 주세요. - * @usage rooms - paymentHandler + * @usage rooms - commitPaymentHandler */ const completeSendingQuest = async (userId, timestamp, roomObject) => { logger.info( From b31b7b2d2924e30bafb68f64c1e10b7078155a1d Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Wed, 27 Mar 2024 02:10:06 +0900 Subject: [PATCH 6/9] Fix: rooms.js comment --- src/services/rooms.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/rooms.js b/src/services/rooms.js index 7d9f5f8d..a1a61913 100644 --- a/src/services/rooms.js +++ b/src/services/rooms.js @@ -613,7 +613,7 @@ const commitSettlementHandler = async (req, res) => { await user.save(); - // 결제 채팅을 보냅니다. + // 정산 채팅을 보냅니다. await emitChatEvent(req.app.get("io"), { roomId, type: "settlement", @@ -691,7 +691,7 @@ const commitPaymentHandler = async (req, res) => { await user.save(); - // 정산 채팅을 보냅니다. + // 송금 채팅을 보냅니다. await emitChatEvent(req.app.get("io"), { roomId, type: "payment", From d1a04f5364a9e90e5f620cf3f939242857359157 Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Thu, 28 Mar 2024 17:55:36 +0900 Subject: [PATCH 7/9] Remove: comment in chatPaymentSettlementUpdater.js --- scripts/chatPaymentSettlementUpdater.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/chatPaymentSettlementUpdater.js b/scripts/chatPaymentSettlementUpdater.js index 22f2fba3..0fa45b89 100644 --- a/scripts/chatPaymentSettlementUpdater.js +++ b/scripts/chatPaymentSettlementUpdater.js @@ -14,7 +14,6 @@ const chats = db.collection("chats"); async function run() { try { for await (const doc of chats.find()) { - // 이미 변환이 완료된 경우에는 Pass합니다. if (doc.type === "settlement" || doc.type === "payment") { await chats.findOneAndUpdate( { _id: doc._id }, From d4336874b52acf2ce7ab655264e3fb93377563da Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Thu, 28 Mar 2024 17:56:14 +0900 Subject: [PATCH 8/9] Fix: test/rooms.js --- test/services/rooms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/services/rooms.js b/test/services/rooms.js index 62d05609..4e948ad1 100644 --- a/test/services/rooms.js +++ b/test/services/rooms.js @@ -141,7 +141,7 @@ describe("[rooms] 6.searchByUserHandler", () => { }); // 7. 1분이 지난 후, 정산 정보를 불러옴. 예상과 같은 정보를 불러오는지 확인 -describe("[rooms] 7.commitsettlementHandler", () => { +describe("[rooms] 7.commitSettlementHandler", () => { it("should return information of room and commit settlement", async () => { const testUser1 = await userModel.findOne({ id: "test1" }); const testRoom = await roomModel.findOne({ name: "test-room" }); From 0a91f62df548d0c077be12d9b7dbed5f34b7166e Mon Sep 17 00:00:00 2001 From: chlehdwon Date: Tue, 28 May 2024 23:04:46 +0900 Subject: [PATCH 9/9] Fix: minor changes --- scripts/chatPaymentSettlementUpdater.js | 2 -- src/lottery/modules/contracts.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/chatPaymentSettlementUpdater.js b/scripts/chatPaymentSettlementUpdater.js index 0fa45b89..76e43682 100644 --- a/scripts/chatPaymentSettlementUpdater.js +++ b/scripts/chatPaymentSettlementUpdater.js @@ -5,8 +5,6 @@ const { MongoClient } = require("mongodb"); const { mongo: mongoUrl } = require("../loadenv"); -const time = Date.now(); - const client = new MongoClient(mongoUrl); const db = client.db("taxi"); const chats = db.collection("chats"); diff --git a/src/lottery/modules/contracts.js b/src/lottery/modules/contracts.js index 93d43e23..72a62deb 100644 --- a/src/lottery/modules/contracts.js +++ b/src/lottery/modules/contracts.js @@ -127,7 +127,7 @@ const completeFirstLoginQuest = async (userId, timestamp) => { * @param {Date} roomObject.time - 출발 시각입니다. * @returns {Promise} * @description 정산 요청 또는 송금이 이루어질 때마다 호출해 주세요. - * @usage rooms - commitPaymentHandler, rooms - commitSettlementHandler + * @usage rooms - commitSettlementHandler, rooms - commitPaymentHandler */ const completePayingAndSendingQuest = async (userId, timestamp, roomObject) => { logger.info(