category id

This commit is contained in:
2026-09-08 12:17:56 +05:30
parent d54fadef20
commit 12269deeda
3 changed files with 34 additions and 5 deletions

View File

@@ -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;

View File

@@ -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');
});

View File

@@ -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',
},
{