Skip to content

Commit 8d58a79

Browse files
committed
Refactor: migrate populate directory to TS
1 parent 7795c73 commit 8d58a79

File tree

7 files changed

+129
-105
lines changed

7 files changed

+129
-105
lines changed

src/modules/populates/chats.js

-10
This file was deleted.

src/modules/populates/chats.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { type User, type Chat } from "@/types/mongo";
2+
3+
/** @constant {{path: string, select: string}[]}
4+
* 쿼리를 통해 얻은 Chat Document를 populate할 설정값을 정의합니다.
5+
*/
6+
export const chatPopulateOption = [
7+
{ path: "authorId", select: "_id nickname profileImageUrl" },
8+
];
9+
10+
export interface PopulatedChat extends Omit<Chat, "authorId"> {
11+
authorId?: Pick<User, "_id" | "nickname" | "profileImageUrl">;
12+
};

src/modules/populates/reports.js

-10
This file was deleted.

src/modules/populates/reports.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { type User, type Report } from "@/types/mongo";
2+
3+
export const reportPopulateOption = [
4+
{
5+
path: "reportedId",
6+
select: "_id id name nickname profileImageUrl",
7+
},
8+
];
9+
10+
export interface PopulatedReport extends Omit<Report, "reportedId"> {
11+
reportedId: Pick<User, "_id" | "id" | "name" | "nickname" | "profileImageUrl">;
12+
};

src/modules/populates/rooms.js

-73
This file was deleted.

src/modules/populates/rooms.ts

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { type User, type SettlementStatus, type Participant, type Room, type Location } from "@/types/mongo";
2+
3+
/**
4+
* 쿼리를 통해 얻은 Room Document를 populate할 설정값을 정의합니다.
5+
* @constant {{path: string, select: string, populate?: {path: string, select: string}}[]}
6+
*/
7+
export const roomPopulateOption = [
8+
{ path: "from", select: "_id koName enName" },
9+
{ path: "to", select: "_id koName enName" },
10+
{
11+
path: "part",
12+
select: "-_id user settlementStatus readAt",
13+
populate: { path: "user", select: "_id id name nickname profileImageUrl" },
14+
},
15+
];
16+
17+
interface PopulatedParticipant extends Pick<Participant, "settlementStatus" | "readAt"> {
18+
user: Pick<User, "_id" | "id" | "name" | "nickname" | "profileImageUrl">;
19+
}
20+
21+
export interface PopulatedRoom extends Omit<Room, "from" | "to" | "part"> {
22+
from: Pick<Location, "_id" | "koName" | "enName">;
23+
to: Pick<Location, "_id" | "koName" | "enName">;
24+
part?: PopulatedParticipant[];
25+
}
26+
27+
export interface FormattedRoom extends Omit<PopulatedRoom, "part" | "settlementTotal"> {
28+
part?: {
29+
_id: string;
30+
name: string;
31+
nickname: string;
32+
profileImageUrl: string;
33+
isSettlement?: SettlementStatus;
34+
readAt: Date;
35+
}[];
36+
settlementTotal?: number;
37+
isOver?: boolean;
38+
isDeparted: boolean;
39+
};
40+
41+
/**
42+
* Room Object가 주어졌을 때 room의 part array의 각 요소를 API 명세에서와 같이 {userId: String, ... , isSettlement: String}으로 가공합니다.
43+
* 또한, 방이 현재 출발했는지 유무인 isDeparted 속성을 추가합니다.
44+
* @param {PopulatedRoom} roomObject - 정산 정보를 가공할 room Object로, Mongoose Document가 아닌 순수 Javascript Object여야 합니다.
45+
* @param {Object} options - 추가 파라미터로, 기본값은 {}입니다.
46+
* @param {Boolean} options.includeSettlement - 반환 결과에 정산 정보를 포함할 지 여부로, 기본값은 true입니다.
47+
* @param {Date} options.timestamp - 방의 출발 여부(isDeparted)를 판단하는 기준이 되는 시각입니다.
48+
* @param {Boolean} options.isOver - 방의 완료 여부(isOver)로, 기본값은 false입니다. includeSettlement가 false인 경우 roomDocument의 isOver 속성은 undefined로 설정됩니다.
49+
* @return {FormattedRoom} 정산 여부가 위와 같이 가공되고 isDeparted 속성이 추가된 Room Object가 반환됩니다.
50+
*/
51+
export const formatSettlement = (
52+
roomObject: PopulatedRoom,
53+
{ includeSettlement = true, isOver = false, timestamp = Date.now() } = {}
54+
): FormattedRoom => {
55+
return {
56+
...roomObject,
57+
part: roomObject.part?.map((participantSubDocument) => {
58+
const { _id, name, nickname, profileImageUrl } =
59+
participantSubDocument.user;
60+
const { settlementStatus, readAt } = participantSubDocument;
61+
return {
62+
_id,
63+
name,
64+
nickname,
65+
profileImageUrl,
66+
isSettlement: includeSettlement ? settlementStatus : undefined,
67+
readAt: readAt ?? roomObject.madeat,
68+
};
69+
}),
70+
settlementTotal: includeSettlement ? roomObject.settlementTotal : undefined,
71+
isOver: includeSettlement ? isOver : undefined,
72+
isDeparted: new Date(roomObject.time) < new Date(timestamp),
73+
};
74+
}
75+
76+
/**
77+
* roomPopulateOption을 사용해 populate된 Room Object와 사용자의 id(userId)가 주어졌을 때, 해당 사용자의 정산 상태를 반환합니다.
78+
* @param {PopulatedRoom} roomObject - roomPopulateOption을 사용해 populate된 변환한 Room Object입니다.
79+
* @param {String} userId - 방 완료 상태를 확인하려는 사용자의 id(user.id)입니다.
80+
* @return {Boolean | undefined} 사용자의 해당 방에 대한 완료 여부(true | false)를 반환합니다. 사용자가 참여중인 방이 아닐 경우 undefined를 반환합니다.
81+
**/
82+
export const getIsOver = (roomObject: PopulatedRoom, userId: string) => {
83+
// room document의 part subdoocument에서 사용자 id와 일치하는 정산 정보를 찾습니다.
84+
const participantSubDocuments = roomObject.part?.filter((part) => {
85+
return part.user.id === userId;
86+
});
87+
88+
// 방에 참여중이지 않은 사용자의 경우, undefined을 반환합니다.
89+
if (!participantSubDocuments || participantSubDocuments.length === 0) return undefined;
90+
91+
// 방에 참여중인 사용자의 경우, 정산 상태가 완료된 것인지("paid"거나 "sent"인지)를 반환합니다.
92+
return ["paid", "sent"].includes(participantSubDocuments[0].settlementStatus);
93+
};

