From cb46cd310fd99e35ba63417806062a5f4e910ae3 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Thu, 5 Mar 2026 00:42:52 -0500 Subject: [PATCH] feat(collections): add WebSocket broadcast on RemoveBook operation Add real-time synchronization for collection book removal: - Extract user ID from context for targeted broadcasts - Broadcast 'collection_updated' message to user's other devices - Includes collection_id, action, and book_id in message payload This ensures that when a user removes a book from a collection, all their connected devices (browser tabs, mobile apps, etc.) receive real-time updates via WebSocket. Consistent with existing AddBooks and BulkRemoveBooks operations which already use BroadcastToUser for synchronization. --- internal/handlers/collections.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/internal/handlers/collections.go b/internal/handlers/collections.go index 084bb14..2a1ec7e 100644 --- a/internal/handlers/collections.go +++ b/internal/handlers/collections.go @@ -356,11 +356,28 @@ func (h *CollectionHandler) RemoveBook(c echo.Context) error { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid book id"}) } + // Get user from context for WebSocket broadcast + user := c.Get("user").(database.Users) + userUUID := uuid.UUID(user.ID.Bytes) + err = h.collectionService.RemoveBookFromCollection(c.Request().Context(), collectionID, bookID) if err != nil { return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } + // Broadcast to user's other devices via WebSocket + if h.connManager != nil { + h.connManager.BroadcastToUser(userUUID.String(), wsync.BroadcastMessage{ + Type: "collection_updated", + Timestamp: time.Now().Format(time.RFC3339), + Data: map[string]interface{}{ + "collection_id": collectionID.String(), + "action": "book_removed", + "book_id": bookID.String(), + }, + }) + } + return c.NoContent(http.StatusNoContent) }