fix: comprehensive shopping name audit + README update
Shopping name system hardening (api/index.php): - phraseMap: added sugar subtypes (zucchero a velo), passato di verdure/patate → Verdure, aroma phrases → Ingredienti Spezie, farina 00 → Farina, explicit brodo subtypes; added ordering comment on 'farina integrale' - keywordMap: added 'lievito' → Lievito, 'aroma' → Ingredienti Spezie single-token fallbacks DB migration (sqlite3 direct): - farina integrale / Farina integrale di grano tenero → Farina integrale (3 rows) - Prodotto sconosciuto (Belbake, it:farina-integrale) → Farina integrale - Zucchero di canna → Zucchero di canna - Passato di patate e carote → Verdure (it's a blended veg purée) - Aroma mandorla per dolci → Ingredienti Spezie (consistent with other aromas) Total: 11 products re-classified README.md: - Shopping List: added generic shopping name feature + auto-add on depletion - Cooking Mode: updated TTS description (browser / native Android / REST) - Kiosk: added native TTS bridge bullet - Roadmap: checked off 3 new completed items
This commit is contained in:
@@ -33,15 +33,17 @@
|
||||
|
||||
### 🛒 Shopping List
|
||||
- **Bring! integration** — Sync with the [Bring!](https://www.getbring.com/) shopping list app
|
||||
- **Generic shopping names** — Products are grouped by type ("Latte", "Affettato", "Panna da cucina") rather than brand, keeping the Bring! list clean and consolidated
|
||||
- **Smart predictions** — Know what you'll need before you run out
|
||||
- **Auto-add on depletion** — When a product reaches zero the app adds it to Bring! automatically, no confirmation needed
|
||||
- **Auto-remove on scan** — Products are removed from the shopping list when scanned in
|
||||
- **DupliClick integration** — Online grocery ordering (Gruppo Poli)
|
||||
|
||||
### 🍳 Cooking Mode
|
||||
- **Step-by-step guidance** — Follow recipes with a hands-free cooking interface
|
||||
- **Text-to-Speech** — Voice readout of recipe steps (configurable TTS endpoint)
|
||||
- **Text-to-Speech** — Voice readout of recipe steps; supports browser Web Speech API, native Android TTS (kiosk), or a custom REST endpoint (Home Assistant, etc.)
|
||||
- **Built-in timer** — Automatic timer suggestions based on recipe instructions
|
||||
- **Ingredient tracking** — Mark ingredients as used during cooking
|
||||
- **Ingredient tracking** — Mark ingredients as used during cooking; leftover quantities prompt a "move to another location" flow
|
||||
|
||||
### 📊 Dashboard
|
||||
- **Waste tracking** — Monitor consumed vs. wasted products over 30 days
|
||||
@@ -76,6 +78,7 @@
|
||||
- **Setup wizard** — 3-step guided configuration (URL, connection test, gateway)
|
||||
- **Gateway auto-launch** — Launches the Scale Gateway in the background on startup
|
||||
- **Camera & mic permissions** — Full hardware access for barcode scanning and voice
|
||||
- **Native TTS bridge** — Cooking mode voice readout uses the Android TextToSpeech engine directly, bypassing Web Speech API voice limitations; no offline voice packs required
|
||||
- **Hard refresh** — ↻ button clears WebView cache to pick up web app updates
|
||||
- **Update notifications** — Checks GitHub releases every 6h, shows banner when updates available
|
||||
- **SSL support** — Accepts self-signed certificates
|
||||
@@ -313,6 +316,9 @@ The application uses no build tools — edit files directly and refresh.
|
||||
- [x] AI scan local matching — suggest existing pantry products before OFF lookup
|
||||
- [x] Scale auto-fill improvements — 10g threshold, ml conversion hints
|
||||
- [x] Update notification system — kiosk checks GitHub releases
|
||||
- [x] Generic shopping name grouping — compound-phrase + keyword map (100+ entries) + Gemini AI fallback
|
||||
- [x] Auto-add to Bring! on product depletion — no confirmation step when stock reaches zero
|
||||
- [x] Native Android TTS in kiosk — bypasses Web Speech API voice detection issues
|
||||
- [ ] Offline mode with service worker
|
||||
- [ ] Export/import inventory data
|
||||
- [ ] Notification system (Telegram, email) for expiring products
|
||||
|
||||
+20
-4
@@ -3703,25 +3703,37 @@ function computeShoppingName(string $name, string $category = '', string $brand
|
||||
'glassa balsamic' => 'Aceto balsamico',
|
||||
// Cold cuts — specific cuts
|
||||
'prosciutto cotto' => 'Prosciutto cotto',
|
||||
// Flour subtypes
|
||||
// Flour subtypes (MUST come before generic "farina")
|
||||
'farina di riso' => 'Farina di riso',
|
||||
'farina riso' => 'Farina di riso',
|
||||
'farina di mais' => 'Farina di mais',
|
||||
'farina mais' => 'Farina di mais',
|
||||
'farina integrale' => 'Farina integrale',
|
||||
'farina 00' => 'Farina',
|
||||
// Roux / sugar subtypes
|
||||
'zucchero di canna' => 'Zucchero di canna',
|
||||
'zucchero canna' => 'Zucchero di canna',
|
||||
'zucchero velo' => 'Zucchero a velo',
|
||||
'zucchero a velo' => 'Zucchero a velo',
|
||||
// Fresh pasta
|
||||
'pasta fresca' => 'Pasta fresca',
|
||||
// Broth / stock
|
||||
'brodo vegetale' => 'Brodo',
|
||||
'brodo pollo' => 'Brodo',
|
||||
'brodo manzo' => 'Brodo',
|
||||
// Sugar subtypes
|
||||
'zucchero di canna' => 'Zucchero di canna',
|
||||
'zucchero canna' => 'Zucchero di canna',
|
||||
// Mixed vegetable purée / passato (MUST come before generic carote/patate)
|
||||
'passato di verdure' => 'Verdure',
|
||||
'passato di patate' => 'Verdure',
|
||||
// Water
|
||||
'acqua frizzante' => 'Acqua',
|
||||
'acqua gassata' => 'Acqua',
|
||||
'acqua minerale' => 'Acqua',
|
||||
// Aroma / flavouring
|
||||
'aroma vaniglia' => 'Ingredienti Spezie',
|
||||
'aroma mandorla' => 'Ingredienti Spezie',
|
||||
'aroma limone' => 'Ingredienti Spezie',
|
||||
'aroma rum' => 'Ingredienti Spezie',
|
||||
'aroma arancia' => 'Ingredienti Spezie',
|
||||
];
|
||||
foreach ($phraseMap as $phrase => $canonical) {
|
||||
if (mb_strpos($lower, $phrase) !== false) {
|
||||
@@ -3771,6 +3783,10 @@ function computeShoppingName(string $name, string $category = '', string $brand
|
||||
'grattato' => 'Pangrattato',
|
||||
'pangrattato' => 'Pangrattato',
|
||||
'biscottate' => 'Fette biscottate',
|
||||
// Leavening agents
|
||||
'lievito' => 'Lievito',
|
||||
// Flavourings / aromas (single-token fallback; phrases handled above)
|
||||
'aroma' => 'Ingredienti Spezie',
|
||||
// Dairy
|
||||
'latte' => 'Latte',
|
||||
'yogurt' => 'Yogurt',
|
||||
|
||||
Reference in New Issue
Block a user