fix: clean up memo_relation and attachments when deleting memo

Fixes #5472

Move cleanup logic to store.DeleteMemo to ensure data consistency:
- Delete memo_relation records where memo is source (MemoID) or target (RelatedMemoID)
- Delete attachments linked to the memo (including S3/local files)

This prevents stale COMMENT records in memo_relation after deleting
a memo that has comments.
This commit is contained in:
Johnny 2026-01-12 23:18:04 +08:00
parent 6899c2f66a
commit f58533003b
2 changed files with 21 additions and 21 deletions

View File

@ -497,23 +497,7 @@ func (s *APIV1Service) DeleteMemo(ctx context.Context, request *v1pb.DeleteMemoR
}
}
if err = s.Store.DeleteMemo(ctx, &store.DeleteMemo{ID: memo.ID}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete memo")
}
// Delete memo relation
if err := s.Store.DeleteMemoRelation(ctx, &store.DeleteMemoRelation{MemoID: &memo.ID}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete memo relations")
}
// Delete related attachments.
for _, attachment := range attachments {
if err := s.Store.DeleteAttachment(ctx, &store.DeleteAttachment{ID: attachment.ID}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete attachment")
}
}
// Delete memo comments
// Delete memo comments first (store.DeleteMemo handles their relations and attachments)
commentType := store.MemoRelationComment
relations, err := s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{RelatedMemoID: &memo.ID, Type: &commentType})
if err != nil {
@ -525,10 +509,9 @@ func (s *APIV1Service) DeleteMemo(ctx context.Context, request *v1pb.DeleteMemoR
}
}
// Delete memo references
referenceType := store.MemoRelationReference
if err := s.Store.DeleteMemoRelation(ctx, &store.DeleteMemoRelation{RelatedMemoID: &memo.ID, Type: &referenceType}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete memo references")
// Delete the memo (store.DeleteMemo handles relation and attachment cleanup)
if err = s.Store.DeleteMemo(ctx, &store.DeleteMemo{ID: memo.ID}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete memo")
}
return &emptypb.Empty{}, nil

View File

@ -138,5 +138,22 @@ func (s *Store) UpdateMemo(ctx context.Context, update *UpdateMemo) error {
}
func (s *Store) DeleteMemo(ctx context.Context, delete *DeleteMemo) error {
// Clean up memo_relation records where this memo is either the source or target.
if err := s.driver.DeleteMemoRelation(ctx, &DeleteMemoRelation{MemoID: &delete.ID}); err != nil {
return err
}
if err := s.driver.DeleteMemoRelation(ctx, &DeleteMemoRelation{RelatedMemoID: &delete.ID}); err != nil {
return err
}
// Clean up attachments linked to this memo.
attachments, err := s.ListAttachments(ctx, &FindAttachment{MemoID: &delete.ID})
if err != nil {
return err
}
for _, attachment := range attachments {
if err := s.DeleteAttachment(ctx, &DeleteAttachment{ID: attachment.ID}); err != nil {
return err
}
}
return s.driver.DeleteMemo(ctx, delete)
}