Commit Graph

85 Commits

Author SHA1 Message Date
davide 3da8ccc4d3 refactor: estrai showUpdateDialog e parseTagName in file dedicati
Sposta la logica del dialog in lib/shared/widgets/update_dialog.dart
per renderla importabile nei test senza duplicare il codice.
Estrae parseTagName come metodo @visibleForTesting in UpdateService
isolando il parsing JSON dalla chiamata HTTP. app.dart semplificato
di conseguenza.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 16:28:13 +02:00
davide 9486a70f1f test: aggiungi unit test per UpdateService
Copre parseVersion (semver standard, parti mancanti, valori non numerici)
e isNewer (patch/minor/major bump, versione uguale, versione più vecchia,
componenti multi-cifra come 2.0.10 > 2.0.9). 10/10 test passati su ARM64.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 16:18:00 +02:00
davide 296a622d82 feat: aggiungi controllo aggiornamenti con dialog all'avvio
All'avvio l'app chiama l'API GitHub releases per confrontare la versione
installata con l'ultima disponibile (comparazione semantica major.minor.patch).
Se esiste una versione più recente, mostra un AlertDialog con i pulsanti
"Più tardi" e "Scarica" — quest'ultimo apre releases/latest nel browser.
Il controllo è silenzioso in caso di assenza di rete o errori, e disabilitato
su Flutter web (dart:io non disponibile).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 16:17:53 +02:00
davide 0f1f585b4a feat(android): aggiungi permesso INTERNET e canale nativo per aprire URL
Aggiunge INTERNET permission e la query ACTION_VIEW/https richiesta da
Android 11+ per la package visibility. Espone il MethodChannel
'com.davide.biteplan/launcher' che lancia un Intent.ACTION_VIEW con
l'URL ricevuto, senza dipendere da plugin Flutter esterni.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 16:17:43 +02:00
davide 481ca86487 data: correggi yield bollitura per bieta, cavolfiore, finocchi e agretti
Valori aggiornati da misurazioni dirette (Muzzone 2024 + INRAN via matematicaincucina),
più accurati rispetto al proxy CREA kcal crudo/cotto usato in precedenza.
bieta 0.83→0.86 · cavolfiore 0.97→0.93 · finocchi 0.88→0.86 · agretti 0.88→0.86

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 00:06:15 +02:00
davide 48e15caf91 docs: aggiorna CLAUDE.md con build riproducibile e firma release
Aggiunge sezione "Build e firma" con: versione Flutter pinnata,
Gradle cache isolata, enforce-lockfile, gestione keystore/password,
vincolo applicationId e regola versionCode crescente.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:25:58 +02:00
davide c36fe32580 docs: aggiungi versione 2.0.0 al changelog e aggiorna conversioni.md
- Changelog: documenta la migrazione completa da Vue 3 + Capacitor a Flutter
- conversioni.md: corregge il path del file dati da src/data/ ad assets/data/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:18:15 +02:00
davide 3055b2a665 chore: rimuovi fallback flutter create e chiarisci gestione keystore
- Rimuove il blocco flutter create da build.sh: android/ è ora versionata
  con la configurazione corretta (com.davide.biteplan), il fallback era
  diventato codice morto con un --org errato
