146 lines
4.4 KiB
JavaScript
146 lines
4.4 KiB
JavaScript
// adapters/responses/dealDetail.adapter.js
|
|
const {mapBreadcrumbToResponse} =require( "./breadCrumb.adapter")
|
|
const { normalizeMediaPath } = require("../../utils/mediaPath")
|
|
|
|
const formatDateAsString = (value) =>
|
|
value instanceof Date ? value.toISOString() : value ?? null
|
|
|
|
const requiredIsoString = (value, fieldName) => {
|
|
if (value instanceof Date) return value.toISOString()
|
|
if (typeof value === "string" && value.length) return value
|
|
throw new Error(`${fieldName} is missing (undefined/null)`)
|
|
}
|
|
|
|
function mapNoticeToResponse(notice) {
|
|
if (!notice) return null
|
|
return {
|
|
id: notice.id,
|
|
title: notice.title,
|
|
dealId: notice.dealId,
|
|
body: notice.body ?? null,
|
|
severity: notice.severity,
|
|
isActive: notice.isActive,
|
|
createdBy: notice.createdBy,
|
|
createdAt: requiredIsoString(notice.createdAt, "notice.createdAt"),
|
|
updatedAt: requiredIsoString(notice.updatedAt, "notice.updatedAt"),
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// minimal similardeal -> response
|
|
function mapSimilarDealItem(d) {
|
|
if (!d) return null
|
|
return {
|
|
id: d.id,
|
|
title: d.title,
|
|
price: d.price ?? null,
|
|
score: Number.isFinite(d.score) ? d.score : 0,
|
|
imageUrl: normalizeMediaPath(d.imageUrl) || "",
|
|
sellerName: d.sellerName || "Bilinmiyor",
|
|
createdAt: formatDateAsString(d.createdAt), // SimilarDealSchema: nullable OK
|
|
// url: d.url ?? null,
|
|
}
|
|
}
|
|
|
|
function mapDealToDealDetailResponse(deal) {
|
|
if (!deal) return null
|
|
|
|
const firstNotice = Array.isArray(deal.notices) ? deal.notices[0] : null
|
|
|
|
if (!deal.user) throw new Error("deal.user is missing (include user in query)")
|
|
|
|
return {
|
|
id: deal.id,
|
|
title: deal.title,
|
|
description: deal.description || "",
|
|
hasLink: Boolean(deal.url),
|
|
price: deal.price ?? null,
|
|
originalPrice: deal.originalPrice ?? null,
|
|
shippingPrice: deal.shippingPrice ?? null,
|
|
couponCode: deal.couponCode ?? null,
|
|
location: deal.location ?? null,
|
|
discountType: deal.discountType ?? null,
|
|
discountValue: deal.discountValue ?? null,
|
|
barcodeId: deal.barcodeId ?? null,
|
|
score: Number.isFinite(deal.score) ? deal.score : 0,
|
|
myVote: deal.myVote ?? 0,
|
|
isSaved: Boolean(deal.isSaved),
|
|
|
|
commentsCount: deal._count?.comments ?? 0,
|
|
|
|
status: deal.status,
|
|
saleType: deal.saletype, // ✅ FIX: saletype değil
|
|
affiliateType: deal.affiliateType,
|
|
|
|
createdAt: requiredIsoString(deal.createdAt, "deal.createdAt"),
|
|
updatedAt: requiredIsoString(deal.updatedAt, "deal.updatedAt"),
|
|
|
|
user: {
|
|
id: deal.user.id,
|
|
username: deal.user.username,
|
|
avatarUrl: normalizeMediaPath(deal.user.avatarUrl) ?? null,
|
|
},
|
|
userStats: {
|
|
totalLikes: deal.userStats?.totalLikes ?? 0,
|
|
totalDeals: deal.userStats?.totalDeals ?? 0,
|
|
},
|
|
|
|
// ✅ FIX: SellerSummarySchema genelde id ister -> custom seller için -1
|
|
seller: deal.seller
|
|
? {
|
|
id: deal.seller.id,
|
|
name: deal.seller.name,
|
|
url: deal.seller.url ?? null,
|
|
}
|
|
: {
|
|
id: -1,
|
|
name: deal.customSeller || "Bilinmiyor",
|
|
url: null,
|
|
},
|
|
|
|
images: (deal.images || []).map((img) => ({
|
|
id: img.id,
|
|
imageUrl: normalizeMediaPath(img.imageUrl) || "",
|
|
order: img.order,
|
|
})),
|
|
|
|
comments: (deal.comments || []).map((comment) => {
|
|
if (!comment.user)
|
|
throw new Error("comment.user is missing (include comments.user in query)")
|
|
|
|
return {
|
|
id: comment.id,
|
|
text: comment.text,
|
|
parentId: comment.parentId ?? null,
|
|
likeCount: Number.isFinite(comment.likeCount) ? comment.likeCount : 0,
|
|
repliesCount: Number.isFinite(comment.repliesCount)
|
|
? comment.repliesCount
|
|
: comment._count?.replies ?? 0,
|
|
hasReplies: Number.isFinite(comment.repliesCount)
|
|
? comment.repliesCount > 0
|
|
: (comment._count?.replies ?? 0) > 0,
|
|
myLike: Boolean(comment.myLike),
|
|
createdAt: requiredIsoString(comment.createdAt, "comment.createdAt"),
|
|
user: {
|
|
id: comment.user.id,
|
|
username: comment.user.username,
|
|
avatarUrl: normalizeMediaPath(comment.user.avatarUrl) ?? null,
|
|
},
|
|
}
|
|
}),
|
|
|
|
breadcrumb: mapBreadcrumbToResponse(deal.breadcrumb),
|
|
|
|
notice: mapNoticeToResponse(firstNotice),
|
|
|
|
similarDeals: Array.isArray(deal.similarDeals)
|
|
? deal.similarDeals.map(mapSimilarDealItem).filter(Boolean)
|
|
: [],
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
mapDealToDealDetailResponse,
|
|
}
|