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

2024 추석이벤트 API: Item 단일 정보 불러오기 #538

Merged
merged 4 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 92 additions & 0 deletions src/lottery/routes/docs/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,92 @@ itemsDocs[`${apiPrefix}/`] = {
},
},
};
itemsDocs[`${apiPrefix}/{itemId}`] = {
get: {
tags: [`${apiPrefix}`],
summary: "상점에서 판매하는 특정 상품의 정보 반환",
description: "상점에서 판매하는 특정 상품의 정보를 가져옵니다.",
parameters: [
{
in: "path",
name: "itemId",
required: true,
description: "상품 정보를 조회할 ObjectId",
example: "ITEM ID",
},
],
responses: {
200: {
content: {
"application/json": {
schema: {
type: "object",
required: ["item"],
properties: {
item: {
type: "object",
required: [
"_id",
"name",
"description",
"imageUrl",
"price",
"isDisabled",
"itemType",
],
description: "상품의 정보",
properties: {
xMHW marked this conversation as resolved.
Show resolved Hide resolved
_id: {
type: "string",
description: "상품의 ObjectId",
example: "ITEM ID",
},
name: {
type: "string",
description: "상품의 이름",
example: "진짜 송편",
},
description: {
type: "string",
description: "상품의 설명",
example: "먹을 수 있는 송편입니다.",
},
imageUrl: {
type: "string",
description: "상품의 썸네일 이미지 URL",
example: "THUMBNAIL URL",
},
instagramStoryStickerImageUrl: {
type: "string",
description: "인스타그램 스토리 스티커 이미지 URL",
example: "STICKER URL",
},
price: {
type: "number",
description: "상품의 가격. 0 이상의 정수입니다.",
example: 400,
},
isDisabled: {
type: "boolean",
description: "상품의 판매 중지 여부",
example: false,
},
itemType: {
type: "number",
description:
"상품의 유형. 0: 일반 상품, 1: 일반 티켓, 2: 고급 티켓, 3: 랜덤박스입니다.",
example: 0,
},
},
},
},
},
},
},
},
},
},
};
itemsDocs[`${apiPrefix}/leaderboard/{itemId}`] = {
get: {
tags: [`${apiPrefix}`],
Expand Down Expand Up @@ -114,6 +200,7 @@ itemsDocs[`${apiPrefix}/leaderboard/{itemId}`] = {
"profileImageUrl",
"amount",
"probability",
"rank",
],
properties: {
nickname: {
Expand All @@ -136,6 +223,11 @@ itemsDocs[`${apiPrefix}/leaderboard/{itemId}`] = {
description: "유저가 상품에 당첨될 확률",
example: 0.1,
},
rank: {
type: "number",
description: "순위",
example: 1,
},
},
},
},
Expand Down
3 changes: 3 additions & 0 deletions src/lottery/routes/docs/schemas/itemsSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const { zodToSchemaObject } = require("../../../../routes/docs/utils");
const { objectId } = require("../../../../modules/patterns");

const itemsZod = {
getItemHandler: z.object({
itemId: z.string().regex(objectId),
}),
getItemLeaderboardHandler: z.object({
itemId: z.string().regex(objectId),
}),
Expand Down
5 changes: 5 additions & 0 deletions src/lottery/routes/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ const { itemsZod } = require("./docs/schemas/itemsSchema");
const itemsHandlers = require("../services/items");

router.get("/", itemsHandlers.getItemsHandler);
router.get(
"/:itemId",
validateParams(itemsZod.getItemHandler),
itemsHandlers.getItemHandler
);
router.get(
"/leaderboard/:itemId",
validateParams(itemsZod.getItemLeaderboardHandler),
Expand Down
20 changes: 20 additions & 0 deletions src/lottery/services/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ const getItemsHandler = async (req, res) => {
}
};

const getItemHandler = async (req, res) => {
try {
const { itemId } = req.params;
const item = await itemModel
.findById(
itemId,
"_id name description imageUrl instagramStoryStickerImageUrl price isDisabled itemType"
)
.lean();
if (!item) return res.status(400).json({ error: "Items/ : invalid item" });

res.json({ item });
} catch (err) {
logger.error(err);
res.status(500).json({ error: "Items/ : internal server error" });
}
};

// 유도 과정은 services/publicNotice.js 파일에 정의된 calculateProbabilityV2 함수의 주석 참조
const calculateWinProbability = (realStock, users, amount, totalAmount) => {
if (users.length <= realStock) return 1;
Expand Down Expand Up @@ -113,6 +131,7 @@ const getItemLeaderboardHandler = async (req, res) => {
profileImageUrl: userInfo.profileImageUrl,
amount: user.amount,
probability: user.probability,
rank: user.rank,
};
})
);
Expand Down Expand Up @@ -363,6 +382,7 @@ const purchaseItemHandler = async (req, res) => {

module.exports = {
getItemsHandler,
getItemHandler,
getItemLeaderboardHandler,
purchaseItemHandler,
};
Loading