Implement atomic collection item creation API with unified content engine approach

Updates collection creation to use database-first atomic operations for reliable collection item management. Replaces manual database calls with unified content engine methods that handle content extraction, storage, and structural template generation consistently.

Key changes:
- Replace manual database operations in CreateCollectionItem handler with DatabaseClient.CreateCollectionItemAtomic()
- Implement unified content engine approach for API-based collection item creation
- Add atomic collection item creation methods across all content clients
- Enhance reconstruction to use stored structural templates with content ID hydration
- Add comprehensive collection management API methods in JavaScript client
- Implement collection manager UI with create, delete, and reorder functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-23 18:39:37 +02:00
parent 5f494b8aa8
commit 1ae4176f23
8 changed files with 755 additions and 202 deletions

View File

@@ -1004,45 +1004,37 @@ func (h *ContentHandler) CreateCollectionItem(w http.ResponseWriter, r *http.Req
if req.CollectionID == "" {
req.CollectionID = collectionID
}
// Generate item ID
itemID := fmt.Sprintf("%s-item-%d", collectionID, time.Now().Unix())
var createdItem interface{}
var err error
switch h.database.GetDBType() {
case "sqlite3":
createdItem, err = h.database.GetSQLiteQueries().CreateCollectionItem(context.Background(), sqlite.CreateCollectionItemParams{
ItemID: itemID,
CollectionID: req.CollectionID,
SiteID: req.SiteID,
TemplateID: int64(req.TemplateID),
HtmlContent: req.HTMLContent,
Position: int64(req.Position),
LastEditedBy: req.CreatedBy,
})
case "postgresql":
createdItem, err = h.database.GetPostgreSQLQueries().CreateCollectionItem(context.Background(), postgresql.CreateCollectionItemParams{
ItemID: itemID,
CollectionID: req.CollectionID,
SiteID: req.SiteID,
TemplateID: int32(req.TemplateID),
HtmlContent: req.HTMLContent,
Position: int32(req.Position),
LastEditedBy: req.CreatedBy,
})
default:
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
return
if req.TemplateID == 0 {
req.TemplateID = 1 // Default to first template
}
// Create database client for atomic operations
dbClient := engine.NewDatabaseClient(h.database)
// Use atomic collection item creation
createdItem, err := dbClient.CreateCollectionItemAtomic(
req.SiteID,
req.CollectionID,
req.TemplateID,
req.CreatedBy,
)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to create collection item: %v", err), http.StatusInternalServerError)
return
}
apiItem := h.convertToAPICollectionItem(createdItem)
// Convert to API response format
apiItem := CollectionItemData{
ItemID: createdItem.ItemID,
CollectionID: createdItem.CollectionID,
SiteID: createdItem.SiteID,
TemplateID: createdItem.TemplateID,
HTMLContent: createdItem.HTMLContent,
Position: createdItem.Position,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
LastEditedBy: createdItem.LastEditedBy,
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)