HotTRDealsBackend/services/redis/userModerationCache.service.js
2026-02-07 22:42:02 +00:00

79 lines
2.3 KiB
JavaScript

const { getRedisClient } = require("./client")
const userDb = require("../../db/user.db")
const { recordCacheMiss } = require("./cacheMetrics.service")
const USER_MOD_KEY_PREFIX = "users:moderation:"
const DEFAULT_TTL_SECONDS = 60 * 60
function createRedisClient() {
return getRedisClient()
}
function normalizeUserId(userId) {
const id = Number(userId)
return Number.isInteger(id) && id > 0 ? id : null
}
function normalizeModerationPayload(user) {
const id = normalizeUserId(user?.id)
if (!id) return null
return {
id,
role: user?.role ?? "USER",
mutedUntil: user?.mutedUntil ? new Date(user.mutedUntil).toISOString() : null,
suspendedUntil: user?.suspendedUntil ? new Date(user.suspendedUntil).toISOString() : null,
disabledAt: user?.disabledAt ? new Date(user.disabledAt).toISOString() : null,
}
}
async function getUserModerationFromRedis(userId) {
const id = normalizeUserId(userId)
if (!id) return null
const redis = createRedisClient()
try {
const raw = await redis.call("JSON.GET", `${USER_MOD_KEY_PREFIX}${id}`)
if (!raw) {
await recordCacheMiss({ key: `${USER_MOD_KEY_PREFIX}${id}`, label: "user-mod" })
}
return raw ? JSON.parse(raw) : null
} catch {
return null
} finally {}
}
async function setUserModerationInRedis(user, { ttlSeconds = DEFAULT_TTL_SECONDS } = {}) {
const payload = normalizeModerationPayload(user)
if (!payload) return false
const redis = createRedisClient()
const key = `${USER_MOD_KEY_PREFIX}${payload.id}`
try {
await redis.call("JSON.SET", key, "$", JSON.stringify(payload))
if (ttlSeconds) await redis.expire(key, Number(ttlSeconds))
return true
} catch {
return false
} finally {}
}
async function getOrCacheUserModeration(userId) {
const id = normalizeUserId(userId)
if (!id) return null
const cached = await getUserModerationFromRedis(id)
if (cached) return cached
const user = await userDb.findUser(
{ id },
{ select: { id: true, role: true, mutedUntil: true, suspendedUntil: true, disabledAt: true } }
)
if (!user) return null
await setUserModerationInRedis(user, { ttlSeconds: DEFAULT_TTL_SECONDS })
return normalizeModerationPayload(user)
}
module.exports = {
USER_MOD_KEY_PREFIX,
getUserModerationFromRedis,
setUserModerationInRedis,
getOrCacheUserModeration,
}