feat(conversations): align last seen reads

This commit is contained in:
2026-06-07 11:33:08 +08:00
parent 6b6289f896
commit 5ae2d7fec9
5 changed files with 192 additions and 17 deletions
@@ -930,7 +930,7 @@ func (h *ConversationHandler) UpdateLastSeen(c *gin.Context) {
if !ok {
return
}
svcErr := h.conversationSvc.UpdateLastSeen(c.Request.Context(), accountID, conversation.ID)
svcErr := h.conversationSvc.UpdateLastSeen(c.Request.Context(), accountID, conversation.ID, currentUserID(c))
if svcErr != nil {
handleServiceError(c, svcErr)
return
@@ -50,6 +50,7 @@ type ConversationHandlerTestSuite struct {
testAccount *model.Account
testConv *model.Conversation
testUser *model.User
testInbox *model.Inbox
}
func (s *ConversationHandlerTestSuite) SetupSuite() {
@@ -71,6 +72,7 @@ func (s *ConversationHandlerTestSuite) SetupSuite() {
&model.ConversationParticipant{},
&model.ReportingEvent{},
&model.Message{},
&model.Notification{},
&model.Attachment{},
&model.InboxMember{},
&model.AccountUser{},
@@ -94,6 +96,7 @@ func (s *ConversationHandlerTestSuite) SetupSuite() {
// Create inbox and contact
inbox := &model.Inbox{AccountID: account.ID, Name: "ConvHandlerTestInbox", ChannelType: "web_widget", ChannelID: 1}
s.Require().NoError(db.Create(inbox).Error)
s.testInbox = inbox
s.Require().NoError(db.Create(&model.InboxMember{InboxID: inbox.ID, UserID: user.ID}).Error)
contact := &model.Contact{AccountID: account.ID, Name: "ConvHandlerTestContact"}
@@ -733,6 +736,30 @@ func (s *ConversationHandlerTestSuite) TestToggleTyping_MissingFields() {
assert.Equal(s.T(), http.StatusBadRequest, w.Code)
}
func (s *ConversationHandlerTestSuite) TestUpdateLastSeen_SuccessMarksNotificationRead() {
oldSeen := time.Now().Add(-2 * time.Hour).Unix()
s.Require().NoError(s.db.Model(s.testConv).Update("agent_last_seen_at", oldSeen).Error)
s.Require().NoError(s.db.Create(&model.Message{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ConversationID: s.testConv.ID, MessageType: string(model.MessageTypeIncoming), Content: "new message"}).Error)
accountID := s.testAccount.ID
notification := &model.Notification{UserID: s.testUser.ID, AccountID: &accountID, NotificationType: "assigned_conversation_new_message", PrimaryActorType: "Conversation", PrimaryActorID: s.testConv.ID}
s.Require().NoError(s.db.Create(notification).Error)
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", fmt.Sprintf("/api/v1/accounts/%d/conversations/%d/update_last_seen", s.testAccount.ID, s.testConv.ID), nil)
s.router.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusOK, w.Code)
assert.Empty(s.T(), w.Body.String())
var conversation model.Conversation
s.Require().NoError(s.db.First(&conversation, s.testConv.ID).Error)
s.Require().NotNil(conversation.AgentLastSeenAt)
assert.Greater(s.T(), *conversation.AgentLastSeenAt, oldSeen)
var updatedNotification model.Notification
s.Require().NoError(s.db.First(&updatedNotification, notification.ID).Error)
assert.NotNil(s.T(), updatedNotification.ReadAt)
}
func (s *ConversationHandlerTestSuite) TestUpdateLastSeen_InvalidAccountID() {
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/v1/accounts/abc/conversations/1/update_last_seen", nil)