Commit Graph

252 Commits

Author SHA1 Message Date
morgane 594c9fa115 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 13:06:56 +00:00
morgane 37bf403412 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 12:54:20 +00:00
morgane bb16e441f5 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 11:40:33 +00:00
morgane 80a915ac35 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 08:58:56 +00:00
morgane 3a33dc7173 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 08:44:06 +00:00
morgane 3a08929353 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:39:07 +00:00
morgane 9fc1dd3614 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:23:05 +00:00
morgane ae3254c195 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:14:28 +00:00
morgane 8b44432244 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:08:18 +00:00
morgane b166a305f2 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:55:39 +00:00
morgane 6377c45eaa Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:53:51 +00:00
morgane 8d18362d83 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:52:13 +00:00
morgane cabb8b28d4 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:50:34 +00:00
morgane 27257caa3e Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:46:48 +00:00
morgane db7fc0df18 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:33:23 +00:00
morgane b28aca5e55 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:28:49 +00:00
morgane fecbbafd38 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:59:24 +00:00
morgane 98553c7600 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:49:34 +00:00
morgane e52aa6d699 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:27:42 +00:00
morgane 662c27d7b4 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 12:55:31 +00:00
morgane bf27f7f462 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-16 21:42:38 +00:00
dadaloop82 85ccdaa6f6 Release v1.7.42: shopping totals, waste learning, stability fixes.
Document waste reason picker, stable price estimates, DB retry, and kiosk CI fixes in CHANGELOG and README.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 12:50:13 +00:00
dadaloop82 5831e3bcea Release v1.7.41: fix Traefik startup and clean JSON API responses.
PHP 8.2 deprecations no longer corrupt health_check JSON; .htaccess
respects X-Forwarded-Proto behind reverse proxies.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 12:32:10 +00:00
dadaloop82 9be8fb5cf3 Release v1.7.40: recipe fixes, DB lock retry, and Docker Traefik support.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 06:00:54 +00:00
dadaloop82 5dd3baea5d Release v1.7.39: faster barcode lookup, spesa UX, and expiry control.
Parallel resolve_barcode with SQLite cache speeds bulk shopping scans; spesa mode skips to add form. Manual expiry dates persist across location moves; family sibling checks dedupe for 24h. Fixes kiosk crashes, empty barcode UNIQUE errors, and spesa ghost products.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:19:39 +00:00
dadaloop82 34dcb05c05 Improve scan flow, AI UX, expiry history, and shopping sync.
Manual AI identification replaces auto-fallback; add duplicate-add guard,
AI product match UI, ZBar/Tesseract offline scanning, expiry averages from
last 3 insertions, family sibling hints, and missing i18n keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 09:38:05 +00:00
dadaloop82 7eda4a5eb9 Release v1.7.38: stable shopping total and finished-product Bring sync.
Add depleted products under generic shopping names, unify weekly canonical price total across all surfaces, and fix screensaver amount mismatch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 18:10:24 +00:00
dadaloop82 b63deca795 Release v1.7.37: strict recipe pantry matching and renderRecipe fix.
Prevent false  pantry links via strict name matching and full inventory prompts; fix qtyNum crash when reopening archived recipes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:38:12 +00:00
dadaloop82 cf65e79010 Release v1.7.36: recipe stock hints, ghost products, and shopping total fix.
Adds pantry stock/remainder lines on recipe ingredients with zero-waste use-all on sealed package leftovers, ghost product restore in the dashboard, unified shopping totals, i18n sync, and maintenance scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:22:59 +00:00
dadaloop82 d33b0ca2fe Harden security, modularize API bootstrap, and fix scale SSE auth.
Block web access to sensitive paths, require API_TOKEN for mutations, encrypt GitHub issue credentials in .env, auto-provision tokens for same-origin clients, and pass api_token in scale relay URLs since EventSource cannot send headers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 18:04:19 +00:00
dadaloop82 7104483dac fix: barcode EAN checksum validation + recipe persons dialog conflict
- Manual barcode input now blocks on invalid EAN checksum (was warning-only)
- Native BarcodeDetector now validates EAN/UPC checksum before confirming
- Renamed duplicate adjustRecipePersons (rescaler) to scaleRecipePersons
  to restore +/- buttons in the recipe generation dialog
