Add position validation and position-only update support to collection item API

This commit is contained in:
2025-09-23 22:04:54 +02:00
parent 3e5cb76d1d
commit c5754181f6

View File

@@ -1051,23 +1051,122 @@ func (h *ContentHandler) UpdateCollectionItem(w http.ResponseWriter, r *http.Req
var updatedItem interface{} var updatedItem interface{}
var err error var err error
// Validate position bounds if position update is requested
if req.Position > 0 {
var maxPos int64
switch h.database.GetDBType() {
case "sqlite3":
result, err := h.database.GetSQLiteQueries().GetMaxPosition(context.Background(), sqlite.GetMaxPositionParams{
CollectionID: collectionID,
SiteID: siteID,
})
if err != nil {
http.Error(w, "Failed to get max position", http.StatusInternalServerError)
return
}
// Convert interface{} to int64
switch v := result.(type) {
case int64:
maxPos = v
case int:
maxPos = int64(v)
default:
maxPos = 0
}
case "postgresql":
result, err := h.database.GetPostgreSQLQueries().GetMaxPosition(context.Background(), postgresql.GetMaxPositionParams{
CollectionID: collectionID,
SiteID: siteID,
})
if err != nil {
http.Error(w, "Failed to get max position", http.StatusInternalServerError)
return
}
// Convert interface{} to int64
switch v := result.(type) {
case int64:
maxPos = v
case int32:
maxPos = int64(v)
case int:
maxPos = int64(v)
default:
maxPos = 0
}
}
// Check if position is valid (1-based, within bounds)
if int64(req.Position) > maxPos {
http.Error(w, fmt.Sprintf("Invalid position: %d exceeds max position %d", req.Position, maxPos), http.StatusBadRequest)
return
}
}
switch h.database.GetDBType() { switch h.database.GetDBType() {
case "sqlite3": case "sqlite3":
updatedItem, err = h.database.GetSQLiteQueries().UpdateCollectionItem(context.Background(), sqlite.UpdateCollectionItemParams{ // Update position if provided
ItemID: itemID, if req.Position > 0 {
CollectionID: collectionID, err = h.database.GetSQLiteQueries().UpdateCollectionItemPosition(context.Background(), sqlite.UpdateCollectionItemPositionParams{
SiteID: siteID, ItemID: itemID,
HtmlContent: req.HTMLContent, CollectionID: collectionID,
LastEditedBy: req.UpdatedBy, SiteID: siteID,
}) Position: int64(req.Position),
})
if err != nil {
http.Error(w, fmt.Sprintf("Failed to update position: %v", err), http.StatusInternalServerError)
return
}
}
// If only position update (no html_content), just get the updated item
if req.HTMLContent == "" {
updatedItem, err = h.database.GetSQLiteQueries().GetCollectionItem(context.Background(), sqlite.GetCollectionItemParams{
ItemID: itemID,
CollectionID: collectionID,
SiteID: siteID,
})
} else {
// Update content and metadata
updatedItem, err = h.database.GetSQLiteQueries().UpdateCollectionItem(context.Background(), sqlite.UpdateCollectionItemParams{
ItemID: itemID,
CollectionID: collectionID,
SiteID: siteID,
HtmlContent: req.HTMLContent,
LastEditedBy: req.UpdatedBy,
})
}
case "postgresql": case "postgresql":
updatedItem, err = h.database.GetPostgreSQLQueries().UpdateCollectionItem(context.Background(), postgresql.UpdateCollectionItemParams{ // Update position if provided
ItemID: itemID, if req.Position > 0 {
CollectionID: collectionID, err = h.database.GetPostgreSQLQueries().UpdateCollectionItemPosition(context.Background(), postgresql.UpdateCollectionItemPositionParams{
SiteID: siteID, ItemID: itemID,
HtmlContent: req.HTMLContent, CollectionID: collectionID,
LastEditedBy: req.UpdatedBy, SiteID: siteID,
}) Position: int32(req.Position),
})
if err != nil {
http.Error(w, fmt.Sprintf("Failed to update position: %v", err), http.StatusInternalServerError)
return
}
}
// If only position update (no html_content), just get the updated item
if req.HTMLContent == "" {
updatedItem, err = h.database.GetPostgreSQLQueries().GetCollectionItem(context.Background(), postgresql.GetCollectionItemParams{
ItemID: itemID,
CollectionID: collectionID,
SiteID: siteID,
})
} else {
// Update content and metadata
updatedItem, err = h.database.GetPostgreSQLQueries().UpdateCollectionItem(context.Background(), postgresql.UpdateCollectionItemParams{
ItemID: itemID,
CollectionID: collectionID,
SiteID: siteID,
HtmlContent: req.HTMLContent,
LastEditedBy: req.UpdatedBy,
})
}
default: default:
http.Error(w, "Unsupported database type", http.StatusInternalServerError) http.Error(w, "Unsupported database type", http.StatusInternalServerError)
return return