// services/user.service.js const userDB = require("../db/user.db") const dealDB = require("../db/deal.db") const commentDB = require("../db/comment.db") const dealService = require("./deal.service") const PROFILE_PAGE_SIZE = 15 function normalizePage(value) { const num = Number(value) if (!Number.isInteger(num) || num < 1) return 1 return num } function buildPagination({ page, total, limit }) { const safeTotal = Number.isFinite(total) ? Math.max(0, total) : 0 const safeLimit = Number.isFinite(limit) && limit > 0 ? Math.floor(limit) : PROFILE_PAGE_SIZE return { page, total: safeTotal, totalPages: safeTotal === 0 ? 0 : Math.ceil(safeTotal / safeLimit), limit: safeLimit, } } async function getUserProfileByUsername(userName) { const username = String(userName).trim() if (!username) throw new Error("username zorunlu") const user = await userDB.findUser( { username }, { select: { id: true, username: true, email: true, avatarUrl: true, createdAt: true, userBadges: { orderBy: { earnedAt: "desc" }, select: { earnedAt: true, badge: { select: { id: true, name: true, iconUrl: true, description: true } }, }, }, }, } ) if (!user) { const err = new Error("Kullanıcı bulunamadı.") err.statusCode = 404 throw err } const commentsPage = 1 const dealsPage = 1 const [dealAgg, totalComments, comments, userDeals] = await Promise.all([ dealDB.aggregateDeals({ userId: user.id, status: { in: ["ACTIVE", "EXPIRED"] } }), commentDB.countComments({ userId: user.id }), commentDB.findComments( { userId: user.id }, { orderBy: { createdAt: "desc" }, skip: (commentsPage - 1) * PROFILE_PAGE_SIZE, take: PROFILE_PAGE_SIZE, include: { user: { select: { id: true, username: true, avatarUrl: true } }, deal: { select: { id: true, title: true } }, }, } ), dealService.getDeals({ preset: "USER_PUBLIC", targetUserId: user.id, viewer: null, page: dealsPage, limit: PROFILE_PAGE_SIZE, }), ]) const totalDeals = dealAgg?._count?._all ?? 0 const stats = { totalLikes: dealAgg?._sum?.score ?? 0, totalComments: totalComments ?? 0, totalShares: totalDeals, totalDeals, } return { user, stats, deals: userDeals.results, comments, badges: user.userBadges || [], dealsPagination: buildPagination({ page: userDeals.page ?? dealsPage, total: userDeals.total ?? 0, limit: PROFILE_PAGE_SIZE, }), commentsPagination: buildPagination({ page: commentsPage, total: totalComments ?? 0, limit: PROFILE_PAGE_SIZE, }), } } async function getUserCommentsByUsername(userName, { page = 1, limit = PROFILE_PAGE_SIZE } = {}) { const username = String(userName).trim() if (!username) throw new Error("username zorunlu") const user = await userDB.findUser( { username }, { select: { id: true } } ) if (!user) { const err = new Error("Kullanici bulunamadi.") err.statusCode = 404 throw err } const safePage = normalizePage(page) const safeLimit = PROFILE_PAGE_SIZE const skip = (safePage - 1) * safeLimit const [total, results] = await Promise.all([ commentDB.countComments({ userId: user.id }), commentDB.findComments( { userId: user.id }, { orderBy: { createdAt: "desc" }, skip, take: safeLimit, include: { user: { select: { id: true, username: true, avatarUrl: true } }, deal: { select: { id: true, title: true } }, }, } ), ]) return { page: safePage, total: total ?? 0, totalPages: total ? Math.ceil(total / safeLimit) : 0, limit: safeLimit, results, } } async function getUserDealsByUsername(userName, { page = 1, limit = PROFILE_PAGE_SIZE, viewer = null } = {}) { const username = String(userName).trim() if (!username) throw new Error("username zorunlu") const user = await userDB.findUser( { username }, { select: { id: true } } ) if (!user) { const err = new Error("Kullanici bulunamadi.") err.statusCode = 404 throw err } const safePage = normalizePage(page) const safeLimit = PROFILE_PAGE_SIZE const isSelfProfile = viewer?.userId && Number(viewer.userId) === Number(user.id) const preset = isSelfProfile ? "MY" : "USER_PUBLIC" const payload = await dealService.getDeals({ preset, targetUserId: user.id, viewer, page: safePage, limit: safeLimit, }) return { page: payload.page ?? safePage, total: payload.total ?? 0, totalPages: payload.totalPages ?? 0, limit: safeLimit, results: payload.results ?? [], } } module.exports = { getUserProfileByUsername, getUserCommentsByUsername, getUserDealsByUsername, }