From 2e01b9df0bee1310887909a9c01fa7d010d64eae Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Thu, 29 Oct 2026 02:44:37 +0700 Subject: [PATCH 1/2] =?UTF-8?q?fix(normalizer):=20a=20size=20before=20"n?= =?UTF-8?q?=C4=83m=20"=20is=20kept;=20dates,=20ram,=20macos=20names?= =?UTF-8?q?=20and=20amounts=20are=20no=20size?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../__tests__/open-core-intelligence.test.ts | 20 +++++++++++++++++++ .../importer/src/shopee/product-normalizer.ts | 14 ++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts b/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts index 56589a7ea..c65cefe48 100644 --- a/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts +++ b/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts @@ -477,6 +477,25 @@ async function runSuite() { ['MacBook Air M2 8GB 256GB bảo hành 15 tháng', 'apple:macbook-air-m2:256gb'], ['MacBook Pro M3 18GB 512GB bảo hành 14 tháng', 'apple:macbook-pro-m3:512gb'], ['MacBook Air M2 8GB 256GB 15 gói quà', 'apple:macbook-air-m2:256gb'], + // " năm " names the size and the year (DOS/Rate#1317); a "năm" + // with no year after it is a duration. + ['Máy tính bảng Apple iPad Pro 11 năm 2022 M2 128GB Wifi', 'apple:ipad-pro-m2-11:128gb'], + ['Laptop Apple MacBook Pro 14 năm 2023 M3 8GB 512GB', 'apple:macbook-pro-m3-14:512gb'], + ['MacBook Air 13 năm 2022 M2 8GB 256GB', 'apple:macbook-air-m2-13:256gb'], + ['MacBook Air 15 năm 2023 M2 8GB 256GB', 'apple:macbook-air-m2-15:256gb'], + ['iPad Air 11 năm 2024 M2 128GB', 'apple:ipad-air-m2-11:128gb'], + ['iPad Pro 12.9 năm 2022 M2 128GB', 'apple:ipad-pro-m2-129:128gb'], + ['MacBook Air M2 13 năm', 'apple:macbook-air-m2:unknown'], + // A date ("11/11"), RAM or SSD, a macOS name, a duration or an amount is no + // size, so the gift's size still stands in. + ['iPad Pro M4 Sale 11/11 tặng ốp 13 inch', 'apple:ipad-pro-m4-13:unknown'], + ['MacBook Pro M3 16 RAM 512 SSD tặng túi 14 inch', 'apple:macbook-pro-m3-14:unknown'], + ['MacBook Air M3 macOS Sonoma 14 tặng túi 13 inch', 'apple:macbook-air-m3-13:unknown'], + ['iPad Air M2 BH 12 months tặng ốp 11 inch', 'apple:ipad-air-m2-11:unknown'], + // A bare gift number is the gift's: the product's own size after it wins. + ['iPad Pro M4 tặng ốp 11 | 13 WiFi', 'apple:ipad-pro-m4-13:unknown'], + ['iPad Pro M4 13 tặng ốp 11 tặng bút', 'apple:ipad-pro-m4-13:unknown'], + ['iPad Pro M4 tặng ốp 11 tặng bút', 'apple:ipad-pro-m4-11:unknown'], // A number after "cho/for" (a school year, an age) is no size of the product. [ 'iPad Pro M4 Wifi 256GB tặng bao da 13 inch cho học sinh lớp 11', @@ -735,6 +754,7 @@ async function runSuite() { ['Apple Watch Series 10 GPS tặng ốp 42mm / 46mm', 'apple:watch-series-10:64gb'], ['Apple Watch Series 10 GPS 46 tặng ốp 42mm', 'apple:watch-series-10:64gb'], ['Apple Watch Series 10 GPS giảm 40% tặng ốp 46mm', 'apple:watch-series-10-46mm:64gb'], + ['Apple Watch Series 10 giảm 44 nghìn tặng ốp 46mm', 'apple:watch-series-10-46mm:64gb'], // A size listed right after the box's is a list, not the watch's own case. ['Apple Watch Series 10 kèm hộp 46mm | 42mm', 'apple:watch-series-10-46mm:64gb'], // "size 46" beats a box's size; a band's "size 42" is not the watch's. diff --git a/apps/importer/src/shopee/product-normalizer.ts b/apps/importer/src/shopee/product-normalizer.ts index e88f6f640..2d881543f 100644 --- a/apps/importer/src/shopee/product-normalizer.ts +++ b/apps/importer/src/shopee/product-normalizer.ts @@ -1257,8 +1257,8 @@ function isProductCodeToken(token: string): boolean { // tặng" or "13 hãng" is a bare 13, not "13 t(b)" or "13 h"; "15 tháng" (warranty), "10%" // or "15 gói" is no size (DOS/Rate#1291). const UNIT_END = String.raw`(?![\p{L}\p{M}\d])`; -const SIZE_NOT_PRECEDED_BY = String.raw`(? Date: Thu, 29 Oct 2026 02:48:41 +0700 Subject: [PATCH 2/2] fix(normalizer): a size before "RAM 8GB", SSD or ROM stays the screen's; no short price units Co-Authored-By: Claude Opus 5.5 --- .../src/shopee/__tests__/open-core-intelligence.test.ts | 9 +++++++++ apps/importer/src/shopee/product-normalizer.ts | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts b/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts index c65cefe48..56ab53c14 100644 --- a/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts +++ b/apps/importer/src/shopee/__tests__/open-core-intelligence.test.ts @@ -492,6 +492,15 @@ async function runSuite() { ['MacBook Pro M3 16 RAM 512 SSD tặng túi 14 inch', 'apple:macbook-pro-m3-14:unknown'], ['MacBook Air M3 macOS Sonoma 14 tặng túi 13 inch', 'apple:macbook-air-m3-13:unknown'], ['iPad Air M2 BH 12 months tặng ốp 11 inch', 'apple:ipad-air-m2-11:unknown'], + // ...but a size before "RAM 8GB" (a RAM size follows), "SSD" or "ROM" is the + // screen's, and short words like "Tr", "k", "đ" are no unit. + ['iPad Pro M4 11 RAM 8GB ROM 256GB tặng ốp 13 inch', 'apple:ipad-pro-m4-11:256gb'], + ['Macbook Air M2 13 RAM 8GB SSD 256GB', 'apple:macbook-air-m2-13:256gb'], + ['MacBook Pro M3 14 RAM 18GB 512GB', 'apple:macbook-pro-m3-14:512gb'], + ['MacBook Air M1 13 SSD 256GB', 'apple:macbook-air-m1-13:256gb'], + ['iPad Pro M4 11 ROM 256GB', 'apple:ipad-pro-m4-11:256gb'], + ['MacBook Pro 14 Tr M3 8GB 512GB', 'apple:macbook-pro-m3-14:512gb'], + ['iPad Pro 11 k M4 256GB', 'apple:ipad-pro-m4-11:256gb'], // A bare gift number is the gift's: the product's own size after it wins. ['iPad Pro M4 tặng ốp 11 | 13 WiFi', 'apple:ipad-pro-m4-13:unknown'], ['iPad Pro M4 13 tặng ốp 11 tặng bút', 'apple:ipad-pro-m4-13:unknown'], diff --git a/apps/importer/src/shopee/product-normalizer.ts b/apps/importer/src/shopee/product-normalizer.ts index 2d881543f..9980b6fe9 100644 --- a/apps/importer/src/shopee/product-normalizer.ts +++ b/apps/importer/src/shopee/product-normalizer.ts @@ -1256,9 +1256,11 @@ function isProductCodeToken(token: string): boolean { // js/polynomial-redos). A unit ends where a letter does, Vietnamese ones included: "13 // tặng" or "13 hãng" is a bare 13, not "13 t(b)" or "13 h"; "15 tháng" (warranty), "10%" // or "15 gói" is no size (DOS/Rate#1291). +// "16 RAM 512" is the RAM; "13 RAM 8GB" (a RAM size follows) is the screen's 13 +// (DOS/Rate#1317). const UNIT_END = String.raw`(?![\p{L}\p{M}\d])`; const SIZE_NOT_PRECEDED_BY = String.raw`(?