From 8049b7073823685283c53abc3eb0c28c6cf82beb Mon Sep 17 00:00:00 2001 From: asepharyana Date: Thu, 27 Aug 2026 14:38:05 +0700 Subject: [PATCH] fix: render server nick per user in messages tab and analysis Extract server_nick from metadata.member.displayName in backend messageMapper, add server_nick to frontend MessageRecord type, and update messages view + analysis view to display the member's server-specific nickname (with @username as secondary context) instead of the global username. --- .../backend/src/shared/utils/messageMapper.ts | 20 ++++++++++++++ .../src/app/(dashboard)/analysis/view.tsx | 13 ++++++++-- .../src/app/(dashboard)/messages/view.tsx | 26 ++++++++++++++++--- services/frontend/src/lib/types/message.ts | 2 ++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/services/backend/src/shared/utils/messageMapper.ts b/services/backend/src/shared/utils/messageMapper.ts index d2e08177..9f95f87b 100644 --- a/services/backend/src/shared/utils/messageMapper.ts +++ b/services/backend/src/shared/utils/messageMapper.ts @@ -1,5 +1,22 @@ // Shared message row mapper for backend repository modules +function resolveServerNick(row: Record): string | null { + const metadata = row.metadata; + if (!metadata || typeof metadata !== "string") { + return (row.username as string | null) ?? null; + } + try { + const parsed = JSON.parse(metadata) as { + member?: { displayName?: string | null } | null; + }; + return ( + parsed?.member?.displayName ?? (row.username as string | null) ?? null + ); + } catch { + return (row.username as string | null) ?? null; + } +} + export interface MappedMessage { id: string; guild_id: string; @@ -7,6 +24,8 @@ export interface MappedMessage { thread_id: string | null; user_id: string; username: string; + /** Member's server-specific display name (nickname), from metadata.member.displayName. Falls back to username when absent. */ + server_nick: string | null; avatar_url: string | null; content: string; edited_content: string | null; @@ -42,6 +61,7 @@ export function mapMessageRow(row: Record): MappedMessage { thread_id: (row.thread_id as string | null) ?? null, user_id: String(row.user_id ?? ""), username: String(row.username ?? ""), + server_nick: resolveServerNick(row), avatar_url: (row.avatar_url as string | null) ?? null, content: String(row.content ?? ""), edited_content: (row.edited_content as string | null) ?? null, diff --git a/services/frontend/src/app/(dashboard)/analysis/view.tsx b/services/frontend/src/app/(dashboard)/analysis/view.tsx index 65a8436b..a3457183 100644 --- a/services/frontend/src/app/(dashboard)/analysis/view.tsx +++ b/services/frontend/src/app/(dashboard)/analysis/view.tsx @@ -193,12 +193,21 @@ export function AnalysisView() { key={m.id} className="search-result-card hud-card flex items-start gap-3 p-3 transition-all" > - +
- {m.username} + {m.server_nick ?? m.username} + {m.server_nick && m.server_nick !== m.username && ( + + @{m.username} + + )} {getMessageChannelLabel(m)} diff --git a/services/frontend/src/app/(dashboard)/messages/view.tsx b/services/frontend/src/app/(dashboard)/messages/view.tsx index 61b15ae4..546840b5 100644 --- a/services/frontend/src/app/(dashboard)/messages/view.tsx +++ b/services/frontend/src/app/(dashboard)/messages/view.tsx @@ -564,9 +564,18 @@ function MessageDetail({ return (
- +
-
{m.username}
+
+ {m.server_nick ?? m.username} +
+ {m.server_nick && m.server_nick !== m.username && ( +
@{m.username}
+ )}
{getMessageChannelLabel(m)} ยท {formatRelativeTime(m.created_at)}
@@ -729,12 +738,21 @@ function MessageRow({ : "border-hairline bg-surface-2 hover:border-hairline-focus hover:bg-surface" }`} > - +
- {m.username} + {m.server_nick ?? m.username} + {m.server_nick && m.server_nick !== m.username && ( + + @{m.username} + + )} {getMessageChannelLabel(m)} diff --git a/services/frontend/src/lib/types/message.ts b/services/frontend/src/lib/types/message.ts index b0471fd3..d375fe93 100644 --- a/services/frontend/src/lib/types/message.ts +++ b/services/frontend/src/lib/types/message.ts @@ -109,6 +109,8 @@ export interface MessageRecord { reference_guild_id?: string | null; user_id: string; username: string; + /** Member's server-specific display name (nickname), from metadata.member.displayName. Falls back to username. */ + server_nick?: string | null; avatar_url?: string | null; content: string; edited_content?: string | null;