- Added error.barcode_checksum translation key (all 5 languages)
- Bump version to v1.7.35
2026-06-02 08:58:48 +00:00
dadaloop82 98c38f017e feat: AI visual barcode fallback after 5s with settings toggle
When the barcode scanner cannot read a code within 5 seconds and Gemini
is available, a camera frame is automatically captured and sent to the
new gemini_barcode_visual endpoint for visual product identification.
The result pre-fills the product form identically to a barcode scan.

- PHP: new geminiBarcodeVisual() function + router case + aiActions entry
- PHP: barcode_ai_fallback setting in getServerSettings() + saveSettings() boolMap
- JS: _aiFallbackTimer (cleared on detection/stop), 5s timer in initScanner()
- JS: _tryGeminiVisualBarcode() — captures JPEG frame, calls API, saves product
- JS: barcode_ai_fallback wired into serverKeys, applyUI, collectUI, POST body
- HTML: AI fallback toggle in Settings → Camera card
- Translations: ai_fallback_* strings in scan + settings.camera (it/en/de/fr/es)

Feature is disabled by default (BARCODE_AI_FALLBACK=false).
2026-05-29 17:37:37 +00:00
dadaloop82 bc39361246 feat: barcode scan visual feedback + EAN checksum validation
- Add scan-status-bar overlay inside scanner viewport showing:
  - Active scan method (Native API / Quagga / Native + Quagga)
  - Scanning state: ready, scanning, partial read, invalid, confirmed
- Validate EAN-8/EAN-13/UPC checksums in Quagga path before confirming
  (native BarcodeDetector validates internally; Quagga can return false positives)
