orders: share the merchant tidy, and fix two bugs the corpus run found (board 212)
ci / lint-test (push) Successful in 41s
ci / lint-test (push) Successful in 41s
The tidy existed but lived inside the list page, so the DETAIL page never had it: following a row through showed "Apple" becoming "Apple Pty Ltd." Moved to src/lib/merchant-label.ts and applied on both surfaces. Running it over all 1,451 distinct merchant names — rather than over examples — turned up two real defects: Coburger & Co -> "Coburger &" eBay Commerce Australia Pty Ltd. -> "EBay Commerce Australia" The first strips a suffix that is part of the brand and leaves a dangling connector. The second is the capitalisation rule firing on "starts with a lower-case letter" when what it means is "is a bare domain" — mangling a brand that is deliberately lower-cased. Both are now guarded, and re-running over the full corpus reports 170 names tidied and 0 defects. PRESENTATION ONLY. It merges nothing and must never decide two rows are the same merchant. Amazon.in stays Amazon.in — a different marketplace with different currency and geography, not a name variant — and there is a test asserting it can never equal amazon.com.au. Kogan.com, GOG.com, AliExpress.com and Catch.com.au are real brand names containing a TLD and are left alone. Real unification is the merchant-alias bridge, ticket 176, which has already merged what can be merged safely. The five names that read alike after tidying (ebay/eBay/eBay Inc., menulog/Menulog Pty Ltd, deliveroo/Deliveroo, grab/Grab, paypal/PayPal) are genuinely one merchant each, so reading alike is correct. Lower-case platform SLUGS are deliberately not capitalised: "ebay" -> "Ebay" is wrong, and getting it right is the registry's job, not the stylesheet's.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Presentational tidy for a merchant name (board 212).
|
||||
*
|
||||
* PRESENTATION ONLY. It merges nothing and must never be used to decide that
|
||||
* two rows are the same merchant. Real unification is the merchant-alias bridge
|
||||
* (ticket 176, `jobs/merchant_merge.py`), which has already merged what can be
|
||||
* merged safely; what is left on screen is one entity looking scruffy, not two
|
||||
* entities that should be one.
|
||||
*
|
||||
* `Amazon.in` MUST NOT become `amazon.com.au`. They are different marketplaces
|
||||
* with different currency and geography — a genuine country distinction, not a
|
||||
* name variant. `Kogan.com`, `GOG.com`, `AliExpress.com` and `Catch.com.au` are
|
||||
* real brand names that happen to contain a TLD and are already correct.
|
||||
*
|
||||
* Two rules, both mechanical:
|
||||
* 1. drop trailing corporate suffixes
|
||||
* 2. capitalise a name that arrived lower-cased FROM A DOMAIN
|
||||
*/
|
||||
|
||||
const CORP_SUFFIX =
|
||||
/,?\s+(pty\.?\s+ltd\.?|pty\.?\s+limited|pte\.?\s+ltd\.?|pte\.?|p\/l|ltd\.?|limited|inc\.?|llc|pbc|gmbh|b\.?v\.?|s\.?a\.?r\.?l\.?|oü|co\.?)$/i;
|
||||
|
||||
/** A bare domain used as a name: all lower case, and a dotted TLD. */
|
||||
const BARE_DOMAIN = /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}(\.[a-z]{2,})?$/;
|
||||
|
||||
/**
|
||||
* Stripping must not leave a dangling connector. `Coburger & Co` is a brand
|
||||
* whose last word happens to match the suffix list, and removing it produced
|
||||
* `Coburger &` — visibly broken, and the kind of thing that only shows up when
|
||||
* you run the rule over the real corpus rather than over examples you chose.
|
||||
*/
|
||||
const DANGLING = /(\s[&+-]|\sand)$/i;
|
||||
|
||||
export function tidyMerchant(name: string): string {
|
||||
let n = name.replace(/\s+/g, " ").trim();
|
||||
|
||||
// At most two passes: "Samsung Electronics Co. Ltd." needs Ltd. then Co.
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const stripped = n.replace(CORP_SUFFIX, "").trim().replace(/,$/, "");
|
||||
if (stripped === n || stripped.length < 3 || DANGLING.test(stripped)) break;
|
||||
n = stripped;
|
||||
}
|
||||
|
||||
// "amazon.com.au" reads as a machine artefact; "Amazon.com.au" reads as a
|
||||
// name. Gated on BARE_DOMAIN, not on "starts with a lower-case letter": the
|
||||
// looser test turned `eBay Commerce Australia Pty Ltd.` into `EBay Commerce
|
||||
// Australia`, mangling a brand that is deliberately lower-cased.
|
||||
if (BARE_DOMAIN.test(n)) n = n[0].toUpperCase() + n.slice(1);
|
||||
|
||||
return n;
|
||||
}
|
||||
Reference in New Issue
Block a user