Skip to content

Commit 6d35fd3

Browse files
authored
Merge pull request #113 from PLANALOG/feature/moment-system-api
Feature: 다른사용자 moment목록조회
2 parents 5717b1e + 2d28571 commit 6d35fd3

5 files changed

Lines changed: 192 additions & 128 deletions

File tree

src/controllers/moment.controller.js

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import {
33
bodyToCreateMoment,
44
bodyToUpdateMoment,
55
responseFromMyMomentDetail,
6-
responseFromFriendsMoments,
7-
responseFromFriendMomentDetail } from "../dtos/moment.dto.js";
6+
responseFromOtherUserMoments,
7+
responseFromOtherUserMomentDetail } from "../dtos/moment.dto.js";
88
import {
99
momentCreate,
1010
momentUpdate,
1111
momentDelete,
1212
getMyMoments,
1313
getMyMomentDetail,
14-
getFriendsMoments,
15-
getFriendMomentDetail } from "../services/moment.service.js";
14+
getOtherUserMoments,
15+
getOtherUserMomentDetail } from "../services/moment.service.js";
1616

1717

1818
export const handleCreateMoment = async (req, res, next) => {
@@ -228,66 +228,83 @@ export const handleGetMyMomentDetail = async (req, res, next) => {
228228
}
229229
};
230230

