From 3c3382a3c652bed3b58058931ff3cbf1d875b9a8 Mon Sep 17 00:00:00 2001 From: boojack Date: Sat, 16 May 2026 21:18:44 +0800 Subject: [PATCH] fix: avoid update event on memo create attachments (#5961) --- server/router/api/v1/memo_service.go | 12 ++----- server/router/api/v1/sse_service_test.go | 42 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/server/router/api/v1/memo_service.go b/server/router/api/v1/memo_service.go index 086cb6b7a..0a544ddb6 100644 --- a/server/router/api/v1/memo_service.go +++ b/server/router/api/v1/memo_service.go @@ -130,11 +130,7 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR attachments := []*store.Attachment{} if len(request.Memo.Attachments) > 0 { - _, err := s.SetMemoAttachments(ctx, &v1pb.SetMemoAttachmentsRequest{ - Name: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID), - Attachments: request.Memo.Attachments, - }) - if err != nil { + if err := s.setMemoAttachmentsInternal(ctx, user, memo, request.Memo.Attachments); err != nil { return nil, errors.Wrap(err, "failed to set memo attachments") } @@ -147,11 +143,7 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR attachments = a } if len(request.Memo.Relations) > 0 { - _, err := s.SetMemoRelations(ctx, &v1pb.SetMemoRelationsRequest{ - Name: fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID), - Relations: request.Memo.Relations, - }) - if err != nil { + if err := s.setMemoRelationsInternal(ctx, memo, request.Memo.Relations); err != nil { return nil, errors.Wrap(err, "failed to set memo relations") } } diff --git a/server/router/api/v1/sse_service_test.go b/server/router/api/v1/sse_service_test.go index 689a35b31..f7910bcbe 100644 --- a/server/router/api/v1/sse_service_test.go +++ b/server/router/api/v1/sse_service_test.go @@ -113,6 +113,48 @@ func TestCreateMemoComment_NoDuplicateSSEBroadcast(t *testing.T) { "expected memo.comment.created, got: %s", events[0]) } +func TestCreateMemoWithAttachment_NoDuplicateUpdatedSSEBroadcast(t *testing.T) { + ctx := context.Background() + svc := newIntegrationService(t) + + user, err := svc.Store.CreateUser(ctx, &store.User{ + Username: "user", Role: store.RoleAdmin, Email: "user@example.com", + }) + require.NoError(t, err) + uctx := userCtx(ctx, user.ID) + + attachment, err := svc.CreateAttachment(uctx, &v1pb.CreateAttachmentRequest{ + Attachment: &v1pb.Attachment{ + Filename: "test.txt", + Size: 5, + Type: "text/plain", + Content: []byte("hello"), + }, + }) + require.NoError(t, err) + + client := svc.SSEHub.Subscribe(user.ID, store.RoleAdmin) + defer svc.SSEHub.Unsubscribe(client) + + memo, err := svc.CreateMemo(uctx, &v1pb.CreateMemoRequest{ + Memo: &v1pb.Memo{ + Content: "memo with initial attachment", + Visibility: v1pb.Visibility_PUBLIC, + Attachments: []*v1pb.Attachment{ + {Name: attachment.Name}, + }, + }, + }) + require.NoError(t, err) + + events := collectEventsFor(client.events, 150*time.Millisecond) + + require.Len(t, events, 1, "expected exactly one SSE event for memo creation with attachment, got: %v", events) + assert.Contains(t, events[0], `"memo.created"`) + assert.Contains(t, events[0], memo.Name) + assert.NotContains(t, events[0], `"memo.updated"`) +} + // ---- Reaction SSE events carry correct visibility / parent fields ---- func TestUpsertMemoReaction_SSEEvent(t *testing.T) {