feat(feedback): snapshot the sender's language and connector bot at submit

Store the sender's interface language (lang) and, for a message that arrived
through an external connector (Telegram), the bot language (channel_lang) on the
feedback row at submit time, so the operator console shows the state as it was
rather than the account's current settings (same snapshot discipline as a
suspension reason). Added additively in migration 00005. The console detail reads
these columns instead of loading the account live.
This commit is contained in:
Ilia Denisov
2026-06-15 13:25:27 +02:00
parent 49b67a0354
commit 55ed87fb11
8 changed files with 111 additions and 28 deletions
@@ -79,7 +79,8 @@ func (s *Server) consoleFeedbackDetail(c *gin.Context) {
}
view := adminconsole.FeedbackDetailView{
ID: m.ID.String(), AccountID: m.AccountID.String(), SenderName: m.SenderName,
Source: m.Source, Channel: m.Channel, IP: m.SenderIP, Body: m.Body,
Source: m.Source, Channel: m.Channel, InterfaceLanguage: m.Lang, BotLanguage: m.ChannelLang,
IP: m.SenderIP, Body: m.Body,
HasAttachment: m.HasAttachment, AttachmentName: m.AttachmentName, IsImage: feedback.IsImage(m.AttachmentName),
Read: m.Read, Archived: m.Archived, Replied: m.Replied, ReplyBody: m.ReplyBody,
RepliedAt: fmtTime(m.RepliedAt), CreatedAt: fmtTime(m.CreatedAt),
@@ -87,14 +88,6 @@ func (s *Server) consoleFeedbackDetail(c *gin.Context) {
if banned, err := s.accounts.HasRole(ctx, m.AccountID, account.RoleFeedbackBanned); err == nil {
view.Banned = banned
}
if acc, err := s.accounts.GetByID(ctx, m.AccountID); err == nil {
view.InterfaceLanguage = acc.PreferredLanguage
// The connector bot (the account's last service-language bot) is meaningful only
// for a message that arrived through an external connector — currently Telegram.
if m.Channel == "telegram" && acc.ServiceLanguage != "" {
view.BotLanguage = acc.ServiceLanguage
}
}
s.renderConsole(c, "feedback_detail", "feedback", "Feedback", view)
}