// routes/deals.js const express = require("express") const router = express.Router() const requireAuth = require("../middleware/requireAuth") const optionalAuth = require("../middleware/optionalAuth") const { upload } = require("../middleware/upload.middleware") const { validate } = require("../middleware/validate.middleware") const { endpoints } = require("@shared/contracts") const userDB = require("../db/user.db") const { getDeals, getDealById, createDeal } = require("../services/deal.service") const { mapCreateDealRequestToDealCreateData } = require("../adapters/requests/dealCreate.adapter") const { mapDealToDealDetailResponse } = require("../adapters/responses/dealDetail.adapter") const { mapPaginatedDealsToDealCardResponse } = require("../adapters/responses/dealCard.adapter") const { deals, users } = endpoints const listQueryValidator = validate(deals.dealsListRequestSchema, "query", "validatedDealListQuery") const buildViewer = (req) => req.auth ? { userId: req.auth.userId, role: req.auth.role } : null function createListHandler(preset) { return async (req, res) => { try { const viewer = buildViewer(req) const { q, page, limit } = req.validatedDealListQuery const payload = await getDeals({ preset, q, page, limit, viewer, }) const response = deals.dealsListResponseSchema.parse( mapPaginatedDealsToDealCardResponse(payload) ) res.json(response) } catch (err) { console.error(err) const status = err.statusCode || 500 res.status(status).json({ error: err.message || "Sunucu hatasi" }) } } } // Public deals of a user (viewer optional; self profile => "MY" else "USER_PUBLIC") router.get( "/users/:userName/deals", optionalAuth, validate(users.userProfileRequestSchema, "params", "validatedUserProfile"), listQueryValidator, async (req, res) => { try { const { userName } = req.validatedUserProfile const targetUser = await userDB.findUser( { username: userName }, { select: { id: true } } ) if (!targetUser) return res.status(404).json({ error: "Kullanici bulunamadi" }) const { q, page, limit } = req.validatedDealListQuery const viewer = buildViewer(req) const isSelfProfile = viewer?.userId === targetUser.id const preset = isSelfProfile ? "MY" : "USER_PUBLIC" const payload = await getDeals({ preset, q, page, limit, targetUserId: targetUser.id, viewer, }) const response = deals.dealsListResponseSchema.parse( mapPaginatedDealsToDealCardResponse(payload) ) res.json(response) } catch (err) { console.error(err) const status = err.statusCode || 500 res.status(status).json({ error: err.message || "Sunucu hatasi" }) } } ) // My deals (auth required) router.get( "/me/deals", requireAuth, listQueryValidator, createListHandler("MY") ) router.get("/new", optionalAuth, listQueryValidator, createListHandler("NEW")) router.get("/hot", optionalAuth, listQueryValidator, createListHandler("HOT")) router.get("/trending", optionalAuth, listQueryValidator, createListHandler("TRENDING")) router.get("/", optionalAuth, listQueryValidator, createListHandler("NEW")) router.get( "/search", optionalAuth, listQueryValidator, async (req, res) => { try { const { q, page, limit } = req.validatedDealListQuery if (!q || !q.trim()) { return res.json({ results: [], total: 0, totalPages: 0, page }) } const payload = await getDeals({ preset: "NEW", q, page, limit, viewer: buildViewer(req), }) const response = deals.dealsListResponseSchema.parse( mapPaginatedDealsToDealCardResponse(payload) ) res.json(response) } catch (err) { console.error(err) const status = err.statusCode || 500 res.status(status).json({ error: err.message || "Sunucu hatasi" }) } } ) // TOP deals (daily/weekly/monthly) - viewer optional router.get("/top", optionalAuth, async (req, res) => { try { const viewer = buildViewer(req) const range = String(req.query.range || "day") const limitRaw = Number(req.query.limit ?? 6) const limit = Number.isFinite(limitRaw) ? Math.max(1, Math.min(20, limitRaw)) : 6 let preset = "HOT_DAY" if (range === "week") preset = "HOT_WEEK" else if (range === "month") preset = "HOT_MONTH" else if (range !== "day") return res.status(400).json({ error: "range invalid" }) const payload = await getDeals({ preset, q: null, page: 1, limit, viewer, }) const response = deals.dealsListResponseSchema.parse( mapPaginatedDealsToDealCardResponse(payload) ) // frontend DealCard[] bekliyor res.json(response.results) } catch (err) { console.error(err) const status = err.statusCode || 500 res.status(status).json({ error: err.message || "Sunucu hatasi" }) } }) router.get( "/:id", validate(deals.dealDetailRequestSchema, "params", "validatedDealId"), async (req, res) => { try { const { id } = req.validatedDealId const deal = await getDealById(id) if (!deal) return res.status(404).json({ error: "Deal bulunamadi" }) const mapped = mapDealToDealDetailResponse(deal) console.log(mapped) res.json(deals.dealDetailResponseSchema.parse(mapped)) } catch (err) { console.error(err) res.status(500).json({ error: "Sunucu hatasi" }) } } ) // Create deal (auth required) router.post( "/", requireAuth, upload.array("images", 5), validate(deals.dealCreateRequestSchema, "body", "validatedDealPayload"), async (req, res) => { try { const userId = req.auth.userId const dealCreateData = mapCreateDealRequestToDealCreateData( req.validatedDealPayload, userId ) const deal = await createDeal(dealCreateData, req.files || []) const mapped = mapDealToDealDetailResponse(deal) res.json(deals.dealCreateResponseSchema.parse(mapped)) } catch (err) { console.error(err) res.status(500).json({ error: "Sunucu hatasi" }) } } ) module.exports = router