src/types/mongo.d.ts

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Types } from "mongoose";
1+
import { Document, Types } from "mongoose";
22

3-
export interface User {
3+
export interface User extends Document {
44
/** 사용자의 실명. */
55
name: string;
66
/** 사용자의 닉네임. */
@@ -39,7 +39,7 @@ export interface User {
3939

4040
export type SettlementStatus = "not-departed" | "paid" | "send-required" | "sent";
4141

42-
export interface Participant {
42+
export interface Participant extends Document {
4343
/** 방 참여자의 User ObjectID. */
4444
user: Types.ObjectId;
4545
/** 방 참여자의 정산 상태. */
@@ -48,14 +48,14 @@ export interface Participant {
4848
readAt?: Date;
4949
}
5050

51-
export interface DeviceToken {
51+
export interface DeviceToken extends Document {
5252
/** 디바이스 토큰 소유자의 User ObjectID. */
5353
userId: Types.ObjectId;
5454
/** 소유한 디바이스 토큰의 배열. */
5555
deviceTokens: Types.Array<string>;
5656
}
5757

58-
export interface NotificationOption {
58+
export interface NotificationOption extends Document {
5959
deviceToken: string;
6060
/** 채팅 알림 수신 여부. */
6161
chatting: boolean;
@@ -69,13 +69,13 @@ export interface NotificationOption {
6969
advertisement: boolean;
7070
}
7171

72-
export interface TopicSubscription {
72+
export interface TopicSubscription extends Document {
7373
deviceToken?: string;
7474
topic?: string;
7575
subscribedAt: Date;
7676
}
7777

78-
export interface Room {
78+
export interface Room extends Document {
7979
/** 방의 이름. */
8080
name: string;
8181
/** 방의 출발지의 Location ObjectID. */
@@ -94,7 +94,7 @@ export interface Room {
9494
maxPartLength: number;
9595
}
9696

97-
export interface Location {
97+
export interface Location extends Document {
9898
enName: string;
9999
koName: string;
100100
priority: number;
@@ -116,7 +116,7 @@ export type ChatType =
116116
| "departure"
117117
| "arrival";
118118

119-
export interface Chat {
119+
export interface Chat extends Document {
120120
/** 메세지가 전송된 방의 Room ObjectID. */
121121
roomId: Types.ObjectId;
122122
/** 메세지의 종류. */
@@ -128,7 +128,7 @@ export interface Chat {
128128
isValid: boolean;
129129
}
130130

131-
export interface Report {
131+
export interface Report extends Document {
132132
/** 신고한 사용자의 ObjectID. */
133133
creatorId: Types.ObjectId;
134134
/** 신고받은 사용자의 ObjectID. */
@@ -143,14 +143,14 @@ export interface Report {
143143
roomId?: Types.ObjectId;
144144
}
145145

146-
export interface AdminIPWhitelist {
146+
export interface AdminIPWhitelist extends Document {
147147
ip: string;
148148
description: string;
149149
}
150150

151151
export type AdminLogAction = "create" | "read" | "update" | "delete";
152152

153-
export interface AdminLog {
153+
export interface AdminLog extends Document {
154154
/** 로그 발생자의 User ObjectID. */
155155
user: Types.ObjectId;
156156
/** 로그의 발생 시각. */

0 commit comments

Comments
 (0)