Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop - Header 추가, 밈 조회 관련 모든 응답에 isSaved 추가, 키워드 응답 형식 변경 #29

Merged
merged 20 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions example.env

This file was deleted.

1 change: 1 addition & 0 deletions get-s3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const AWS = require('aws-sdk')
36 changes: 16 additions & 20 deletions src/controller/meme.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,18 @@ const getMeme = async (req: Request, res: Response, next: NextFunction) => {
}
};

const getMemeWithKeywords = async (req: Request, res: Response, next: NextFunction) => {
const memeId = req.params?.memeId || null;

if (_.isNull(memeId)) {
return next(new CustomError(`'memeId' field should be provided`, HttpCode.BAD_REQUEST));
}

if (!mongoose.Types.ObjectId.isValid(memeId)) {
return next(new CustomError(`'memeId' is not a valid ObjectId`, HttpCode.BAD_REQUEST));
}
const getMemeWithKeywords = async (req: CustomRequest, res: Response, next: NextFunction) => {
const user = req.requestedUser;
const meme = req.requestedMeme;

try {
const meme = await MemeService.getMemeWithKeywords(memeId);
if (_.isNull(meme)) {
return next(new CustomError(`Meme(${memeId}) not found.`, HttpCode.NOT_FOUND));
const ret = await MemeService.getMemeWithKeywords(user, meme);
if (_.isNull(ret)) {
return next(new CustomError(`Meme(${meme._id}) not found.`, HttpCode.NOT_FOUND));
}

logger.info(`Get meme with keywords - ${memeId})`);
return res.json(createSuccessResponse(HttpCode.OK, 'Get Meme', meme));
logger.info(`Get meme with keywords - ${meme._id})`);
return res.json(createSuccessResponse(HttpCode.OK, 'Get Meme', ret));
} catch (err) {
return next(new CustomError(err.message, err.status));
}
Expand Down Expand Up @@ -120,7 +113,8 @@ const deleteMeme = async (req: CustomRequest, res: Response, next: NextFunction)
}
};

const getAllMemeList = async (req: Request, res: Response, next: NextFunction) => {
const getAllMemeList = async (req: CustomRequest, res: Response, next: NextFunction) => {
const user = req.requestedUser;
const page = parseInt(req.query.page as string) || 1;
if (page < 1) {
return next(new CustomError(`Invalid 'page' parameter`, HttpCode.BAD_REQUEST));
Expand All @@ -132,7 +126,7 @@ const getAllMemeList = async (req: Request, res: Response, next: NextFunction) =
}

try {
const memeList = await MemeService.getAllMemeList(page, size);
const memeList = await MemeService.getAllMemeList(page, size, user);

const data = {
pagination: {
Expand All @@ -151,7 +145,8 @@ const getAllMemeList = async (req: Request, res: Response, next: NextFunction) =
}
};

const getTodayMemeList = async (req: Request, res: Response, next: NextFunction) => {
const getTodayMemeList = async (req: CustomRequest, res: Response, next: NextFunction) => {
const user = req.requestedUser;
const size = parseInt(req.query.size as string) || 5;

if (size > 5) {
Expand All @@ -164,14 +159,15 @@ const getTodayMemeList = async (req: Request, res: Response, next: NextFunction)
}

try {
const todayMemeList = await MemeService.getTodayMemeList(size);
const todayMemeList = await MemeService.getTodayMemeList(size, user);
return res.json(createSuccessResponse(HttpCode.OK, 'Get today meme list', todayMemeList));
} catch (err) {
return next(new CustomError(err.message, err.status));
}
};

const searchMemeListByKeyword = async (req: CustomRequest, res: Response, next: NextFunction) => {
const user = req.requestedUser;
const keyword = req.requestedKeyword;

const page = parseInt(req.query.page as string) || 1;
Expand All @@ -185,7 +181,7 @@ const searchMemeListByKeyword = async (req: CustomRequest, res: Response, next:
}

try {
const memeList = await MemeService.searchMemeByKeyword(page, size, keyword);
const memeList = await MemeService.searchMemeByKeyword(page, size, keyword, user);
const data = {
pagination: {
total: memeList.total,
Expand Down
39 changes: 8 additions & 31 deletions src/controller/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import _ from 'lodash';
import CustomError from '../errors/CustomError';
import { HttpCode } from '../errors/HttpCode';
import { CustomRequest } from '../middleware/requestedInfo';
import { InteractionType, MemeInteractionModel } from '../model/memeInteraction';
import * as UserService from '../service/user.service';
import { createSuccessResponse } from '../util/response';

Expand All @@ -26,48 +25,26 @@ const getUser = async (req: CustomRequest, res: Response, next: NextFunction) =>
const user = req.requestedUser;

try {
const countInteractionType = (type: InteractionType) =>
MemeInteractionModel.countDocuments({
deviceId: user.deviceId,
interactionType: type,
});

const [watch, reaction, share, save] = await Promise.all([
countInteractionType(InteractionType.WATCH),
countInteractionType(InteractionType.REACTION),
countInteractionType(InteractionType.SHARE),
countInteractionType(InteractionType.SAVE),
]);

const level = getLevel(watch, reaction, share);

return res.json(
createSuccessResponse(HttpCode.OK, 'Get User', {
...user,
watch,
reaction,
share,
save,
level,
}),
);
const userInfos = await UserService.makeUserInfos(user.deviceId);
const level = getLevel(userInfos.watch, userInfos.reaction, userInfos.share);
return res.json(createSuccessResponse(HttpCode.OK, 'Get User', { ...userInfos, level }));
} catch (err) {
return next(new CustomError(err.message, err.status));
}
};

const getLastSeenMemes = async (req: CustomRequest, res: Response, next: NextFunction) => {
const getLastSeenMemeList = async (req: CustomRequest, res: Response, next: NextFunction) => {
const user = req.requestedUser;

try {
const memeList = await UserService.getLastSeenMemes(user);
const memeList = await UserService.getLastSeenMemeList(user);
return res.json(createSuccessResponse(HttpCode.OK, 'Get Last Seen Meme', memeList));
} catch (err) {
return next(new CustomError(err.message, err.status));
}
};

const getSavedMemes = async (req: CustomRequest, res: Response, next: NextFunction) => {
const getSavedMemeList = async (req: CustomRequest, res: Response, next: NextFunction) => {
const user = req.requestedUser;

const page = parseInt(req.query.page as string) || 1;
Expand All @@ -81,7 +58,7 @@ const getSavedMemes = async (req: CustomRequest, res: Response, next: NextFuncti
}

try {
const memeList = await UserService.getSavedMemes(page, size, user);
const memeList = await UserService.getSavedMemeList(page, size, user);

const data = {
pagination: {
Expand All @@ -99,7 +76,7 @@ const getSavedMemes = async (req: CustomRequest, res: Response, next: NextFuncti
}
};

export { getUser, createUser, getLastSeenMemes, getSavedMemes };
export { getUser, createUser, getLastSeenMemeList, getSavedMemeList };

function getLevel(watch: number, reaction: number, share: number): number {
let level = 1;
Expand Down
5 changes: 2 additions & 3 deletions src/middleware/requestedInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ export const getKeywordInfoByName = async (
}

const keyword = await getKeywordByName(keywordName);

if (!keyword) {
if (_.isNull(keyword)) {
return next(
new CustomError(`Keyword with name ${keywordName} does not exist`, HttpCode.NOT_FOUND),
);
Expand Down Expand Up @@ -100,7 +99,7 @@ export const getRequestedUserInfo = async (

const user = await getUser(deviceId);

if (!user) {
if (_.isNull(user)) {
return next(new CustomError(`user(${deviceId}) does not exist`, HttpCode.NOT_FOUND));
}

Expand Down
5 changes: 5 additions & 0 deletions src/model/keyword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export interface IKeywordWithImage extends IKeyword {
topReactionImage: string;
}

export interface IKeywordGetResponse {
_id: Types.ObjectId;
name: string;
}

export interface IKeyword {
name: string;
category: string;
Expand Down
12 changes: 7 additions & 5 deletions src/model/meme.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import mongoose, { Schema, Document, Types } from 'mongoose';

import { IKeywordGetResponse } from './keyword';

export interface IMemeCreatePayload {
title: string;
keywordIds: Types.ObjectId[];
Expand All @@ -23,6 +25,11 @@ export interface IMeme {
isTodayMeme: boolean;
}

export interface IMemeGetResponse extends Omit<IMemeDocument, 'keywordIds'> {
keywords: IKeywordGetResponse[];
isSaved: boolean; // 나의 파밈함 저장 여부
}

export interface IMemeDocument extends Document {
_id: Types.ObjectId;
title: string;
Expand All @@ -36,11 +43,6 @@ export interface IMemeDocument extends Document {
isDeleted: boolean;
}

// keywordIds로 조회한 keywords로 대체된 Meme 정보
export interface IMemeWithKeywords extends Omit<IMemeDocument, 'keywordIds'> {
keywords: string[];
}

const MemeSchema: Schema = new Schema(
{
title: { type: String, required: true },
Expand Down
8 changes: 4 additions & 4 deletions src/model/memeInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ export enum InteractionType {
}

export interface IMemeInteraction {
deviceId: String;
deviceId: string;
memeId: Types.ObjectId;
interactionType: InteractionType;
}

export interface IMemeInteraction extends Document {
export interface IMemeInteractionDocument extends Document {
_id: Types.ObjectId;
deviceId: String;
deviceId: string;
memeId: Types.ObjectId;
interactionType: InteractionType;
isDeleted: boolean;
Expand All @@ -37,7 +37,7 @@ const MemeInteractionSchema: Schema = new Schema(
},
);

export const MemeInteractionModel = mongoose.model<IMemeInteraction>(
export const MemeInteractionModel = mongoose.model<IMemeInteractionDocument>(
'memeInteraction',
MemeInteractionSchema,
);
20 changes: 12 additions & 8 deletions src/routes/keyword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ router.delete('/:keywordId', getKeywordInfoById, deleteKeyword);
* example: 100
* topReactionImage:
* type: string
* example: "https://example.com/top-reaction-image.jpg"
* example: "https://ppac-meme.s3.ap-northeast-2.amazonaws.com/17207029441190.png"
* createdAt:
* type: string
* example: "2024-07-05T15:21:34.012Z"
Expand Down Expand Up @@ -446,13 +446,17 @@ router.patch('/count', getKeywordInfoByName, increaseSearchCount);
* type: string
* example: "상황"
* keywords:
* type: array
* items:
* type: string
* example:
* - "키워드1"
* - "키워드2"
* - "키워드3"
* type: object
* properties:
* _id:
* type: string
* example: "667ff3d1239eeaf78630a283"
* name:
* type: string
* example: "웃긴"
* name:
* type: string
* example: "웃긴"
* 500:
* description: Internal server error
* content:
Expand Down
Loading