groceries: add Picnic store (picnic.app storefront API, full range via category pages)
Deploy production / deploy (push) Successful in 1m24s

- picnic.ts: crawls the category tree, subcategory and overview pages (RSC), maps
  Picnic categories to the shared list; no EANs, so matching is by name/brand/size
- picnic-auth.ts + scripts/picnic-login.ts: one-shot login from
  /etc/grocery-tracker/picnic.env, token kept in ~/.config/groceries/picnic.env;
  2FA is never requested unattended (run picnic-login.ts by hand)
- migration: store row picnic; Picnic as own brand in stats
This commit is contained in:
stan committed 2026-10-27 09:04:26 +00:00
1 parent 079399635d
commit c094754c5b
11 files changed
+46305 -2

No files matched your search

+2 -1
View File
@@ -59,6 +59,7 @@ export const OWN_BRANDS: { slug: string; rx: string; unbranded: boolean }[] = [
{ slug: 'hoogvliet', rx: `^(hoogvliet|${SUPERUNIE})`, unbranded: true },
{ slug: 'vomar', rx: `^(vomar|${SUPERUNIE})`, unbranded: true },
{ slug: 'aldi', rx: `^(aldi|${ALDI})`, unbranded: true },
{ slug: 'picnic', rx: '^picnic($|\\s)', unbranded: true },
{
slug: 'lidl',
rx: '^(lidl|milbona|pilos|vitasia|chef select|deluxe|solevita|freeway)',
@@ -66,7 +67,7 @@ export const OWN_BRANDS: { slug: string; rx: string; unbranded: boolean }[] = [
}
];
// A group counts as own brand when its display brand is a house class or any store's own label.
const GROUP_HOUSE_RX = `^(huismerk|ah|albert heijn|jumbo|plus|dirk|hoogvliet|vomar|aldi|${SUPERUNIE}|${ALDI})`;
const GROUP_HOUSE_RX = `^(huismerk|ah|albert heijn|jumbo|plus|dirk|hoogvliet|vomar|aldi|picnic|${SUPERUNIE}|${ALDI})`;
/** Staples basket ("Gouda shopping route"). rx/nrx match lower(name); qty in kg, l or pieces. */
const STAPLES: (Staple & {