const { updateDealVoteInRedis } = require("./redis/dealVote.service"); const { queueVoteUpdate, queueDealUpdate, queueNotificationCreate } = require("./redis/dbSync.service"); const { updateDealInRedis, getDealFromRedis } = require("./redis/dealCache.service"); const { publishNotification } = require("./redis/notificationPubsub.service"); async function voteDeal({ dealId, userId, voteType }) { if (!dealId || !userId || voteType === undefined) { const err = new Error("Eksik veri"); err.statusCode = 400; throw err; } if (![ -1, 0, 1 ].includes(voteType)) { const err = new Error("voteType -1, 0 veya 1 olmalı"); err.statusCode = 400; throw err; } const deal = await getDealFromRedis(Number(dealId)); if (!deal || !["ACTIVE", "EXPIRED"].includes(deal.status)) { const err = new Error("deal sadece ACTIVE veya EXPIRED iken oylanabilir"); err.statusCode = 400; throw err; } const createdAt = new Date(); const redisResult = await updateDealVoteInRedis({ dealId, userId, voteType, }).catch((err) => { console.error("Redis vote update failed:", err?.message || err); return { updated: false, delta: 0, score: null, maxNotifiedMilestone: 0, dealUserId: null }; }); queueVoteUpdate({ dealId, userId, voteType, createdAt: createdAt.toISOString(), }).catch((err) => console.error("DB sync vote queue failed:", err?.message || err)); const scoreVal = Number(redisResult?.score) const maxNotified = Number(redisResult?.maxNotifiedMilestone ?? 0) const ownerId = Number(redisResult?.dealUserId) if (Number.isFinite(scoreVal) && Number.isInteger(ownerId) && ownerId > 0) { const milestone = 100 if (scoreVal >= milestone && maxNotified < milestone) { const updatedAt = new Date() await updateDealInRedis(dealId, { maxNotifiedMilestone: milestone }, { updatedAt }).catch((err) => console.error("Redis deal milestone update failed:", err?.message || err) ) queueDealUpdate({ dealId, data: { maxNotifiedMilestone: milestone }, updatedAt: updatedAt.toISOString(), }).catch((err) => console.error("DB sync deal milestone update failed:", err?.message || err)) queueNotificationCreate({ userId: ownerId, message: "Fırsatın 100 beğeniyi geçti!", type: "MILESTONE", createdAt: updatedAt.toISOString(), }).catch((err) => console.error("DB sync notification queue failed:", err?.message || err)) publishNotification({ userId: ownerId, message: "Fırsatın 100 beğeniyi geçti!", type: "MILESTONE", createdAt: updatedAt.toISOString(), }).catch((err) => console.error("Notification publish failed:", err?.message || err)) } } // Fallback: Redis yoksa mevcut DB'den approx hesapla let delta = redisResult?.delta ?? 0; let score = redisResult?.score ?? null; if (score === null) { const current = await getDealFromRedis(Number(dealId)); score = current ? Number(current?.score ?? 0) : null; delta = 0; } return { dealId, voteType, delta, score, }; } async function getVotes(dealId) { const votes = await voteDb.findVotes( { dealId }, { select: { id: true, dealId: true, userId: true, voteType: true, createdAt: true, lastVotedAt: true, }, orderBy: { createdAt: "desc" }, } ) return votes.map((vote) => ({ ...vote, createdAt: vote.createdAt.toISOString(), lastVotedAt: vote.lastVotedAt.toISOString(), })) } module.exports = { voteDeal, getVotes };