Fix AI prompts not refreshing in the frontend after save, some AI tweaks
This commit is contained in:
@@ -1025,60 +1025,87 @@ router.post("/validate", async (req, res) => {
|
||||
Object.keys(aiResponse)
|
||||
);
|
||||
|
||||
// Create a detailed comparison between original and corrected data
|
||||
// Merge AI changes back into original products
|
||||
// AI now only returns changed products and changed fields
|
||||
const mergedProducts = products.map((original, index) => ({ ...original }));
|
||||
const changeDetails = [];
|
||||
|
||||
// Compare original and corrected data
|
||||
if (aiResponse.correctedData) {
|
||||
console.log("📊 Changes summary:");
|
||||
if (aiResponse.correctedData && Array.isArray(aiResponse.correctedData)) {
|
||||
console.log("📊 Processing AI changes - received", aiResponse.correctedData.length, "products with changes");
|
||||
|
||||
// Debug: Log the first product's fields
|
||||
if (products.length > 0) {
|
||||
console.log("🔍 First product fields:", Object.keys(products[0]));
|
||||
}
|
||||
|
||||
products.forEach((original, index) => {
|
||||
const corrected = aiResponse.correctedData[index];
|
||||
if (corrected) {
|
||||
const productChanges = {
|
||||
productIndex: index,
|
||||
title: original.name || original.title || `Product ${index + 1}`,
|
||||
changes: []
|
||||
};
|
||||
|
||||
const changes = Object.keys(corrected).filter(
|
||||
(key) =>
|
||||
JSON.stringify(original[key]) !==
|
||||
JSON.stringify(corrected[key])
|
||||
);
|
||||
|
||||
if (changes.length > 0) {
|
||||
console.log(`\nProduct ${index + 1} changes:`);
|
||||
changes.forEach((key) => {
|
||||
console.log(` ${key}:`);
|
||||
console.log(
|
||||
` - Original: ${JSON.stringify(original[key])}`
|
||||
);
|
||||
console.log(
|
||||
` - Corrected: ${JSON.stringify(corrected[key])}`
|
||||
);
|
||||
|
||||
// Add to our detailed changes array
|
||||
productChanges.changes.push({
|
||||
field: key,
|
||||
original: original[key],
|
||||
corrected: corrected[key]
|
||||
});
|
||||
});
|
||||
|
||||
// Only add products that have changes
|
||||
if (productChanges.changes.length > 0) {
|
||||
changeDetails.push(productChanges);
|
||||
// Process each changed product from AI
|
||||
aiResponse.correctedData.forEach((changedProduct) => {
|
||||
// Find the matching original product using stable identifiers in priority order
|
||||
// Priority: upc > supplier_no > notions_no
|
||||
// These fields should not change during validation
|
||||
const identifiers = ['upc', 'supplier_no', 'notions_no'];
|
||||
let matchedIndex = -1;
|
||||
let matchedBy = null;
|
||||
|
||||
for (const identifier of identifiers) {
|
||||
if (changedProduct[identifier] !== undefined && changedProduct[identifier] !== null && changedProduct[identifier] !== '') {
|
||||
matchedIndex = products.findIndex(
|
||||
(p) => p[identifier] !== undefined &&
|
||||
p[identifier] !== null &&
|
||||
p[identifier] !== '' &&
|
||||
String(p[identifier]).trim() === String(changedProduct[identifier]).trim()
|
||||
);
|
||||
if (matchedIndex !== -1) {
|
||||
matchedBy = identifier;
|
||||
console.log(`✓ Matched product by ${identifier}:`, changedProduct[identifier]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no identifier match found, log an error with details
|
||||
if (matchedIndex === -1) {
|
||||
console.error("❌ Could not match changed product to original. Product identifiers:", {
|
||||
upc: changedProduct.upc,
|
||||
supplier_no: changedProduct.supplier_no,
|
||||
notions_no: changedProduct.notions_no
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const original = products[matchedIndex];
|
||||
const productChanges = {
|
||||
productIndex: matchedIndex,
|
||||
title: original.name || original.title || `Product ${matchedIndex + 1}`,
|
||||
changes: []
|
||||
};
|
||||
|
||||
// Apply each changed field to the merged product
|
||||
Object.keys(changedProduct).forEach((key) => {
|
||||
// Check if the value actually changed
|
||||
if (JSON.stringify(original[key]) !== JSON.stringify(changedProduct[key])) {
|
||||
console.log(`\nProduct ${matchedIndex + 1} - Field ${key}:`);
|
||||
console.log(` - Original: ${JSON.stringify(original[key])}`);
|
||||
console.log(` - Corrected: ${JSON.stringify(changedProduct[key])}`);
|
||||
|
||||
// Apply the change to merged product
|
||||
mergedProducts[matchedIndex][key] = changedProduct[key];
|
||||
|
||||
// Track the change
|
||||
productChanges.changes.push({
|
||||
field: key,
|
||||
original: original[key],
|
||||
corrected: changedProduct[key]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Only add to changeDetails if there were actual changes
|
||||
if (productChanges.changes.length > 0) {
|
||||
changeDetails.push(productChanges);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`📊 Applied changes to ${changeDetails.length} products`);
|
||||
}
|
||||
|
||||
// Replace aiResponse.correctedData with the fully merged product array
|
||||
aiResponse.correctedData = mergedProducts;
|
||||
|
||||
// Record performance metrics after successful validation
|
||||
const endTime = new Date();
|
||||
|
||||
@@ -186,7 +186,7 @@ export const ImageUploadStep = ({
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}, [data, file, onSubmit, productImages]);
|
||||
}, [data, file, onSubmit, productImages, targetEnvironment, useTestDataSource]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-[calc(100vh-9.5rem)] overflow-hidden">
|
||||
|
||||
@@ -134,8 +134,12 @@ export function PromptManagement() {
|
||||
|
||||
return response.json();
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["ai-prompts"] });
|
||||
onSuccess: (newPrompt) => {
|
||||
// Optimistically update the cache with the new prompt
|
||||
queryClient.setQueryData<AiPrompt[]>(["ai-prompts"], (old) => {
|
||||
if (!old) return [newPrompt];
|
||||
return [...old, newPrompt];
|
||||
});
|
||||
toast.success("Prompt created successfully");
|
||||
resetForm();
|
||||
},
|
||||
@@ -163,8 +167,14 @@ export function PromptManagement() {
|
||||
|
||||
return response.json();
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["ai-prompts"] });
|
||||
onSuccess: (updatedPrompt) => {
|
||||
// Optimistically update the cache with the returned data
|
||||
queryClient.setQueryData<AiPrompt[]>(["ai-prompts"], (old) => {
|
||||
if (!old) return [updatedPrompt];
|
||||
return old.map((prompt) =>
|
||||
prompt.id === updatedPrompt.id ? updatedPrompt : prompt
|
||||
);
|
||||
});
|
||||
toast.success("Prompt updated successfully");
|
||||
resetForm();
|
||||
},
|
||||
@@ -181,9 +191,14 @@ export function PromptManagement() {
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete prompt");
|
||||
}
|
||||
return id;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["ai-prompts"] });
|
||||
onSuccess: (deletedId) => {
|
||||
// Optimistically update the cache by removing the deleted prompt
|
||||
queryClient.setQueryData<AiPrompt[]>(["ai-prompts"], (old) => {
|
||||
if (!old) return [];
|
||||
return old.filter((prompt) => prompt.id !== deletedId);
|
||||
});
|
||||
toast.success("Prompt deleted successfully");
|
||||
},
|
||||
onError: (error) => {
|
||||
|
||||
Reference in New Issue
Block a user