From bda8304bb936d6b6d5ad0dd1ab7bfa8ce034f46e Mon Sep 17 00:00:00 2001 From: MythEclipse Date: Mon, 1 Jun 2026 19:23:46 +0700 Subject: [PATCH] fix(analytics): align flag counts and violation score math - Count only flagged messages in the active users Flag column - Coerce PostgreSQL count results to numbers before calculating violation_score - Prevent string concatenation in flagged*3 + warned scoring Co-Authored-By: Claude Opus 4.8 --- src/moderation/analyticsStore.ts | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/moderation/analyticsStore.ts b/src/moderation/analyticsStore.ts index 925374b..20c129e 100644 --- a/src/moderation/analyticsStore.ts +++ b/src/moderation/analyticsStore.ts @@ -483,7 +483,7 @@ export async function getUserLeaderboard(input: { count(*) as message_count, count(case when type = 'edited' then 1 end) as edited_count, count(case when type = 'deleted' then 1 end) as deleted_count, - count(case when ai_status in ('flagged', 'warn') then 1 end) as flagged_count, + count(case when ai_status = 'flagged' then 1 end) as flagged_count, max(created_at) as last_active FROM messages WHERE guild_id = ? @@ -682,17 +682,21 @@ export async function getTopViolators(input: { : [guildId, since, limit], ); - const violators: ViolatorStat[] = rows.map((row: any) => ({ - user_id: row.user_id, - username: row.username, - avatar_url: row.avatar_url, - total_messages: row.total_messages, - flagged_count: row.flagged_count, - warned_count: row.warned_count, - violation_score: row.flagged_count * 3 + row.warned_count, - worst_flags: [], - last_violation: row.last_violation, - })); + const violators: ViolatorStat[] = rows.map((row: any) => { + const flaggedCount = Number(row.flagged_count ?? 0); + const warnedCount = Number(row.warned_count ?? 0); + return { + user_id: row.user_id, + username: row.username, + avatar_url: row.avatar_url, + total_messages: Number(row.total_messages ?? 0), + flagged_count: flaggedCount, + warned_count: warnedCount, + violation_score: flaggedCount * 3 + warnedCount, + worst_flags: [], + last_violation: Number(row.last_violation ?? 0), + }; + }); setCache(cacheKey, violators, AGGREGATE_CACHE_TTL_MS); return violators;