feat: logique diff Sheets/Shopify (TDD)
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>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
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 }
|
||||
}
|
||||
Reference in New Issue
Block a user