2988ecab0b
Implémentation de la fonction pure computeDiff pour calculer les changements entre les produits Google Sheets et Shopify, avec distinction des opérations (create, update, deactivate, unchanged) et traçabilité des champs modifiés. - Matching par handle (ref normalisée) - Comparaison des champs: title, description, price, status - Draft products Shopify non synchronisés ne sont pas déactivés - Tests TDD: 9 cas couverts (empty, create, unchanged, update, deactivate) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import type { SyncProduct, ShopifyProductFull, SyncChange, DiffResult } from '@/types/sync'
|
|
|
|
const COMPARABLE_FIELDS = ['title', 'description', 'price', 'status'] as const
|
|
|
|
function getChangedFields(
|
|
sheet: SyncProduct,
|
|
shopify: ShopifyProductFull,
|
|
): Array<{ field: string; from: string; to: string }> {
|
|
return COMPARABLE_FIELDS
|
|
.filter((field) => sheet[field] !== shopify[field])
|
|
.map((field) => ({
|
|
field,
|
|
from: String(shopify[field]),
|
|
to: String(sheet[field]),
|
|
}))
|
|
}
|
|
|
|
/**
|
|
* Calcule le diff entre les produits Sheets et Shopify.
|
|
* Matching par handle (ref normalisée).
|
|
*/
|
|
export function computeDiff(
|
|
sheetProducts: SyncProduct[],
|
|
shopifyProducts: ShopifyProductFull[],
|
|
): DiffResult {
|
|
const shopifyMap = new Map(shopifyProducts.map((p) => [p.handle, p]))
|
|
const sheetHandles = new Set(sheetProducts.map((p) => p.handle))
|
|
|
|
const changes: SyncChange[] = []
|
|
|
|
for (const sheet of sheetProducts) {
|
|
const shopify = shopifyMap.get(sheet.handle)
|
|
if (!shopify) {
|
|
changes.push({ type: 'create', ref: sheet.ref, sheetProduct: sheet })
|
|
} else {
|
|
const changedFields = getChangedFields(sheet, shopify)
|
|
if (changedFields.length > 0) {
|
|
changes.push({
|
|
type: 'update',
|
|
ref: sheet.ref,
|
|
sheetProduct: sheet,
|
|
shopifyProduct: shopify,
|
|
changedFields,
|
|
})
|
|
} else {
|
|
changes.push({ type: 'unchanged', ref: sheet.ref, sheetProduct: sheet, shopifyProduct: shopify })
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const shopify of shopifyProducts) {
|
|
if (shopify.status === 'active' && !sheetHandles.has(shopify.handle)) {
|
|
changes.push({ type: 'deactivate', ref: shopify.ref, shopifyProduct: shopify })
|
|
}
|
|
}
|
|
|
|
const summary = {
|
|
create: changes.filter((c) => c.type === 'create').length,
|
|
update: changes.filter((c) => c.type === 'update').length,
|
|
deactivate: changes.filter((c) => c.type === 'deactivate').length,
|
|
unchanged: changes.filter((c) => c.type === 'unchanged').length,
|
|
}
|
|
|
|
return { changes, summary }
|
|
}
|