HotTRDealsBackend/routes/seller.routes.js
2026-02-07 22:42:02 +00:00

125 lines
4.3 KiB
JavaScript

const express = require("express")
const router = express.Router()
const requireAuth = require("../middleware/requireAuth")
const optionalAuth = require("../middleware/optionalAuth")
const { validate } = require("../middleware/validate.middleware")
const { endpoints } = require("@shared/contracts")
const { getSellerByName, getDealsBySellerName, getActiveSellers } = require("../services/seller.service")
const { findSellerFromLink } = require("../services/sellerLookup.service")
const { getProductPreviewFromUrl } = require("../services/productPreview.service")
const { setBarcodeForUrl } = require("../services/redis/linkPreviewCache.service")
const { cacheLinkPreviewImages } = require("../services/linkPreviewImage.service")
const { mapSellerToSellerDetailsResponse } = require("../adapters/responses/sellerDetails.adapter")
const { mapPaginatedDealsToDealCardResponse } = require("../adapters/responses/dealCard.adapter")
const { getClientIp } = require("../utils/requestInfo")
const { queueDealImpressions } = require("../services/redis/dealAnalytics.service")
const { seller, deals } = endpoints
const buildViewer = (req) =>
req.auth ? { userId: req.auth.userId, role: req.auth.role } : null
const listQueryValidator = validate(deals.dealsListRequestSchema, "query", "validatedDealListQuery")
router.post("/from-link", requireAuth, async (req, res) => {
try {
const sellerUrl = req.body.url
if (!sellerUrl) return res.status(400).json({ error: "url parametresi zorunlu" })
const [sellerLookup, initialProduct] = await Promise.all([
findSellerFromLink(sellerUrl),
getProductPreviewFromUrl(sellerUrl),
])
let product = initialProduct
if (product?.barcodeId) {
setBarcodeForUrl(sellerUrl, product.barcodeId, { ttlSeconds: 15 * 60 }).catch((err) =>
console.error("Link preview barcode cache failed:", err?.message || err)
)
}
const baseUrl = `${req.protocol}://${req.get("host")}`
if (product && baseUrl) {
const cached = await cacheLinkPreviewImages({ product, baseUrl })
product = cached.product
}
const response = seller.sellerLookupResponseSchema.parse(
sellerLookup
? {
found: true,
seller: {
id: sellerLookup.id,
name: sellerLookup.name,
url: sellerLookup.url ?? null,
},
product,
}
: { found: false, seller: null, product }
)
return res.json(response)
} catch (e) {
console.error(e)
res.status(500).json({ error: "Sunucu hatasi" })
}
})
router.get("/", async (req, res) => {
try {
const sellers = await getActiveSellers()
res.json(sellers)
} catch (e) {
const status = e.statusCode || 500
res.status(status).json({ error: e.message || "Sunucu hatasi" })
}
})
router.get("/:sellerName", async (req, res) => {
try {
const sellerName = req.params.sellerName
const sellerInfo = await getSellerByName(sellerName)
if (!sellerInfo) return res.status(404).json({ error: "Seller bulunamadi" })
res.json(mapSellerToSellerDetailsResponse(sellerInfo))
} catch (e) {
const status = e.statusCode || 500
res.status(status).json({ error: e.message || "Sunucu hatasi" })
}
})
router.get("/:sellerName/deals", optionalAuth, listQueryValidator, async (req, res) => {
try {
const sellerName = req.params.sellerName
const { q, page, limit } = req.validatedDealListQuery
const { payload } = await getDealsBySellerName(sellerName, {
page,
limit,
filters: req.query,
viewer: buildViewer(req),
})
const response = mapPaginatedDealsToDealCardResponse(payload)
const dealIds = payload?.results?.map((deal) => deal.id) || []
queueDealImpressions({
dealIds,
userId: req.auth?.userId ?? null,
ip: getClientIp(req),
}).catch((err) => console.error("Deal impression queue failed:", err?.message || err))
res.json({
page: response.page,
total: response.total,
totalPages: response.totalPages,
results: response.results,
minPrice: payload?.minPrice ?? null,
maxPrice: payload?.maxPrice ?? null,
})
} catch (e) {
const status = e.statusCode || 500
res.status(status).json({ error: e.message || "Sunucu hatasi" })
}
})
module.exports = router