79 lines
2.3 KiB
JavaScript
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,
|
|
}
|