231+
export const handleGetOtherUserMoments = async (req, res, next) => {
232+
try {
231233

234+
// userId 확인: 잘못된 값이 전달되는지 확인
235+
const userId = Number(req.params.userId);
236+
console.log("Received userId from params:", req.params.userId); // 확인용 로그 추가
237+
if (isNaN(userId)) {
238+
throw new Error("유효하지 않은 사용자 ID입니다.");
239+
}
232240

233-
export const handleGetFriendsMoments = async (req, res, next) => {
234-
/*
235-
#swagger.tags = ['Moments']
236-
#swagger.summary = '친구의 Moment 목록 조회 API'
237-
#swagger.description = '친구의 페이지에서 해당 친구의 Moment 게시물 목록을 조회합니다.'
238-
#swagger.security = [{
239-
"bearerAuth": []
240-
}]
241-
242-
*/
241+
// getOtherUserMoments 함수에서 userId 확인
242+
const responseData = await getOtherUserMoments(userId);
243243

244-
try {
245-
console.log("친구의 Moment 목록 조회 요청");
246-
const friendId = parseInt(req.params.friendId, 10);
247-
const moments = await getFriendsMoments(friendId);
248244
res.status(StatusCodes.OK).json({
249245
resultType: "SUCCESS",
250246
error: null,
251-
success: {
252-
data: responseFromFriendsMoments(moments)
253-
}
247+
success: { data: responseData }
254248
});
249+
255250
} catch (error) {
251+
console.error("❌ 특정 사용자의 Moment 목록 조회 오류:", error);
256252
next(error);
257253
}
258254
};
259255

260256

261-
export const handleGetFriendMomentDetail = async (req, res, next) => {
257+
258+
259+
260+
261+
262+
263+
264+
export const handleGetOtherUserMomentDetail = async (req, res, next) => {
262265
/*
263266
#swagger.tags = ['Moments']
264-
#swagger.summary = '친구의 특정 Moment 상세 조회 API'
265-
#swagger.description = '친구의 페이지에서 특정 Moment 게시물의 상세 정보를 조회합니다.'
266-
#swagger.security = [{
267-
"bearerAuth": []
268-
}]
267+
#swagger.summary = '특정 사용자의 특정 Moment 상세 조회 API'
268+
#swagger.description = '특정 사용자의 페이지에서 특정 Moment 게시물의 상세 정보를 조회합니다.'
269+
#swagger.security = [{ "bearerAuth": [] }]
270+
#swagger.parameters['userId'] = {
271+
in: "path",
272+
required: true,
273+
description: "조회할 사용자의 ID",
274+
schema: { type: "integer", example: 1234 }
275+
}
269276
#swagger.parameters['momentId'] = {
270277
in: "path",
271278
required: true,
272279
description: "조회할 Moment의 ID",
273280
schema: { type: "integer", example: 456 }
274281
}
275-
276282
*/
277283

278284
try {
279-
console.log("친구의 특정 Moment 상세 조회 요청");
280-
const friendId = parseInt(req.params.friendId, 10);
281-
const momentId = parseInt(req.params.momentId, 10);
282-
const moment = await getFriendMomentDetail(friendId, momentId);
285+
console.log("특정 사용자의 Moment 목록 조회 요청");
286+
287+
const userId = parseInt(req.params.userId, 10);
288+
if (isNaN(userId)) {
289+
throw new Error("유효하지 않은 사용자 ID입니다.");
290+
}
291+
292+
const moments = await getOtherUserMoments(userId);
293+
294+
// 🔍 responseFromOtherUserMoments() 변환 결과 확인
295+
const responseData = responseFromOtherUserMoments(moments);
296+
console.log("Swagger 응답 데이터:", JSON.stringify(responseData, null, 2));
297+
283298
res.status(StatusCodes.OK).json({
284299
resultType: "SUCCESS",
285300
error: null,
286301
success: {
287-
data: responseFromFriendMomentDetail(moment)
302+
data: responseData
288303
}
289304
});
290305
} catch (error) {
306+
console.error("특정 사용자의 Moment 목록 조회 오류:", error);
291307
next(error);
292308
}
293-
};
309+
};
310+

src/dtos/moment.dto.js

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -194,33 +194,56 @@ export const responseFromMyMomentDetail = (moment) => {
194194
};
195195

196196

197-
// 친구의 Moment 목록 조회 DTO
198-
export const responseFromFriendsMoments = (moments) => {
199-
return moments.map(moment => ({
200-
userId: moment.userId,
201-
momentId: moment.id,
202-
title: moment.title,
203-
status: moment.status,
204-
createdAt: formatDateTime(moment.createdAt),
205-
updatedAt: formatDateTime(moment.updatedAt),
206-
thumbnailUrl: moment.momentContents[0]?.url || null
207-
}));
197+
export const responseFromOtherUserMoments = (moments) => {
198+
if (!Array.isArray(moments)) {
199+
console.error("❌ moments가 배열이 아님:", moments);
200+
return [];
201+
}
202+
203+
return moments.map(moment => {
204+
if (!moment || typeof moment.id === "undefined") {
205+
console.error("❌ moment.id가 유실됨! 원인 추적 필요:", moment);
206+
return null;
207+
}
208+
209+
const transformedMoment = {
210+
userId: Number(moment.userId), // ✅ bigint 변환
211+
momentId: Number(moment.id), // ✅ bigint 변환
212+
title: moment.title,
213+
date: moment.createdAt ? moment.createdAt.toISOString().split("T")[0] : "날짜 없음",
214+
userName: moment.user?.name ?? "알 수 없음",
215+
likingCount: Number(moment.likingCount ?? 0),
216+
commentCount: Number(moment._count?.comments ?? 0),
217+
thumbnailURL: moment.momentContents?.length > 0 ? moment.momentContents[0].url : null
218+
};
219+
220+
return transformedMoment;
221+
}).filter(moment => moment !== null);
208222
};
209223

210-
// 친구의 moment 상세 조회 DTO
211-
export const responseFromFriendMomentDetail = (moment) => {
224+
225+
226+
227+
228+
// 친구의 Moment 상세 조회 DTO
229+
export const responseFromOtherUserMomentDetail = (moment) => {
230+
if (!moment || !moment.id) {
231+
console.error("잘못된 moment 데이터:", moment);
232+
return null;
233+
}
234+
212235
return {
213236
userId: moment.userId,
214237
momentId: moment.id,
215238
title: moment.title,
216-
status: moment.status,
217-
plannerId: moment.plannerId || null,
218-
createdAt: formatDateTime(moment.createdAt),
219-
updatedAt: formatDateTime(moment.updatedAt),
239+
date: formatDate(moment.createdAt),
240+
plannerId: moment.plannerId ?? null,
241+
createdAt: formatDateTime(moment.createdAt),
242+
updatedAt: formatDateTime(moment.updatedAt),
220243
momentContents: moment.momentContents.map(content => ({
221244
sortOrder: content.sortOrder,
222245
content: content.content,
223-
url: content.url,
246+
url: content.url ?? null
224247
}))
225248
};
226-
};
249+
};

src/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,17 @@ import {
187187
handleDeleteMoment,
188188
handleGetMyMoments,
189189
handleGetMyMomentDetail,
190-
handleGetFriendsMoments,
191-
handleGetFriendMomentDetail
190+
handleGetOtherUserMoments,
191+
handleGetOtherUserMomentDetail
192192
} from "./controllers/moment.controller.js";
193193

194194
app.post("/moments", authenticateJWT, handleCreateMoment); //모먼트 생성
195195
app.patch("/moments/:momentId", authenticateJWT, handleUpdateMoment); //모먼트 수정
196196
app.delete("/moments/:momentId", authenticateJWT, handleDeleteMoment); //모먼트 삭제
197197
app.get("/mypage/moments", authenticateJWT, handleGetMyMoments); //마이페이지에서 나의 moment게시글 목록 조회
198198
app.get("/mypage/moments/:momentId", authenticateJWT, handleGetMyMomentDetail); //마이페이지에서 나의 특정 moment게시물 조회
199-
app.get("/friends/:friendId/moments", authenticateJWT, handleGetFriendsMoments) //친구페이지 moment게시물 목록 조회
200-
app.get("/friends/:friendId/moments/momentId", authenticateJWT, handleGetFriendMomentDetail); //친구페이지 특정 moment게시물 조회
199+
app.get("/users/:userId/moments", authenticateJWT, handleGetOtherUserMoments) //친구페이지 moment게시물 목록 조회
200+
app.get("/users/:userId/moments/momentId", authenticateJWT, handleGetOtherUserMomentDetail); //친구페이지 특정 moment게시물 조회
201201

202202

203203

src/repositories/moment.repository.js

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -203,57 +203,60 @@ export const findMyMomentDetail = async (userId, momentId) => {
203203
};
204204

205205

206-
// 친구들의 Moment 목록 조회 (status: public만 조회)
207-
export const findFriendsMoments = async (userId) => {
208-
// 친구 목록 조회
209-
const friendIds = await prisma.friend.findMany({
210-
where: {
211-
fromUserId: BigInt(userId),
212-
isAccepted: true,
213-
},
214-
select: {
215-
toUserId: true,
216-
},
217-
});
218-
219-
const friendUserIds = friendIds.map(friend => friend.toUserId);
220-
221-
return await prisma.moment.findMany({
222-
where: {
223-
userId: { in: friendUserIds },
224-
status: 'public',
225-
},
226-
include: {
227-
momentContents: true,
228-
},
229-
orderBy: {
230-
createdAt: 'desc',
231-
},
232-
});
206+
export const findOtherUserMoments = async (userId) => {
207+
try {
208+
209+
const moments = await prisma.moment.findMany({
210+
where: { userId: BigInt(userId) },
211+
include: {
212+
user: { select: { name: true } },
213+
momentContents: { select: { url: true }, take: 1 },
214+
_count: { select: { comments: true } }
215+
},
216+
orderBy: { createdAt: "desc" },
217+
});
218+
219+
for (const moment of moments) {
220+
const likesCount = await prisma.like.count({
221+
where: {
222+
entityId: Number(moment.id),
223+
entityType: "moment",
224+
},
225+
});
226+
moment.likingCount = likesCount;
227+
}
228+
229+
return moments;
230+
} catch (error) {
231+
console.error("[findOtherUserMoments] DB 조회 오류:", error);
232+
throw new Error("Moment 목록 조회 실패");
233+
}
233234
};
234235

235-
// 친구의 특정 Moment 상세 조회 (status: public만 조회)
236-
export const findFriendMomentDetail = async (userId, momentId) => {
237-
// 친구인지 확인
238-
const isFriend = await prisma.friend.findFirst({
239-
where: {
240-
fromUserId: BigInt(userId),
241-
isAccepted: true,
242-
},
243-
});
244-
245-
if (!isFriend) {
246-
throw new Error("친구가 아닌 사용자입니다.");
247-
}
248-
249-
return await prisma.moment.findFirst({
250-
where: {
251-
id: BigInt(momentId),
252-
userId: isFriend.toUserId,
253-
status: 'public',
254-
},
255-
include: {
256-
momentContents: true,
257-
},
258-
});
259-
};
236+
237+
238+
239+
240+
// 특정 사용자의 특정 Moment 상세 조회
241+
export const findOtherUserMomentDetail = async (userId, momentId) => {
242+
try {
243+
console.log(`[findOtherUserMomentDetail] API 호출됨! userId: ${userId}, momentId: ${momentId}`);
244+
245+
const moment = await prisma.moment.findUnique({
246+
where: { id: BigInt(momentId) },
247+
include: {
248+
momentContents: true,
249+
planner: true
250+
}
251+
});
252+
253+
if (!moment) {
254+
throw new Error("Moment를 찾을 수 없습니다.");
255+
}
256+
257+
return moment;
258+
} catch (error) {
259+
console.error("[findOtherUserMomentDetail] DB 조회 오류:", error.message);
260+
throw error;
261+
}
262+
};

0 commit comments

Comments
 (0)