- Show 'invalid barcode, retrying' message with invalid code highlighted
- Reset invalid barcode confidence counter on invalid read so scanner retries
- Spawn parallel Quagga scan with 'combined scan active' status message
- Add 6 translation keys (scan.status_*) in all 5 language files
2026-05-27 05:26:47 +00:00
dadaloop82 f46b12e3ad feat: recipe favorites (#124), portion rescaler (#123), financial waste report (#117), macronutrient panel (#118)
- #124: star toggle on recipe view + favorites shown first in archive with gold border
- #123: +/- persons buttons on recipe to scale ingredient quantities
- #117: wasted value in EUR displayed in monthly stats section
- #118: macronutrient breakdown panel (P/C/F/fiber bars) with 4th insight rotation phase
- DB: is_favorite column on recipes, nutriments_json on products (auto-migrated)
- OFF API: nutriments fields fetched and stored per product
- Translations: it/en/de/fr/es updated with new keys
2026-05-26 18:09:32 +00:00
dadaloop82 b985247b95 feat: monthly stats panel in rotating insight banner (closes #100)
- Add PHP action 'monthly_stats' + getMonthlyStats() function:
  items consumed/added/wasted this month, trend vs prev month,
  top 5 categories and top 3 products by transaction count
- Expand insight rotation from 2 → 3 phases (waste → nutrition → monthly)
- Add _renderMonthlyStatsSection() following nutrition section styling:
  large indigo number, trend arrow with %, horizontal category bars
  animated on show, badges for added/wasted/top-product
- Add ms-* CSS classes (bar chart layout matching nutr-* design)
- Add stats_monthly translations in it/en/de/fr/es (10 keys each)
2026-05-26 17:19:54 +00:00
dadaloop82 be3dceeebb feat: add separate sound beep test button + always show move modal on open
- Add testSound() function: plays AudioContext beep independently of TTS
- Add '🔔 Esegui Test Suono' button in TTS settings (above voice test btn)
- Add translations: settings.tts.test_sound_btn (it/en/de)
- Remove hasOtherLocs guard in showMoveAfterUseModal: always show
  location-choice modal when opening a package, regardless of whether
  the product already exists in other locations (e.g. peas only in pantry
  → user can now choose to move opened portion to fridge)
2026-05-26 12:17:18 +00:00
dadaloop82 83b5eb3063 fix: browser TTS ignored when HA TTS configured; wrong ha_hint i18n key
- speakCookingStep: respect tts_engine='browser' explicitly; if user
  chose browser engine, always use _speakBrowser regardless of HA.
  Also add per-engine try/catch so HA or server TTS failures fall back
  to browser TTS instead of silently doing nothing.
- index.html: fix data-i18n='settings.tts.ha_hint' → 'settings.ha.ha_hint'
  (key lived in settings.ha not settings.tts)
2026-05-25 10:37:17 +00:00
dadaloop82 4e4a736dba feat: ask replace vs save-to-archive on regenerate recipe
When user clicks 'Generate another', show a choice:
- Replace (discard current, generate new) — former behavior
- Save to archive & generate new — saves current recipe first

All 5 languages (it/en/de/fr/es) with regen_choice_title,
regen_replace, regen_save_new keys.
2026-05-25 10:11:56 +00:00
dadaloop82 eddb622c85 feat(offline): full offline mode — cache sync, write queue, startup recovery
- Full-screen network error overlay (z-index 300000, above screensaver)
- 'Continue offline' button after 3s, auto-enter after 8s
- Inventory + settings synced to localStorage at startup (during health check)
- inventory_summary and stats computed from local cache while offline
- Write queue (add/use/update/delete): optimistic UI + sync on reconnect
- Pending ops survive page refresh — detected and re-synced at next startup
- Buffered remoteLog/reportError flushed to server (GitHub issues) on restore
- AI/network sections hidden in offline mode (CSS body.offline-mode)
- Banner: pulsing dot while loading cache, item count when ready
- Broken external images replaced with grey SVG placeholder
- Fix: opened items marked is_edible:true offline (was flooding banner)
- Fix: _semverGt() prevents update badge for older GitHub releases
- Bump version to v1.7.25
2026-05-25 09:05:19 +00:00
dadaloop82 965a672abe feat: full Home Assistant integration
- PHP: _fireHaWebhook(), _sendHaNotify(), haInventorySensor(), haTestConnection()
- PHP: ha_sensor + ha_test routing actions
- PHP: getServerSettings() exposes ha_token (consistent with tts_token)
- PHP: saveSettings() handles all HA_* env keys (url, token, tts_entity, webhook_id, events, notify_service, expiry_days)
- PHP: bringAddItems(), shoppingAdd(), updateInventory() fire shopping_add / stock_update webhooks
- Cron: daily HA expiry/expired webhook + push notify with flag-file guard
- HTML: 🏠 Settings tab button + full HA panel (connection, TTS, webhook, notify, sensor cards)
- JS: serverKeys + loadSettingsUI extended with HA fields
- JS: _applyHaSettingsUI(), _loadHaTab(), _renderHaSensorYaml()
- JS: onHaEnabledChange(), testHaConnection(), applyHaTtsPreset()
- JS: saveHaSettings(), copyHaSensorYaml(), showHaWebhookHelp()
- JS: _buildHaTtsRequest() for HA media_player TTS
- JS: speakCookingStep() now supports HA TTS as first-priority path
- JS: onTtsEngineChange() fixed to show server section for both 'server' and 'custom'
- Translations: settings.ha.* (52 keys) in all 5 languages (it/en/de/fr/es)
- .env.example: HA_ENABLED/URL/TOKEN/TTS_ENTITY/WEBHOOK_ID/EVENTS/NOTIFY_SERVICE/EXPIRY_DAYS
- docs/wiki/Home-Assistant.md: new wiki page (REST sensors, webhooks, TTS, push notify, troubleshooting)
- README: HA integration highlighted as first feature block
2026-05-23 12:28:09 +00:00
dadaloop82 6320b575e0 v1.7.25 — partial throw from banner, barcode fallback, related stock, Bring! re-add fix
- Fix: Bring! items re-appearing after manual removal (missing _markBringPurchased call in removeBringItem / confirmShoppingItemFound; autoAddCriticalItems now respects blocklist for qty=0 items)
- Fix: barcode false 'not found' — new _offFetchProduct() helper tries UPC-A↔EAN-13 candidates × 2 locales with auto-retry; UPCItemDB fallback also iterates candidates
- Fix: bannerThrowAway() now opens partial-throw modal (location + qty input + throw-all button) instead of immediately discarding everything
- Add: related stock card on action page — shows same-family inventory items when scanning a branded product
2026-05-23 08:17:20 +00:00
dadaloop82 5c1afaaaf5 feat: redesign action-page hero card (match use-page style) 2026-05-22 21:23:18 +00:00
dadaloop82 fa0442e2f6 feat: native shopping list — decouple from Bring! (#105)
- New shopping_list SQLite table (migration in migrateDB)
- shoppingGetList/Add/Remove — delegates to Bring! or internal DB
  based on SHOPPING_MODE env var (default: internal)
- isShoppingBringMode() guard: requires mode=bring + BRING credentials
- bringQuickSyncProduct updated to support both modes
- All bring_* JS calls replaced with shopping_* (bring_migrate_names kept)
- New settings tab 'Lista spesa' (tab-bring) with:
  - Enable/disable shopping list toggle
  - Provider radio: internal vs Bring!
  - Bring! sub-section (shown only when mode=bring)
  - AI smart suggestions toggle
  - Forecast toggle
  - Auto-add threshold (qty slider)
  - Price estimation section
- _applyShoppingSettingsUI, onShoppingEnabledChange, onShoppingModeChange
- SHOPPING_* env vars documented in .env.example
- cron_smart_shopping respects SHOPPING_MODE and SHOPPING_SMART_SUGGESTIONS
- Translations: 12 new keys in all 5 languages (it/en/de/fr/es)
- DB busy_timeout=5000ms + WAL pragma in getDB() (fixes #95)
2026-05-19 16:05:49 +00:00
dadaloop82 7364e75881 feat: Google Drive OAuth via http://localhost redirect (no public domain required)
- Switch redirect URI from server IP to http://localhost (works everywhere)
- Add manual code exchange flow: user copies URL from browser, pastes in app
- New PHP action gdrive_oauth_exchange to exchange auth code for refresh token
- Fix  null bug in gdrive_oauth_exchange (was read before initialization)
- Add #gdrive-code-section UI with input + submit button in index.html
- Update _gdriveAuthorize() to show code section and store redirect_uri
- Add _gdriveSubmitCode() JS function for manual code submission
- Update setup wizard and backup tab to show http://localhost as redirect URI
- Add 5 new translation keys (gdrive_redirect_uri_hint, gdrive_code_title,
  gdrive_code_hint, gdrive_code_submit, gdrive_code_empty) in all 5 languages
- Update gdrive_oauth_steps in all translations to reflect new flow
- Document Google Drive OAuth setup in README.md
- Dark mode: comprehensive fix for 30+ components with hardcoded light colors
2026-05-18 18:41:56 +00:00
dadaloop82 a58ef241e9 release: v1.7.23
- README: update feature callout to v1.7.23, add DB maintenance section,
  update dark mode description (time-based auto), add vacuum-sealed expiry
  paragraph, add new .env params (retention, vacuum, Gemini costs)
- CHANGELOG: add v1.7.23 entry (Generali tab, DB cleanup, vacuum expiry,
  AI tracking, time-based theme, ZeroWaste/screensaver save fix)
- manifest.json: version 1.7.22 → 1.7.23
- index.html: version label and preloader updated to v1.7.23; asset v=20260518c
2026-05-18 07:21:38 +00:00
dadaloop82 bd5d4bcac6 fix: dispensa.db auto-delete, zerowaste save, vacuum expiry, DB retention
- api/index.php: auto-delete legacy dispensa.db when evershelf.db exists
  and dispensa.db is empty (<1KB); vacuum-sealed items only show as
  expired after VACUUM_EXPIRY_EXTENSION_DAYS (default 30) past printed
  date; add dbCleanup() function; add recipe/tx/vacuum params to
  getServerSettings + saveSettings intMap; add 'db_cleanup' action
- api/cron_smart_shopping.php: run dbCleanup() each cron cycle
- app.js: add zerowaste_tips_enabled + screensaver_timeout + retention
  days to saveSettings POST payload (were missing, causing reset on sync);
  asset version bumped to v=20260518b
- .env: added ZEROWASTE_TIPS_ENABLED, RECIPE_RETENTION_DAYS=7,
  TRANSACTION_RETENTION_DAYS=7, VACUUM_EXPIRY_EXTENSION_DAYS=30
2026-05-18 07:16:26 +00:00
dadaloop82 c9a859463c feat: Generali tab, time-based auto theme, AI cost from real data
- index.html: new Generali tab (first, active) with Language/Currency/
  Theme/Screensaver/ZeroWaste/Export; old tab-language removed;
  screensaver timeout select uses form-input style; asset v=20260518a
- app.js: auto theme = time-based (20:00-07:00 dark, not system pref);
  removed matchMedia listener; added 5min setInterval for auto re-check;
  removed Bring! token row from Info tab (internal implementation detail)
- api/index.php: gemini_usage - removed all cache-estimation code;
  month/year_stats from ai_usage.json only
- data/ai_usage.json: data-driven baseline estimate for 2026-05:
  ~4.4M in + ~1.3M out from 8374 inferred historical calls (102 recipes,
  555 price lookups, getStats loop pre-fix, smart cron runs, etc.)
  = ~EUR 1.32 at 2.5-flash rates; new calls tracked precisely from now
- translations: settings.tab_general added; theme.auto updated to
  'Automatico (orario)' / 'Automatic (time of day)' / 'Automatisch (Tageszeit)'
2026-05-18 07:07:47 +00:00
dadaloop82 56e68b72f8 feat: Info tab v3 — clean month/year stats, currency to Info tab, Gemini costs from .env
- .env: GEMINI_COST_* rates configurable (4 new vars, defaults to current Google pricing)
- api/index.php: GEMINI_COST defines read from env() with fallback; added SHOPPING_NAME_CACHE_PATH
- api/index.php: gemini_usage output — clean month_stats/year_stats (no tracked/retro split)
  updated token estimates: price 700/250, shelf 650/120, cat 280/40, shopping_name 250/40
  added 'pricing' key to response (current rates); removed food_facts from estimate
- index.html: currency selector moved from tab-api to tab-info as first card (global setting)
- app.js: _renderInfoTab() rewritten — just month + year sections, no retro framing
  cost displayed in user's currency (price_currency) with expanded multi-currency conversion
- translations: settings.info.currency_title/hint/year_label added; retro/tracked keys removed
2026-05-18 06:45:56 +00:00
dadaloop82 cc0d9763ed feat: Info tab enriched — retroactive AI estimate, annual totals, inventory & activity stats
api/index.php:
- gemini_usage: retroactive AI call estimate from cache files (price/shelf/category)
  with per-entry token estimates (price ~475tok, shelf ~580tok, category ~230tok)
- yearly totals: sum tracked months + retro estimate for full 2026 view
- DB activity stats: products, inventory, transactions, expired, expiring_soon
- cache stats: price (255), shelf (30), category (7), foodfacts (10)
- system info: last backup timestamp+size, Bring! token expiry
- new constants: SHELF_CACHE_PATH, FOODFACTS_CACHE_PATH, BRING_TOKEN_PATH

assets/js/app.js:
- _renderInfoTab(): full rewrite — 4 cards (AI, Inventory, Activity, System)
- month displayed as localized name via Intl.DateTimeFormat (es. 'maggio 2026')
- tracked section shown when calls > 0; retro estimate always shown if gap exists
- year section: tracked + retro combined total
- pill() helper for consistent stat display

index.html: 4 cards with ids info-ai-content, info-inv-content, info-act-content, info-system-content

translations: updated settings.info.* keys in it/en/de (overview subtitle, retro labels, inv/act/system keys)
2026-05-18 06:33:59 +00:00
dadaloop82 9f554c6e22 feat: Gemini token usage counter (#82) + smarter qty suggestions 90-day EWMA (#70)
Backend (api/index.php):
- callGemini() now extracts usageMetadata (tokens_in/tokens_out) from response
- _recordAiUsage() persists monthly token data to data/ai_usage.json
- callGeminiWithFallback() accepts $usageAction param; all 15 call sites labeled
- gemini_usage endpoint: returns token stats, cost estimate, log info, DB size
- smartShopping(): rolling 90-day EWMA (70% last-30d / 30% days-31-90)
  with fallback to all-time rate when <14 days of history

Frontend (index.html + app.js):
- New Info tab (ℹ️) in Settings with Gemini usage and System cards
- _loadInfoTab() / _renderInfoTab(): loads on click, auto-refreshes every 30s
- switchSettingsTab() stops auto-refresh when leaving Info tab

Translations (it/en/de): settings.info.* keys
2026-05-18 06:23:42 +00:00