feat: implement single POST upsert API with automatic ID generation
- Replace separate POST/PUT endpoints with unified POST upsert - Add automatic content ID generation from element context when no ID provided - Implement version history preservation before content updates - Add element context support for backend ID generation - Update frontend to use single endpoint for all content operations - Enhanced demo site with latest database content including proper content IDs
This commit is contained in:
@@ -252,68 +252,6 @@ func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
userID := userInfo.ID
|
||||
|
||||
var content interface{}
|
||||
var err error
|
||||
|
||||
switch h.database.GetDBType() {
|
||||
case "sqlite3":
|
||||
content, err = h.database.GetSQLiteQueries().CreateContent(context.Background(), sqlite.CreateContentParams{
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
Value: req.Value,
|
||||
Type: req.Type,
|
||||
LastEditedBy: userID,
|
||||
})
|
||||
case "postgresql":
|
||||
content, err = h.database.GetPostgreSQLQueries().CreateContent(context.Background(), postgresql.CreateContentParams{
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
Value: req.Value,
|
||||
Type: req.Type,
|
||||
LastEditedBy: userID,
|
||||
})
|
||||
default:
|
||||
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Failed to create content: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
item := h.convertToAPIContent(content)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(item)
|
||||
}
|
||||
|
||||
// UpdateContent handles PUT /api/content/{id} with upsert functionality
|
||||
func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
contentID := vars["id"]
|
||||
siteID := r.URL.Query().Get("site_id")
|
||||
|
||||
if siteID == "" {
|
||||
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var req UpdateContentRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Extract user from request using authentication service
|
||||
userInfo, authErr := h.authService.ExtractUserFromRequest(r)
|
||||
if authErr != nil {
|
||||
http.Error(w, fmt.Sprintf("Authentication error: %v", authErr), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
userID := userInfo.ID
|
||||
|
||||
// Check if content exists for version history (non-blocking)
|
||||
var existingContent interface{}
|
||||
var contentExists bool
|
||||
@@ -350,13 +288,12 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
|
||||
contentType = "text" // default type for new content
|
||||
}
|
||||
|
||||
// Perform upsert operation
|
||||
var upsertedContent interface{}
|
||||
var content interface{}
|
||||
var err error
|
||||
|
||||
switch h.database.GetDBType() {
|
||||
case "sqlite3":
|
||||
upsertedContent, err = h.database.GetSQLiteQueries().UpsertContent(context.Background(), sqlite.UpsertContentParams{
|
||||
content, err = h.database.GetSQLiteQueries().UpsertContent(context.Background(), sqlite.UpsertContentParams{
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
Value: req.Value,
|
||||
@@ -364,7 +301,7 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
|
||||
LastEditedBy: userID,
|
||||
})
|
||||
case "postgresql":
|
||||
upsertedContent, err = h.database.GetPostgreSQLQueries().UpsertContent(context.Background(), postgresql.UpsertContentParams{
|
||||
content, err = h.database.GetPostgreSQLQueries().UpsertContent(context.Background(), postgresql.UpsertContentParams{
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
Value: req.Value,
|
||||
@@ -381,7 +318,7 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
item := h.convertToAPIContent(upsertedContent)
|
||||
item := h.convertToAPIContent(content)
|
||||
|
||||
// Trigger file enhancement if site is registered for auto-enhancement
|
||||
if h.siteManager != nil && h.siteManager.IsAutoEnhanceEnabled(siteID) {
|
||||
@@ -395,6 +332,7 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(item)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,12 +50,6 @@ type CreateContentRequest struct {
|
||||
CreatedBy string `json:"created_by,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateContentRequest struct {
|
||||
Value string `json:"value"`
|
||||
Type string `json:"type,omitempty"`
|
||||
UpdatedBy string `json:"updated_by,omitempty"`
|
||||
}
|
||||
|
||||
type RollbackContentRequest struct {
|
||||
VersionID int64 `json:"version_id"`
|
||||
RolledBackBy string `json:"rolled_back_by,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user