health score in drawer

This commit is contained in:
2026-09-04 17:20:24 +05:30
parent b8150eb158
commit 9f1593ff87
6 changed files with 151 additions and 11 deletions

View File

@@ -0,0 +1,76 @@
/**
* What the health panel would render, for real products, against the live
* service.
*
* Not a test — the tests pin behaviour against a frozen fixture. This runs the
* SAME functions the panel calls against whatever the service is returning
* right now, which is the only way to catch the service changing under us.
*
* npx tsx scripts/checkHealthPanel.ts
*/
import { nutritionApi } from '../src/api/nutrition';
import { facts, present, BAND_LABEL } from '../src/features/store-admin/healthScore';
const CASES: { label: string; brand: string; imageId: string; expect: string }[] = [
{
label: 'Cadbury 5 Star 200g',
brand: 'Cadbury',
imageId: 'cadbury_cadbury_5_star_200g',
expect: 'a score, with a low-confidence caveat',
},
{
label: 'Godrej Hit Spray (INSECTICIDE)',
brand: 'Godrej',
imageId: 'godrej_hit_spray_1101d017',
expect: 'NO score — blocked by the edibility guard',
},
{
label: 'Naga Sooji',
brand: 'Naga',
imageId: 'naga_naga_sooji_100g',
expect: 'a high score, allergen declared',
},
{
label: 'Aachi Baby Fryums 100g (a real merchant product)',
brand: 'Aachi',
imageId: 'aachi_aachi_baby_fryums_100g',
expect: 'known but unscored',
},
];
const line = (s = '') => console.log(s);
for (const testCase of CASES) {
line();
line('─'.repeat(72));
line(`${testCase.label}`);
line(`expected: ${testCase.expect}`);
line('─'.repeat(72));
const raw = await nutritionApi.forProduct(testCase.brand, testCase.imageId);
const shown = present(raw);
if (shown.isEmpty) {
line(' → "No health score available for this product yet."');
continue;
}
if (shown.isPending) {
line(' → "This product is in the catalogue but has not been scored yet."');
line(` (service sent health_score=${raw?.health_score}, category="${raw?.category}")`);
continue;
}
line(` SCORE ${shown.display}/100 ${shown.band ? BAND_LABEL[shown.band] : ''}`);
for (const good of shown.good) line(` ✓ ${good}`);
for (const caution of shown.cautions) line(` ! ${caution}`);
if (shown.tags.length) line(` TAGS ${shown.tags.join(' · ')}`);
if (shown.allergens.length) line(` ALLERGENS Contains ${shown.allergens.join(', ')}`);
else if (shown.allergensUnconfirmed) line(' ALLERGENS not confirmed — check the pack');
const rows = facts(raw);
if (rows.length) line(` PER 100g ${rows.map((r) => `${r.label} ${r.value}`).join(' · ')}`);
if (shown.caveat) line(` CAVEAT ${shown.caveat}`);
if (shown.source) line(` SOURCE ${shown.source.label}`);
}
line();