Both PHP and JS rules for opened confettura/marmellata in
section G (fridge condiments) were returning 60 days — too short.
An opened jar of jam lasts ~6 months in the fridge.
Also: update README roadmap with comprehensive, grouped view
matching the internal memory roadmap (high/medium/low/completed).
Fixes: database.php line ~412, app.js line ~1707
- Category badge on every inventory item (icon + label); 'altro' items
refined asynchronously via new guess_category Gemini endpoint
(data/category_ai_cache.json) — no AI call when key not configured
- Category search: inventory search now matches by macro-category key
and translated label (e.g. 'biscotti' finds all cookie items)
- Brand fast-path in guessCategoryFromName (Oreo, Barilla, Lavazza…)
- Fix: duplicate banner alerts — _bannerLoading guard + _queuedItemIds Set
- Fix: mapToLocalCategory with en:dairies (dairi stem added)
- Fix: mapToLocalCategory no longer blocks on 'altro' — falls back to
guessCategoryFromName(productName) before returning 'altro'
- Fix: 'Tonno all'olio' was resolving to condimenti — moved tonno\b
check before olio\b in conserve regex block
- AI guards: _refineCategoryBadgesAsync and fetchAllPrices now check
_geminiAvailable (JS); getShoppingPrice returns no_api_key (PHP)
when GEMINI_API_KEY is not set — all AI functions are now explicit
- SettingsActivity: replace GATEWAY_PACKAGE / PackageManager check with
GatewayService status; show BLE device name + live :8765 probe;
buttons now restart GatewayService or redirect to setup wizard
- activity_settings.xml: rename section label to 'BILANCIA SMART',
update button text to '⚙️ Configura bilancia'
- evershelf-scale-gateway/README.md: add DEPRECATED notice (gateway is
now integrated into kiosk v1.6.0+, this app is no longer maintained)
- evershelf-kiosk/README.md: full rewrite — reflects v1.6.0, integrated
BLE gateway, 6-step wizard, permissions table, protocol reference
- README.md: update kiosk features (remove gateway APK install/launch,
add integrated BLE service), update scale section, update architecture,
add kiosk v1.6.0 entry in Recent Updates
README:
- Added prominent live demo banner at the top with links to
https://evershelfproject.dadaloop.it/demo and project website
Wiki (docs/wiki/):
- Home.md — overview, table of contents, what's new
- Installation.md — Docker, Apache, Nginx, HTTPS, cron, backup
- Configuration.md — full .env reference, settings UI, rate limits
- Features.md — complete feature documentation
- API-Reference.md — all REST endpoints with params/responses
- Android-Kiosk.md — setup wizard, permissions, troubleshooting
- Scale-Gateway.md — BLE protocol, setup, troubleshooting
- Translations.md — how to add/edit language files
- Contributing.md — dev workflow, branch strategy, CI, code style
- FAQ.md — common issues and solutions
A partially-used fridge entry (e.g. 191 ml of milk) triggered a
'suspiciously low quantity' banner even when sealed packages of the
same product were present in another location (e.g. pantry).
Fix: before pushing a low-qty review alert, group all inventory rows
by product key (barcode, or name+brand fallback). If any sibling entry
for the same product has qty > 0 in a different row, skip the alert.
High-qty and suspicious package-size alerts are unaffected.
- Banner: detect expired opened-products via effective shelf-life (opened_at +
estimateOpenedExpiryDays), not just raw expiry_date — fixes Fagioli/Panna case
- Banner: expired items show safety tip inline; danger-level items (fridge dairy,
meat, fish) get red banner + 'L'ho buttato' as primary button, 'Usa comunque'
demoted to grey; safety-ok/warning items keep original button order
- Banner: anomaly dismiss button now shows current inventory qty ('La quantità è
giusta (2 pz)') so the action is unambiguous
- AI: add callGeminiWithFallback() helper — tries gemini-2.5-flash first (separate
quota), falls back to gemini-2.0-flash; applied to all endpoints (expiry, chat,
identify, recipe non-streaming, shopping name classifier)
- AI: show friendly 'Quota AI esaurita' message instead of raw Gemini error string
- Cooking TTS: fix auto-speak broken since 'auto-speak removed' comment — each step
is now read automatically on navigate and on first step when entering cooking mode
- Cooking TTS: remove incorrect s.tts_enabled gate — _cookingTTS toggle is the only
gate; browser Web Speech API used by default without requiring Settings config
- Cooking TTS: timer fires '10 secondi rimanenti' warning at T-10s
- Cooking TTS: announce recipe completion ('Buon appetito!') on last step confirm
- i18n: add timer_warning_tts, recipe_done_tts, error.ai_quota keys (IT/EN/DE)
- CSS: add banner-expired-danger, banner-safety-* styles for unsafe expired items
- Add evershelf-scale-gateway/ Android app (Kotlin):
- BLE scanning and GATT connection to smart scales
- Supports BT SIG Weight Scale (0x181D), Body Composition (0x181B), and generic heuristic parser
- WebSocket server on port 8765 (local LAN)
- Real-time weight broadcasting to EverShelf browser client
- Add scale status indicator in header (green/orange/grey dot)
- Add Settings tab for scale configuration (URL, enable toggle, test, APK download link)
- Add 'Read from scale' button in Add/Use forms when unit is g or ml
- Add scale WebSocket client logic in app.js with auto-reconnect
- Fix recipe suggestion: expiry-prioritized ingredients now only injected into
AI prompt when user explicitly selects 'Priorità Scadenze' or 'Zero Sprechi'
- Update README with smart scale section and website link
- Update all translations (it, en, de) with scale strings
- Add 9 curated screenshots to assets/img/screenshots/ covering all main features
- Update README with 3x3 screenshot table with Italian descriptions
- Anchor /screenshots/ gitignore rule so assets/img/screenshots/ is tracked
- Screenshots cover: dashboard, inventory, barcode scanner, recipe detail,
recipes list, cooking mode, AI chat, shopping list, smart predictions