- Aggiorna docker/README.md: distingue collaboratore (riceve keystore
  dall'autore) da fork/uso personale (genera keystore proprio), spiega
  l'impatto sulla compatibilità degli aggiornamenti sui dispositivi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:13:54 +02:00
davide 72b50b4b3c chore: versiona cartella android/ e pubspec.lock
Rende il repo clonabile e buildabile da chiunque senza passi manuali:
- android/ rimosso da .gitignore: contiene applicationId, label, icone
  e MainActivity con il package corretto (com.davide.biteplan)
- pubspec.lock aggiunto: necessario per --enforce-lockfile nella build
- File generati/macchina-specifici già esclusi da android/.gitignore
  (.gradle/, local.properties, GeneratedPluginRegistrant.java)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:05:51 +02:00
davide 518c1d74a7 chore: allinea identità app Android alla v1.2.1 per aggiornamento diretto
- applicationId e namespace: com.biteplan.biteplan → com.davide.biteplan
- android🏷️ biteplan → BitePlan
- MainActivity.kt spostato nel package com.davide.biteplan
- versionCode: 1 → 10300 (superiore al 10201 della v1.2.1 Capacitor)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:04:11 +02:00
davide 85f62a8d66 build: correggi firma APK release non-interattiva
- Valida BITEPLAN_KEYSTORE_PASS prima della build e stampa istruzioni chiare
- Passa --ks-pass a apksigner tramite env var (stdin era chiuso nel container)
- Aggiunge rm -f su biteplan-aligned.apk prima di zipalign per evitare errori
  su run consecutive
- Documenta export BITEPLAN_KEYSTORE_PASS nel docker/README.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:04:00 +02:00
davide 5c871f247d build: rendi la build Docker riproducibile
- Pinna Flutter a 3.41.9 (ARG FLUTTER_VERSION) in entrambi i Dockerfile
- Aggiunge /opt/android-sdk/build-tools/34.0.0 al PATH (zipalign era missing)
- Sostituisce mount ${HOME}/.gradle con named volume gradle-cache
- Aggiunge --enforce-lockfile a flutter pub get per bloccare le dipendenze
- Aggiunge .flutter-version con la versione Flutter attesa

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:03:51 +02:00
davide 0e4925e61d refactor: riscrivi app in Flutter (da branch flutter)
Migrazione completa da Vue 3 + Vite a Flutter:
- rimossa sorgente Vue 3/Vite/Playwright
- app riscritta in Flutter con Material 3, Provider, SharedPreferences
- aggiunto supporto QR code per condivisione piano pasti
- aggregazione duplicati nella lista della spesa
- guida utente con 3 tab (Pasti, Converti, Spesa)
- containerizzazione Docker per dev e build APK
- suite di 110 test (unit + widget)
- ottimizzazioni APK: spazio e allocazioni a runtime

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:06:30 +02:00
davide 8d25f63f24 perf: riduci spazio APK e allocazioni a runtime
- Comprimi icon-only.png da 5.2 MB a 72 KB (512×512, quantizzazione 256 colori)
- Rimuovi setState() ridondante in ConverterPage.onChanged: search() chiama già notifyListeners()
- Cattura pendingItems/checkedItems in variabili locali nel build di ShoppingListPage per evitare filtraggio ripetuto a ogni paint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 00:01:49 +02:00
davide ca875d29c4 docs: allinea CLAUDE.md, README e docker/README al codice reale
CLAUDE.md: rimossi riferimenti a noVNC/Vue3/sop.md, aggiornata
architettura reale (features/*/presentation/), rimossi file fantasma
(checkbox_item.dart, conversion_service.dart), aggiunta feature guide,
corretta struttura test, aggiornati comandi Docker.

README.md: riscritto per Flutter (rimosso stack Vue3/Node.js), aggiunta
sezione test con comandi e struttura cartelle, link docs/.

docker/README.md: aggiunta sezione test completa con comandi per tutti
i test, singolo file e singola feature; aggiornato flusso completo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:39:00 +02:00
davide 65214ac34e test: espandi copertura a 110 test e organizza in gruppi
- Aggiunto converter_provider_test.dart (nuovo): stato iniziale, select,
  setGrams, result, swapDirection, reset, search
- Aggiunto qr_test.dart (nuovo): buildQrPayload e parseMealPlanFromQr
  con round-trip e casi di errore
- meal_planner_provider_test: group(), importPlan(), fallback JSON corrotto
- shopping_list_provider_test: group(), addAll con aggregazione quantity,
  fallback JSON corrotto
- shopping_item_test: campi quantity (default, copyWith, JSON round-trip)
- shopping_item_tile_test: group(), visualizzazione (xN)
- conversion_entry_test: caso limite yieldFactor=0
- meal_card_test: group()
- Rimosso widget_test.dart (boilerplate obsoleto)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:27:19 +02:00
davide 9fcaae9687 fix(shopping_list): genera ID univoci in ShoppingListProvider
add() usava millisecondsSinceEpoch come ID: chiamate ravvicinate nello
stesso millisecondo producevano ID identici, causando toggle e remove
incorretti su più elementi. Introdotto _idSeq come contatore progressivo,
allineato all'approccio già usato in addAll().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:27:04 +02:00
davide 49e7bcdbfa refactor(meal_planner): estrai logica QR in qr_codec.dart
buildQrPayload e parseMealPlanFromQr erano metodi privati non testabili.
Estratti in un modulo dedicato e importati da qr_share_sheet e qr_scan_page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:26:55 +02:00
davide 9c24651ec2 fix: aggiungi permesso CAMERA e correggi sed in AndroidManifest.xml
build.sh: il permesso CAMERA viene iniettato dentro il container
Docker subito dopo flutter create (sed gira come root, evita il
problema di permessi su android/ owned by root).

entrypoint.sh: stesso approccio, sed eseguito già dentro il container.

Il sed inserisce <uses-permission android:name="android.permission.CAMERA" />
prima di <application>, posizione corretta nel manifest Android.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:09:26 +02:00
davide cebeaf889a feat: condivisione piano pasti via QR code
Porta la funzionalità QR code dalla versione Vue a Flutter.

Condividi: pulsante in fondo alla tab Pasti (attivo solo con piano
non vuoto) → bottom sheet con QR code generato da qr_flutter.
Payload: { "v": 1, "meals": { ... } }, limite 2953 byte.

Ricevi: pulsante sempre visibile → QrScanPage full-screen con
fotocamera via mobile_scanner, cornice di mira, validazione
struttura JSON e importazione via MealPlannerProvider.importPlan().

Nuovi package: qr_flutter ^4.1.0, mobile_scanner ^5.0.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:09:16 +02:00
davide 404a5f44ac feat: aggrega duplicati nella lista della spesa con quantità
Quando si genera la lista dal piano pasti, gli alimenti ripetuti in
più giorni o slot vengono aggregati in un unico elemento con contatore.
Es. zucchine lunedì + mercoledì → "zucchine (x2)".

- ShoppingItem: aggiunto campo quantity (default 1, persistito in JSON)
- ShoppingListProvider.addAll: conta le occorrenze per nome
  (case-insensitive) e crea un ShoppingItem con quantity = conteggio
- ShoppingItemTile: mostra "(xN)" colorato in primary quando quantity > 1,
  diventa muted insieme al nome quando l'elemento è completato

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 18:54:22 +02:00
davide cba83c9559 feat: aggiungi guida utente e icona launcher
Guida utente:
- Pulsante info nell'AppBar principale
- InfoBottomSheet: icona app, versione, autore, licenza, link alla guida
- GuidePage: tre tab (Pasti / Converti / Spesa) con card e step numerati,
  portata dalla DocsPanel Vue originale

AppBar globale in app.dart con titolo dinamico per tab corrente.

Icona launcher:
- flutter_launcher_icons eseguito in build.sh prima di flutter build apk
  (sia debug che release) per applicare assets/icon-only.png all'APK.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 18:38:02 +02:00
davide 36e8034efd feat: aggiungi container Docker dev e build per Flutter
docker/build/: build headless APK Android
- Dockerfile: Ubuntu 22.04 + Java 17 + Flutter stable + Android SDK
- build.sh: genera android/ automaticamente se mancante, poi
  flutter build apk; --release aggiunge zipalign + apksigner

docker/dev/: ambiente di sviluppo web con hot reload
- Dockerfile: Ubuntu 22.04 + Flutter stable (solo web, senza Android SDK)
- docker-compose.yml: espone porta 5173, monta il progetto come volume
- entrypoint.sh: inizializza web/ se mancante, flutter pub get,
  flutter run -d web-server su 0.0.0.0:5173

docker/README.md: documentazione aggiornata per entrambi i container;
rimossi Dockerfile e build.sh Vue/Capacitor non più usati.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 18:25:48 +02:00
davide aa88e2095b chore: aggiorna .gitignore e CLAUDE.md per Flutter
.gitignore: aggiunti scaffold Flutter (/android/, /ios/, /web/, ecc.),
file IDE (/.idea/, *.iml), .metadata; corretto /build/ (solo root).

CLAUDE.md: aggiornato con architettura Flutter, comandi dev/build/test
e stato avanzamento roadmap (checklist SOP).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 17:41:45 +02:00
davide 9a865a1479 test: aggiungi suite di test Flutter
Struttura specchia lib/features/:
- test/features/meal_planner/ — unit (DayPlan, MealPlan, provider) + widget (MealCard)
- test/features/converter/ — unit (ConversionEntry, formule rawToCooked/cookedToRaw)
- test/features/shopping_list/ — unit (ShoppingItem, provider) + widget (ShoppingItemTile)
- test/helpers/pump_app.dart — estensione PumpApp condivisa tra widget test
- integration_test/app_test.dart — e2e navigazione, shopping list, convertitore, meal planner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 17:41:38 +02:00
davide eb7912421c feat: riscrivi app in Flutter
Riscrittura completa da Vue 3 + Capacitor a Flutter/Dart.

Architettura feature-based (lib/features/):
- meal_planner: modello MealPlan/DayPlan, provider, pagina e widget
- converter: modello ConversionEntry, provider con ricerca, pagina
- shopping_list: modello ShoppingItem, provider con deduplicazione, pagina e widget

Core:
- Material 3 con seed color #2d6a4f
- NavigationBar + IndexedStack (preserva stato dei tab)
- Portrait lock via SystemChrome
- Persistenza con shared_preferences
- 50+ alimenti × metodi cottura in assets/data/conversions.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 17:41:26 +02:00
davide d49b31f21d chore: rimuovi sorgente Vue 3, Vite e Playwright
Il progetto viene riscritto in Flutter. Eliminati tutti i file
Vue 3 (src/, tests/, public/), le configurazioni Vite/Vitest e
i test Playwright che non saranno più mantenuti.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 17:41:14 +02:00
davide 3f79e30ecd chore: aggiorna SOP e CLAUDE.md per migrazione a Flutter
Riscritto sop.md con stack Flutter + Docker (container dev noVNC +
container build headless). Aggiornato CLAUDE.md con roadmap, architettura
target e mapping Vue→Flutter come riferimento per la riscrittura.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:43:26 +02:00
davide 6293743fa1 chore: aggiungi CLAUDE.md e rimuovi skill UX locale
Aggiunta documentazione per Claude Code (comandi, architettura, testing,
pipeline Android). Rimossa la skill UX da .claude/skills/ non più necessaria.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:38:23 +02:00
davide febf2efb86 chore: bump version a 1.2.1 e aggiorna changelog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 18:47:11 +02:00
davide 47f4bcba28 feat: blocca orientamento in portrait su APK e browser
- Dockerfile: aggiunge android:screenOrientation="portrait" all'activity
  in AndroidManifest.xml per bloccare il portrait nativamente sull'APK
- App.vue: fixOrientation() rileva il landscape tramite dimensioni viewport
  e applica un counter-rotate CSS in modo che l'app rimanga visivamente
  in portrait anche da browser mobile (dev server)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 18:41:22 +02:00
davide 3bd2b04a06 chore: bump version to 1.2.0 e aggiorna changelog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:32:45 +02:00
davide f1bfa9a88c feat: aggiungi pulsante svuota piano settimanale
- Sposta .btn-clear da ShoppingList.vue (scoped) a style.css (globale)
- Aggiunge hasMeals, clearAll e btn-clear in MealPlanner.vue
- Aggiunge 4 test di integrazione per il nuovo pulsante

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:28:07 +02:00
davide cc866ae78c fix: aggiorna vite a 6.4.2 (path traversal, arbitrary file read)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:27:52 +02:00
davide 36cd84f32e chore: bump version to 1.1.0 e aggiorna documentazione
- package.json: versione 1.0.0 → 1.1.0
- CHANGELOG.md: aggiunta sezione [1.1.0]
- docs/guida-utente.md: aggiunte sezioni QR code condivisione/ricezione
- src/components/DocsPanel.vue: aggiunte card condivisione e ricezione piano
2026-04-02 23:06:32 +02:00
davide d79ce06278 feat: condivisione piano pasti via QR code
Merge branch 'qrcode'
2026-03-31 10:44:54 +02:00
davide 55257f849d fix: aggiungi permesso CAMERA all'AndroidManifest.xml generato da Capacitor 2026-03-31 10:44:09 +02:00
davide 7dd1bce80f chore: merge main nel branch qrcode (fix vulnerabilità npm)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:20:03 +02:00
davide 9b099dac83 fix: risolvi 6 vulnerabilità npm aggiornando vite e vitest
- Upgrade vite 5 → 6 (fix GHSA-67mh-4wv8-2f99: esbuild CORS dev server)
- Upgrade vitest 2 → 3 e @vitest/coverage-v8 2 → 3
- Rinomina vite.config.js → vite.config.mjs (richiesto da vite 6 ESM)
- Aggiorna requisito Node.js in README: 18.x → >= 20.x LTS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:15:55 +02:00
davide 8685ea0aca feat: condivisione piano pasti via QR code
Aggiunge due pulsanti in fondo alla schermata Piano Pasti:
- "Condividi": genera un QR code con i dati della settimana
- "Ricevi": apre la fotocamera per scansionare il QR e importare il piano

Dipendenze aggiunte: qrcode, jsqr

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 23:13:21 +02:00
davide 7a63706af5 chore: aggiorna versione a 1.0.0 e CHANGELOG
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 12:16:45 +01:00
davide 5df7956069 fix: crea dist/ prima del docker run per evitare ownership root
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 11:57:33 +01:00
davide 76cf672d80 fix: APK con --head ora copiato in dist/ invece di andare perso nella tmpdir
Con --head la DIST_DIR puntava alla directory temporanea che veniva cancellata
dal trap EXIT prima che l'utente potesse recuperare l'APK. L'APK viene ora
copiato esplicitamente in PROJECT_ROOT/dist/ dopo il docker run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 11:50:55 +01:00
davide 96f75df6f2 feat: supporto build APK release firmato nella pipeline Docker
- Dockerfile: CMD condizionale su BUILD_TYPE (debug default, release con
  assembleRelease + zipalign + apksigner)
- build.sh: flag --release, richiesta password interattiva, mount keystore
  come volume read-only (mai nell'immagine)
- .gitignore: aggiunto *.jks
- docker/README.md: documentazione build debug/release, keytool, flag combinabili

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 10:10:43 +01:00
davide 0c2a227be2 chore: aggiorna versione a 0.9.1 e CHANGELOG
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:47:57 +01:00
davide e10bb2df4c test: aggiungi suite completa unit, integration ed e2e
- Unit (12+9): conversion.js (rawToCooked/cookedToRaw, edge case, inversa)
  e storage.js (save/load, round-trip, default fallback)
- Integration (17+12+14): Converter (ricerca, selezione, calcolo, swap, reset),
  MealPlanner (rendering, add/remove, generateShopping, deduplicazione),
  ShoppingList (add, toggle, remove, clearAll, contatore)
- E2E Playwright (6+6+7+10): navigation, meal-planner, converter, shopping-list
- Configurazione: vitest.config.js + playwright.config.js + tests/setup.js
- Script: test, test:coverage, test:e2e, test:e2e:ui

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:45:31 +01:00
davide 09c9706938 docs: aggiungi requisiti di sviluppo al README
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:35:11 +01:00
davide ecbae836b3 feat: guida utente in-app e fix grafici Convertitore
- DocsPanel: pannello documentazione slide-from-right con nav a pill,
  IntersectionObserver per sezione attiva, card con step numerati e callout tip
- InfoPanel: bottone "Guida" emette open-docs invece di aprire link esterno
- App: integra DocsPanel con v-model showDocs
- Converter: fix capitalize food names (capFirst invece di text-transform),
  simmetria visiva input/output (stesso underline e font-size 1.6rem),
  rimosso CSS morto (doppio align-items, doppio background, visibility hack)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:32:36 +01:00
davide f24e591ca0 docs: riscrivi guida utente allineata allo stato attuale dell'app
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:10:00 +01:00
davide eef38a74cc Merge branch 'new-logo' 2026-03-27 14:07:32 +01:00