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:
@@ -28,36 +28,7 @@ export class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
async updateContent(contentId, content) {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/${contentId}?site_id=${this.siteId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${this.getAuthToken()}`
|
||||
},
|
||||
body: JSON.stringify({ value: content })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
console.log(`✅ Content updated: ${contentId}`);
|
||||
return true;
|
||||
} else {
|
||||
console.warn(`⚠️ Update failed (${response.status}): ${contentId}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
// Provide helpful error message for common development issues
|
||||
if (error.name === 'TypeError' && error.message.includes('fetch')) {
|
||||
console.warn(`🔌 API Server not reachable at ${this.baseUrl}`);
|
||||
console.warn('💡 Start full-stack development: just dev');
|
||||
} else {
|
||||
console.error('Failed to update content:', contentId, error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async createContent(contentId, content, type, elementContext = null) {
|
||||
try {
|
||||
const payload = {
|
||||
|
||||
@@ -102,27 +102,22 @@ export class InsertrEditor {
|
||||
contentValue = formData.text || formData;
|
||||
}
|
||||
|
||||
if (meta.hasExistingId) {
|
||||
// Enhanced site - update existing content
|
||||
const updateSuccess = await this.apiClient.updateContent(meta.contentId, contentValue);
|
||||
if (!updateSuccess) {
|
||||
console.error('❌ Failed to update content:', meta.contentId);
|
||||
} else {
|
||||
console.log(`✅ Content updated:`, meta.contentId, contentValue);
|
||||
}
|
||||
// Universal upsert - works for both new and existing content
|
||||
const contentType = this.determineContentType(meta.element);
|
||||
const result = await this.apiClient.createContent(
|
||||
meta.contentId, // Use existing ID if available, null if new
|
||||
contentValue,
|
||||
contentType,
|
||||
meta.elementContext
|
||||
);
|
||||
|
||||
if (result) {
|
||||
// Store the backend-generated/confirmed ID in the element
|
||||
meta.element.setAttribute('data-content-id', result.id);
|
||||
meta.element.setAttribute('data-content-type', result.type);
|
||||
console.log(`✅ Content saved: ${result.id}`, contentValue);
|
||||
} else {
|
||||
// Non-enhanced site - create with backend ID generation
|
||||
const contentType = this.determineContentType(meta.element);
|
||||
const result = await this.apiClient.createContent(null, contentValue, contentType, meta.elementContext);
|
||||
|
||||
if (result) {
|
||||
// Store the backend-generated ID in the element
|
||||
meta.element.setAttribute('data-content-id', result.id);
|
||||
meta.element.setAttribute('data-content-type', result.type);
|
||||
console.log(`✅ Content created with backend ID: ${result.id}`, contentValue);
|
||||
} else {
|
||||
console.error('❌ Failed to save content to server');
|
||||
}
|
||||
console.error('❌ Failed to save content to server');
|
||||
}
|
||||
|
||||
// Close form
|
||||
|
||||
@@ -106,24 +106,14 @@ export class InsertrCore {
|
||||
getElementMetadata(element) {
|
||||
const existingId = element.getAttribute('data-content-id');
|
||||
|
||||
if (existingId) {
|
||||
// Enhanced site - use existing ID
|
||||
return {
|
||||
contentId: existingId,
|
||||
contentType: element.getAttribute('data-content-type') || this.detectContentType(element),
|
||||
element: element,
|
||||
hasExistingId: true
|
||||
};
|
||||
} else {
|
||||
// Non-enhanced site - prepare context for backend ID generation
|
||||
return {
|
||||
contentId: null, // Backend will generate
|
||||
contentType: this.detectContentType(element),
|
||||
element: element,
|
||||
elementContext: this.extractElementContext(element),
|
||||
hasExistingId: false
|
||||
};
|
||||
}
|
||||
// Always provide both existing ID (if any) and element context
|
||||
// Backend will use existing ID if provided, or generate new one from context
|
||||
return {
|
||||
contentId: existingId, // null if new content, existing ID if updating
|
||||
contentType: element.getAttribute('data-content-type') || this.detectContentType(element),
|
||||
element: element,
|
||||
elementContext: this.extractElementContext(element)
|
||||
};
|
||||
}
|
||||
|
||||
// Extract element context for backend ID generation
|
||||
|
||||
Reference in New Issue
Block a user