From 4578e03d018d0f7acdd2698fea04e9aac9e616c7 Mon Sep 17 00:00:00 2001 From: Hyun-git Date: Tue, 2 Jul 2024 12:11:02 +0900 Subject: [PATCH 1/3] feat: additional task --- src/controller/keyword.controller.ts | 12 ++++++++++++ src/controller/meme.controller.ts | 7 +++++-- src/model/user.ts | 1 + src/service/meme.service.ts | 14 ++++++++++++++ src/service/user.service.ts | 17 +++++++++++++---- 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/controller/keyword.controller.ts b/src/controller/keyword.controller.ts index 7e3eb82..6b868b3 100644 --- a/src/controller/keyword.controller.ts +++ b/src/controller/keyword.controller.ts @@ -40,6 +40,18 @@ const getTopKeywords = async (req: Request, res: Response, next: NextFunction) = const limit = 6; try { const topKeywords = await KeywordService.getTopKeywords(limit); + // 키워드에 해당하는 밈 이미지 가져오기 + const promises = topKeywords.map(async (keyword) => { + try { + const topReactionImage = await MemeService.getTopReactionImage(keyword); + keyword["topReactionImage"] = topReactionImage; + } catch (error) { + console.error(`Error fetching reaction image for keyword "${keyword}":`, error); + } + }); + + await Promise.all(promises); + logger.info(`Get top ${limit} keywords: ${JSON.stringify(topKeywords)}`); return res.json(createSuccessResponse(HttpCode.OK, 'Get Top Keywords', topKeywords)); } catch (err) { diff --git a/src/controller/meme.controller.ts b/src/controller/meme.controller.ts index 1b6b8e6..68a9ec9 100644 --- a/src/controller/meme.controller.ts +++ b/src/controller/meme.controller.ts @@ -234,10 +234,13 @@ const createMemeWatch = async (req: CustomRequest, res: Response, next: NextFunc return res.json(createSuccessResponse(HttpCode.CREATED, 'Crate Meme Watch', result)); } else if (type == MemeWatchType.RECOMMEND) { - const memeRecommendWatch = await UserService.createMemeRecommendWatch(user, meme); + const [recommendMemeWatchCount, _]: [number, any] = await Promise.all([ + UserService.createMemeRecommendWatch(user, meme), + UserService.updateLastSeenMeme(user, meme), + ]); return res.json( - createSuccessResponse(HttpCode.CREATED, `${type} Meme Watch`, memeRecommendWatch), + createSuccessResponse(HttpCode.CREATED, `${type} Meme Watch`, recommendMemeWatchCount), ); } else { return next(new CustomError(`Invalid 'type' parameter.`, HttpCode.BAD_REQUEST)); diff --git a/src/model/user.ts b/src/model/user.ts index b596dd9..12bffc2 100644 --- a/src/model/user.ts +++ b/src/model/user.ts @@ -11,6 +11,7 @@ export interface IUserInfos extends IUser { reaction: number; save: number; level: number; + memeRecommendWatchCount: number; } export interface IUserDocument extends Document { diff --git a/src/service/meme.service.ts b/src/service/meme.service.ts index 09db62f..5ad9fe4 100644 --- a/src/service/meme.service.ts +++ b/src/service/meme.service.ts @@ -250,6 +250,18 @@ async function deleteMemeSave(user: IUserDocument, meme: IMemeDocument): Promise throw new CustomError(`Failed delete memeSave(${err.message})`, HttpCode.INTERNAL_SERVER_ERROR); } } +async function getTopReactionImage(keyword: IKeywordDocument): Promise { + try { + const topReactionMeme = await MemeModel.findOne({ keywordIds: keyword._id }).sort({ reaction: -1 }); + + logger.info(`Get top reaction meme - keyword(${keyword.name}), meme(${topReactionMeme._id})`); + return topReactionMeme.image; + }catch (err) { + logger.error(`Failed get top reaction meme`, err.message); + throw new CustomError(`Failed get top reaction meme(${err.message})`, HttpCode.INTERNAL_SERVER_ERROR); + } +} + export { getMeme, @@ -263,4 +275,6 @@ export { deleteKeywordOfMeme, getMemeWithKeywords, searchMemeByKeyword, + getTopReactionImage, }; + diff --git a/src/service/user.service.ts b/src/service/user.service.ts index 1b8defe..3176fe8 100644 --- a/src/service/user.service.ts +++ b/src/service/user.service.ts @@ -11,7 +11,7 @@ import { IMemeRecommendWatchCreatePayload, } from '../model/memeRecommendWatch'; import { logger } from '../util/logger'; -import { startOfWeek, format } from 'date-fns'; +import { startOfWeek } from 'date-fns'; async function getUser(deviceId: string): Promise { try { @@ -47,12 +47,21 @@ async function createUser(deviceId: string): Promise { countInteractionType(InteractionType.SAVE), ]); + const todayWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }); + const memeRecommendWatchList = await MemeRecommendWatchModel.find({ + startDate: todayWeekStart, + deviceId: foundUser.deviceId, + isDeleted: false, + }); + + return { ...foundUser.toObject(), watch, reaction, save, share, + memeRecommendWatchCount: memeRecommendWatchList.length, level: 1, }; } @@ -156,7 +165,7 @@ async function getSavedMeme(user: IUserDocument): Promise { async function createMemeRecommendWatch( user: IUserDocument, meme: IMemeDocument, -): Promise { +): Promise { try { const todayWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }); const memeRecommendWatch = await MemeRecommendWatchModel.findOne({ @@ -176,7 +185,7 @@ async function createMemeRecommendWatch( { _id: memeRecommendWatch._id }, { $set: updatePayload }, ); - return true; + return updatePayload.memeIds.length; } const createPayload: IMemeRecommendWatchCreatePayload = { @@ -187,7 +196,7 @@ async function createMemeRecommendWatch( await MemeRecommendWatchModel.create(createPayload); - return true; + return 1; } catch (err) { logger.error(`Failed create memeRecommendWatch`, err.message); throw new CustomError( From f78e30678240f6e641277dd540d6de1ab13ff972 Mon Sep 17 00:00:00 2001 From: Hyun-git Date: Thu, 4 Jul 2024 15:23:57 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/keyword.controller.ts | 19 ++++++++++--------- src/model/keyword.ts | 4 ++++ src/service/user.service.ts | 5 +++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/controller/keyword.controller.ts b/src/controller/keyword.controller.ts index 6b868b3..49a2da6 100644 --- a/src/controller/keyword.controller.ts +++ b/src/controller/keyword.controller.ts @@ -4,7 +4,7 @@ import _ from 'lodash'; import CustomError from '../errors/CustomError'; import { HttpCode } from '../errors/HttpCode'; import { CustomRequest } from '../middleware/requestedInfo'; -import { IKeywordUpdatePayload } from '../model/keyword'; +import { IKeywordDocument, IKeywordUpdatePayload, IKeywordWithImage } from '../model/keyword'; import * as KeywordService from '../service/keyword.service'; import * as MemeService from '../service/meme.service'; import { logger } from '../util/logger'; @@ -39,21 +39,22 @@ const deleteKeyword = async (req: CustomRequest, res: Response, next: NextFuncti const getTopKeywords = async (req: Request, res: Response, next: NextFunction) => { const limit = 6; try { - const topKeywords = await KeywordService.getTopKeywords(limit); + const topKeywords: IKeywordDocument[] = await KeywordService.getTopKeywords(limit); // 키워드에 해당하는 밈 이미지 가져오기 - const promises = topKeywords.map(async (keyword) => { + const promises: Promise[] = topKeywords.map(async (keyword: IKeywordDocument) => { try { - const topReactionImage = await MemeService.getTopReactionImage(keyword); - keyword["topReactionImage"] = topReactionImage; + const topReactionImage: string = await MemeService.getTopReactionImage(keyword); + return { ...keyword, topReactionImage } as IKeywordWithImage; } catch (error) { - console.error(`Error fetching reaction image for keyword "${keyword}":`, error); + logger.error(`Error retrieving top reaction image for keyword: ${keyword}`, error); + throw new CustomError(`Failed to get top reaction image`, HttpCode.INTERNAL_SERVER_ERROR); } }); - await Promise.all(promises); + const keywordWithImages: IKeywordWithImage[] = await Promise.all(promises); - logger.info(`Get top ${limit} keywords: ${JSON.stringify(topKeywords)}`); - return res.json(createSuccessResponse(HttpCode.OK, 'Get Top Keywords', topKeywords)); + logger.info(`Get top ${limit} keywords: ${JSON.stringify(keywordWithImages)}`); + return res.json(createSuccessResponse(HttpCode.OK, 'Get Top Keywords', keywordWithImages)); } catch (err) { return next(new CustomError(err.message, err.status || HttpCode.INTERNAL_SERVER_ERROR)); } diff --git a/src/model/keyword.ts b/src/model/keyword.ts index 1f76f87..f7a9658 100644 --- a/src/model/keyword.ts +++ b/src/model/keyword.ts @@ -10,6 +10,10 @@ export interface IKeywordUpdatePayload { category?: string; } +export interface IKeywordWithImage extends IKeyword { + topReactionImage: string; +} + export interface IKeyword { name: string; category: string; diff --git a/src/service/user.service.ts b/src/service/user.service.ts index 3176fe8..0266f78 100644 --- a/src/service/user.service.ts +++ b/src/service/user.service.ts @@ -48,7 +48,7 @@ async function createUser(deviceId: string): Promise { ]); const todayWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }); - const memeRecommendWatchList = await MemeRecommendWatchModel.find({ + const memeRecommendWatctCount = await MemeRecommendWatchModel.countDocuments({ startDate: todayWeekStart, deviceId: foundUser.deviceId, isDeleted: false, @@ -61,7 +61,7 @@ async function createUser(deviceId: string): Promise { reaction, save, share, - memeRecommendWatchCount: memeRecommendWatchList.length, + memeRecommendWatchCount: memeRecommendWatctCount, level: 1, }; } @@ -169,6 +169,7 @@ async function createMemeRecommendWatch( try { const todayWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }); const memeRecommendWatch = await MemeRecommendWatchModel.findOne({ + memeId: meme._id, startDate: todayWeekStart, deviceId: user.deviceId, isDeleted: false, From 817d5c650c36846c06f1ce808a20234167854c3f Mon Sep 17 00:00:00 2001 From: Hyun_Gwang Date: Thu, 4 Jul 2024 22:08:46 +0900 Subject: [PATCH 3/3] fix: wrong word --- src/service/user.service.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/service/user.service.ts b/src/service/user.service.ts index 0266f78..19fcad7 100644 --- a/src/service/user.service.ts +++ b/src/service/user.service.ts @@ -48,12 +48,11 @@ async function createUser(deviceId: string): Promise { ]); const todayWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }); - const memeRecommendWatctCount = await MemeRecommendWatchModel.countDocuments({ + const memeRecommendWatchCount = await MemeRecommendWatchModel.countDocuments({ startDate: todayWeekStart, deviceId: foundUser.deviceId, isDeleted: false, }); - return { ...foundUser.toObject(), @@ -61,7 +60,7 @@ async function createUser(deviceId: string): Promise { reaction, save, share, - memeRecommendWatchCount: memeRecommendWatctCount, + memeRecommendWatchCount: memeRecommendWatchCount, level: 1, }; } @@ -162,10 +161,7 @@ async function getSavedMeme(user: IUserDocument): Promise { } } -async function createMemeRecommendWatch( - user: IUserDocument, - meme: IMemeDocument, -): Promise { +async function createMemeRecommendWatch(user: IUserDocument, meme: IMemeDocument): Promise { try { const todayWeekStart = startOfWeek(new Date(), { weekStartsOn: 1 }); const memeRecommendWatch = await MemeRecommendWatchModel.findOne({