From 12269deeda31cd635b9b3c2a68d70d0f93621682 Mon Sep 17 00:00:00 2001 From: abhishek Date: Tue, 8 Sep 2026 12:17:56 +0530 Subject: [PATCH] category id --- scripts/refileCategories.ts | 6 ++++- .../store-admin/productCategory.test.ts | 25 +++++++++++++++++++ src/features/store-admin/productCategory.ts | 8 +++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/scripts/refileCategories.ts b/scripts/refileCategories.ts index 1dadd80..556499f 100644 --- a/scripts/refileCategories.ts +++ b/scripts/refileCategories.ts @@ -132,7 +132,11 @@ async function main() { for (const plan of plans) { if (!plan.aisle) { - orphans.push(plan); + // Only worth reporting if the product has no aisle ALREADY. Several were + // filed by hand long before any of this, and listing those as "would stay + // under Uncategorized" says the opposite of what is true. + if (plan.from === 0) orphans.push(plan); + else unchanged += 1; continue; } const to = aisleIds.get(plan.aisle.toLowerCase()) ?? 0; diff --git a/src/features/store-admin/productCategory.test.ts b/src/features/store-admin/productCategory.test.ts index ffbda42..41552bb 100644 --- a/src/features/store-admin/productCategory.test.ts +++ b/src/features/store-admin/productCategory.test.ts @@ -225,3 +225,28 @@ test('the shapes the non-canonical names were covering now land somewhere sane', 'Dairy', ); }); + +/* ── Plain names, typed by a shop rather than read from a catalogue ───────── */ + +// Six live products sat in the app's "Uncategorized" bucket because the +// registry only knew branded goods. A shop that types "Tuna" into a sheet is +// naming a category, not a product line, and the ladder has to hear it. +test('a bare food name reaches the aisle a shopper would look in', () => { + assert.equal(resolveCategory({ title: 'Tuna' }).category, 'Fish & Seafood'); + assert.equal(resolveCategory({ title: 'Strawberries' }).category, 'Fruits & Vegetables'); + assert.equal(resolveCategory({ title: 'Pineapple' }).category, 'Fruits & Vegetables'); + assert.equal( + resolveCategory({ title: 'Cheerios Breakfast Cereal 100g' }).category, + 'Atta & Staples', + ); + assert.equal(resolveCategory({ title: 'Closeup Red Hot Gel 150g' }).category, 'Oral Care'); +}); + +// Widening a keyword list is where a registry starts eating its neighbours. +// These are the collisions the new words could plausibly cause. +test('the widened keywords do not swallow their neighbours', () => { + assert.equal(resolveCategory({ title: 'Coconut Oil 1L' }).category, 'Cooking Oils'); + assert.equal(resolveCategory({ title: 'Ginger Garlic Paste 200g' }).category, 'Spices & Masalas'); + assert.equal(resolveCategory({ title: 'Oats Digestive Biscuits 200g' }).category, 'Biscuits & Cookies'); + assert.equal(resolveCategory({ title: 'Chilli Powder 100g' }).category, 'Spices & Masalas'); +}); diff --git a/src/features/store-admin/productCategory.ts b/src/features/store-admin/productCategory.ts index 1468ba3..2e95cd1 100644 --- a/src/features/store-admin/productCategory.ts +++ b/src/features/store-admin/productCategory.ts @@ -114,7 +114,7 @@ export const CATEGORY_REGISTRY: readonly CategoryEntry[] = [ { category: 'Salt & Staples', keywords: ['salt', 'rock salt', 'iodised salt', 'sea salt'], genericTerm: 'salt' }, { category: 'Atta & Staples', - keywords: ['atta', 'flour', 'maida', 'rava', 'sooji', 'suji', 'besan', 'ragi', 'rice', 'basmati', 'poha', 'aval', 'idli rice', 'wheat'], + keywords: ['atta', 'flour', 'maida', 'rava', 'sooji', 'suji', 'besan', 'ragi', 'rice', 'basmati', 'poha', 'aval', 'idli rice', 'wheat', 'cereal', 'cereals', 'cornflakes', 'corn flakes', 'muesli', 'oats', 'porridge'], genericTerm: 'flour', }, { @@ -124,7 +124,7 @@ export const CATEGORY_REGISTRY: readonly CategoryEntry[] = [ }, { category: 'Fruits & Vegetables', - keywords: ['fruit', 'fruits', 'vegetable', 'vegetables', 'onion', 'potato', 'tomato', 'banana', 'apple', 'mango', 'carrot', 'brinjal', 'cabbage', 'cauliflower', 'lemon', 'dragon fruit', 'grapes', 'orange'], + keywords: ['fruit', 'fruits', 'vegetable', 'vegetables', 'onion', 'potato', 'tomato', 'banana', 'apple', 'mango', 'carrot', 'brinjal', 'cabbage', 'cauliflower', 'lemon', 'dragon fruit', 'grapes', 'orange', 'strawberry', 'strawberries', 'pineapple', 'papaya', 'guava', 'watermelon', 'pomegranate', 'beetroot', 'cucumber', 'ginger', 'garlic', 'beans', 'peas', 'chilli', 'coconut'], genericTerm: 'produce', }, { @@ -135,13 +135,13 @@ export const CATEGORY_REGISTRY: readonly CategoryEntry[] = [ { category: 'Flowers', keywords: ['flower', 'flowers', 'jasmine', 'rose petals', 'garland'], genericTerm: 'flowers' }, { category: 'Fish & Seafood', - keywords: ['fish', 'seafood', 'prawn', 'prawns', 'crab', 'squid', 'sardine', 'mackerel'], + keywords: ['fish', 'seafood', 'prawn', 'prawns', 'crab', 'squid', 'sardine', 'mackerel', 'tuna', 'salmon', 'anchovy', 'nethili', 'vanjaram', 'seer fish'], genericTerm: 'fish', }, { category: 'Eggs', keywords: ['egg', 'eggs'], genericTerm: 'eggs' }, { category: 'Oral Care', - keywords: ['toothpaste', 'toothbrush', 'tooth powder', 'mouthwash', 'dental', 'oral care', 'colgate'], + keywords: ['toothpaste', 'toothbrush', 'tooth powder', 'mouthwash', 'dental', 'oral care', 'colgate', 'closeup', 'close up', 'pepsodent', 'sensodyne'], genericTerm: 'oral care', }, {