mirror of
https://github.com/samsonjs/spirit-tracker.git
synced 2026-04-27 15:07:43 +00:00
feat: URL and img changes
This commit is contained in:
parent
30bf9ed983
commit
140b73af37
1 changed files with 44 additions and 4 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
// src/tracker/merge.js
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { normalizeCspc } = require("../utils/sku");
|
const { normalizeCspc } = require("../utils/sku");
|
||||||
|
|
@ -10,6 +11,10 @@ function normImg(v) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRealSku(v) {
|
||||||
|
return Boolean(normalizeCspc(v));
|
||||||
|
}
|
||||||
|
|
||||||
function mergeDiscoveredIntoDb(prevDb, discovered) {
|
function mergeDiscoveredIntoDb(prevDb, discovered) {
|
||||||
const merged = new Map(prevDb.byUrl);
|
const merged = new Map(prevDb.byUrl);
|
||||||
|
|
||||||
|
|
@ -18,9 +23,40 @@ function mergeDiscoveredIntoDb(prevDb, discovered) {
|
||||||
const removedItems = [];
|
const removedItems = [];
|
||||||
const restoredItems = [];
|
const restoredItems = [];
|
||||||
|
|
||||||
for (const [url, nowRaw] of discovered.entries()) {
|
// If a product's URL changes but it has a *real* SKU, treat it as the same product:
|
||||||
const prev = prevDb.byUrl.get(url);
|
// update DB entry (and URL key) but do NOT count it as New/Removed.
|
||||||
|
const prevByRealSku = new Map(); // sku6 -> { url, item }
|
||||||
|
for (const [url, it] of prevDb.byUrl.entries()) {
|
||||||
|
if (!it || it.removed) continue;
|
||||||
|
const sku6 = normalizeCspc(it.sku);
|
||||||
|
if (!sku6) continue;
|
||||||
|
// If dup SKUs exist, keep the first one we saw (stable enough).
|
||||||
|
if (!prevByRealSku.has(sku6)) prevByRealSku.set(sku6, { url, item: it });
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchedPrevUrls = new Set(); // old URLs we "found" via SKU even if URL changed
|
||||||
|
|
||||||
|
for (const [url, nowRaw] of discovered.entries()) {
|
||||||
|
let prev = prevDb.byUrl.get(url);
|
||||||
|
let prevUrlForThisItem = url;
|
||||||
|
|
||||||
|
// URL not found in previous DB: try to match by *real* SKU.
|
||||||
|
if (!prev) {
|
||||||
|
const nowSku6 = normalizeCspc(nowRaw.sku);
|
||||||
|
if (nowSku6) {
|
||||||
|
const hit = prevByRealSku.get(nowSku6);
|
||||||
|
if (hit && hit.url && hit.url !== url) {
|
||||||
|
prev = hit.item;
|
||||||
|
prevUrlForThisItem = hit.url;
|
||||||
|
matchedPrevUrls.add(hit.url);
|
||||||
|
|
||||||
|
// Move record key from old URL -> new URL in DB map (no New/Removed noise)
|
||||||
|
if (merged.has(hit.url)) merged.delete(hit.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truly new (no URL match, no real-SKU match)
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
const now = {
|
const now = {
|
||||||
...nowRaw,
|
...nowRaw,
|
||||||
|
|
@ -33,7 +69,9 @@ function mergeDiscoveredIntoDb(prevDb, discovered) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev.removed) {
|
// If the previous record was removed and we found it by the SAME URL, keep current behavior (restored).
|
||||||
|
// Note: if it "came back" under a different URL, we only de-dupe New/Removed for URL changes on active items.
|
||||||
|
if (prevUrlForThisItem === url && prev.removed) {
|
||||||
const now = {
|
const now = {
|
||||||
...nowRaw,
|
...nowRaw,
|
||||||
sku: normalizeCspc(nowRaw.sku) || normalizeCspc(prev.sku),
|
sku: normalizeCspc(nowRaw.sku) || normalizeCspc(prev.sku),
|
||||||
|
|
@ -50,6 +88,7 @@ function mergeDiscoveredIntoDb(prevDb, discovered) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update-in-place (or URL-move-with-real-SKU): update DB, report price changes normally.
|
||||||
const prevPrice = normPrice(prev.price);
|
const prevPrice = normPrice(prev.price);
|
||||||
const nowPrice = normPrice(nowRaw.price);
|
const nowPrice = normPrice(nowRaw.price);
|
||||||
|
|
||||||
|
|
@ -65,7 +104,7 @@ function mergeDiscoveredIntoDb(prevDb, discovered) {
|
||||||
const skuChanged = prevSku !== nowSku;
|
const skuChanged = prevSku !== nowSku;
|
||||||
const imgChanged = prevImg !== nowImg;
|
const imgChanged = prevImg !== nowImg;
|
||||||
|
|
||||||
if (nameChanged || priceChanged || skuChanged || imgChanged) {
|
if (nameChanged || priceChanged || skuChanged || imgChanged || prevUrlForThisItem !== url) {
|
||||||
merged.set(url, { ...nowRaw, sku: nowSku, img: nowImg, removed: false });
|
merged.set(url, { ...nowRaw, sku: nowSku, img: nowImg, removed: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,6 +121,7 @@ function mergeDiscoveredIntoDb(prevDb, discovered) {
|
||||||
|
|
||||||
for (const [url, prev] of prevDb.byUrl.entries()) {
|
for (const [url, prev] of prevDb.byUrl.entries()) {
|
||||||
if (discovered.has(url)) continue;
|
if (discovered.has(url)) continue;
|
||||||
|
if (matchedPrevUrls.has(url)) continue; // de-dupe URL changes for real-SKU items
|
||||||
if (!prev.removed) {
|
if (!prev.removed) {
|
||||||
const removed = { ...prev, removed: true };
|
const removed = { ...prev, removed: true };
|
||||||
merged.set(url, removed);
|
merged.set(url, removed);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue