backend: expand bookmark API with bulk ops and metadata fetcher
- bulk create/delete/move, reorder, rename-category endpoints - /bookmarks/meta with SSRF-safe fetcher (blocks private/loopback IPs, 8s timeout, 1 MiB body cap) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,13 @@ func (r *BookmarkRepository) Create(bm *domain.Bookmark) error {
|
||||
return r.db.Create(bm).Error
|
||||
}
|
||||
|
||||
func (r *BookmarkRepository) BulkCreate(bms []*domain.Bookmark) error {
|
||||
if len(bms) == 0 {
|
||||
return nil
|
||||
}
|
||||
return r.db.Create(&bms).Error
|
||||
}
|
||||
|
||||
func (r *BookmarkRepository) FindByID(id uint) (*domain.Bookmark, error) {
|
||||
var bm domain.Bookmark
|
||||
err := r.db.First(&bm, id).Error
|
||||
@@ -49,3 +56,40 @@ func (r *BookmarkRepository) Update(bm *domain.Bookmark) error {
|
||||
func (r *BookmarkRepository) Delete(id uint) error {
|
||||
return r.db.Delete(&domain.Bookmark{}, id).Error
|
||||
}
|
||||
|
||||
func (r *BookmarkRepository) BulkDeleteByUser(userID uint, ids []uint) (int64, error) {
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
res := r.db.Where("user_id = ? AND id IN ?", userID, ids).Delete(&domain.Bookmark{})
|
||||
return res.RowsAffected, res.Error
|
||||
}
|
||||
|
||||
func (r *BookmarkRepository) BulkUpdateCategoryByUser(userID uint, ids []uint, category string) (int64, error) {
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
res := r.db.Model(&domain.Bookmark{}).Where("user_id = ? AND id IN ?", userID, ids).Update("category", category)
|
||||
return res.RowsAffected, res.Error
|
||||
}
|
||||
|
||||
func (r *BookmarkRepository) RenameCategoryByUser(userID uint, from, to string) (int64, error) {
|
||||
res := r.db.Model(&domain.Bookmark{}).Where("user_id = ? AND category = ?", userID, from).Update("category", to)
|
||||
return res.RowsAffected, res.Error
|
||||
}
|
||||
|
||||
func (r *BookmarkRepository) ReorderByUser(userID uint, orderedIDs []uint) error {
|
||||
if len(orderedIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
for i, id := range orderedIDs {
|
||||
if err := tx.Model(&domain.Bookmark{}).
|
||||
Where("id = ? AND user_id = ?", id, userID).
|
||||
Update("sort_order", i).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user