You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up of #1089 / PR #1091, which moved the rules into @repo/shared-data/rules without changing behaviour. These changes alter behaviour and need a decision on the target values.
1. Earbuds regex misses model numbers
EARBUDS_TITLE_REGEX uses \bbuds\b, so "Galaxy Buds3 Pro", "Buds2" and "FreeBuds5i" do not match. Those listings get the 1.2M VND device floor, and the extension or inspect flow can flag a genuine 700k earbuds listing as an accessory. The test in packages/shared-data/src/__tests__/shared-data.test.ts pins the current behaviour, marked as a gap. Fix: allow a trailing model number (for example buds\d*, freebuds\d*i?) and update that test.
2. Rate-Services uses its own thresholds
Rate-Services keeps its own copies instead of importing @repo/shared-data/rules, which it already has as a workspace package through vendor/rate:
src/scrapers/search-discovery.ts (isAccessoryOrInvalidCandidate): the device floor is 800,000, not 1,200,000. Its earbuds regex has no word boundaries and is tested against title + targetModelKey. A missing price is rejected, where web lets it through.
src/scrapers/job-seeder.ts: bait price is 50% of the true median with at least 2 others, not 40% of the lower median with at least 3 listings.
src/scrapers/scraped-values.ts: its own MAX_VALID_VND_PRICE.
Discovery may deliberately be looser than display. Decide per rule whether the crawler should share the rule or keep a documented, named variant, then import from @repo/shared-data/rules after the vendor/rate bump.
[Agent: Core] Mục 2, phía Rate-Services: đã xong ở DOS/Rate-Services#629 (6d70744), sau khi bump vendor/rate lên d1a559f ở DOS/Rate-Services#627. PR không đổi hành vi.
Dùng rule chung:
MAX_VALID_VND_PRICE lấy từ @repo/shared-data/rules, bỏ hai bản sao trong scraped-values.ts và queue-worker.ts.
Sàn earbuds của discovery dùng MINIMUM_EARBUDS_PRICE_FLOOR_VND.
Giữ biến thể có tên và ghi chú:
DISCOVERY_DEVICE_PRICE_FLOOR_VND = 800_000, thấp hơn MINIMUM_DEVICE_PRICE_FLOOR_VND = 1_200_000. Discovery là cổng một chiều: listing bị từ chối thì không vào catalog nữa. Web chỉ ẩn listing đã có, nên có thể chặt hơn.
DISCOVERY_EARBUDS_REGEX, không có word boundary, nên bắt được "Buds3" và "FreeBuds5i", là những tên mà EARBUDS_TITLE_REGEX đang bỏ sót (mục 1 của issue này).
DISCOVERY_MIN_MARKET_PRICE_RATIO = 0.5, cần ít nhất 2 offer khác. Refresh dưới sàn sẽ đánh dấu listing là discontinued, còn rule chung chỉ ẩn offer. Catalog thường chỉ có 2 đến 3 offer cho mỗi master, nên điều kiện 3 offer sẽ tắt cổng ở hầu hết master.
Khi mục 1 được sửa: test RS runSharedRulesTests628 có một assertion cố ý khóa việc EARBUDS_TITLE_REGEX không khớp "Buds3". Lần bump đầu tiên sau khi sửa sẽ fail ở đó, kèm thông điệp hướng dẫn chuyển DISCOVERY_EARBUDS_REGEX sang dùng regex chung.
[Agent: Core] Note for the next DOS/Rate-Services vendor/rate bump, which will bring #1094 (PR #1101, merged in dev 0c64546):
The normalizer no longer guesses a storage for a registry model sold in several sizes, so a storage-less title of such a model now keys brand:model:unknown. Only the five single-storage watches (Watch Ultra 2, Watch Ultra 3, Watch Series 11, Galaxy Watch Ultra, Forerunner 265) still key at a storage.
keyStorageIsDefault therefore returns false for those multi-storage titles, because their key holds no storage. In src/scrapers/test-multi-platform-scrapers.ts, the assertions that expect true for "Laptop ASUS Zenbook S 14 UX5406AA-SU348W", "Asus Zenbook S 14 OLED UX5406SA-PV140WS Core Ultra 7-258V", "Samsung Galaxy S26 Ultra 5G 12GB", "Apple iPhone 18 Pro Max", "MacBook Air M4 13 inch" and "Máy tính bảng iPad Pro M5 11 inch WiFi" will fail and need updating. "Apple Watch Series 11 GPS 46mm" stays true.
statedModelKeyOfTitle returns the same keys as before (:unknown for those titles), so listingMatchesMaster and discovery keep their behaviour. The keyStorageIsDefault workaround from DOS/Rate-Services#618 is now only needed for the watches and can be simplified.
After the bump, run audit-catalog to list stored listings whose title key moves from :<n>gb to :unknown. Already-clustered listings keep their master through masterIdHint.
Activity
JOY commentedon Oct 26, 2026
[Agent: Core] Mục 2, phía Rate-Services: đã xong ở DOS/Rate-Services#629 (6d70744), sau khi bump
vendor/ratelên d1a559f ở DOS/Rate-Services#627. PR không đổi hành vi.Dùng rule chung:
MAX_VALID_VND_PRICElấy từ@repo/shared-data/rules, bỏ hai bản sao trongscraped-values.tsvàqueue-worker.ts.MINIMUM_EARBUDS_PRICE_FLOOR_VND.Giữ biến thể có tên và ghi chú:
DISCOVERY_DEVICE_PRICE_FLOOR_VND = 800_000, thấp hơnMINIMUM_DEVICE_PRICE_FLOOR_VND = 1_200_000. Discovery là cổng một chiều: listing bị từ chối thì không vào catalog nữa. Web chỉ ẩn listing đã có, nên có thể chặt hơn.DISCOVERY_EARBUDS_REGEX, không có word boundary, nên bắt được "Buds3" và "FreeBuds5i", là những tên màEARBUDS_TITLE_REGEXđang bỏ sót (mục 1 của issue này).DISCOVERY_MIN_MARKET_PRICE_RATIO = 0.5, cần ít nhất 2 offer khác. Refresh dưới sàn sẽ đánh dấu listing là discontinued, còn rule chung chỉ ẩn offer. Catalog thường chỉ có 2 đến 3 offer cho mỗi master, nên điều kiện 3 offer sẽ tắt cổng ở hầu hết master.Khi mục 1 được sửa: test RS
runSharedRulesTests628có một assertion cố ý khóa việcEARBUDS_TITLE_REGEXkhông khớp "Buds3". Lần bump đầu tiên sau khi sửa sẽ fail ở đó, kèm thông điệp hướng dẫn chuyểnDISCOVERY_EARBUDS_REGEXsang dùng regex chung.Generated by Claude Code
JOY commentedon Oct 27, 2026
[Agent: Core] Note for the next DOS/Rate-Services
vendor/ratebump, which will bring #1094 (PR #1101, merged in dev 0c64546):brand:model:unknown. Only the five single-storage watches (Watch Ultra 2, Watch Ultra 3, Watch Series 11, Galaxy Watch Ultra, Forerunner 265) still key at a storage.keyStorageIsDefaulttherefore returnsfalsefor those multi-storage titles, because their key holds no storage. Insrc/scrapers/test-multi-platform-scrapers.ts, the assertions that expecttruefor "Laptop ASUS Zenbook S 14 UX5406AA-SU348W", "Asus Zenbook S 14 OLED UX5406SA-PV140WS Core Ultra 7-258V", "Samsung Galaxy S26 Ultra 5G 12GB", "Apple iPhone 18 Pro Max", "MacBook Air M4 13 inch" and "Máy tính bảng iPad Pro M5 11 inch WiFi" will fail and need updating. "Apple Watch Series 11 GPS 46mm" staystrue.statedModelKeyOfTitlereturns the same keys as before (:unknownfor those titles), solistingMatchesMasterand discovery keep their behaviour. ThekeyStorageIsDefaultworkaround from DOS/Rate-Services#618 is now only needed for the watches and can be simplified.:<n>gbto:unknown. Already-clustered listings keep their master throughmasterIdHint.runSharedRulesTests628fails by design, as noted above.fix(shared-data): earbuds regex reads a model number after the name (#…
JOY commentedon Oct 27, 2026
[Agent: PO] Released to production in #1117 (main 22109de). verify-live: https://rate.vn serves main 22109de, database ok, 5 routes 200.