Files
biteplan/CLAUDE.md
T
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

97 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
BitePlan è un'app Android per meal planning, conversione crudo/cotto e lista della spesa, scritta in Flutter. Tutta la UI e la UX sono in **italiano**. L'obiettivo finale è un APK Android buildabile via Docker.
## Comandi
```bash
# Sviluppo (web server con hot reload)
cd docker/dev && docker compose up
# → http://localhost:5173
# Con il container attivo: docker compose attach dev → r = hot reload
# Test (dalla root del progetto — richiede immagine biteplan-build)
docker run --rm -v "$(pwd):/workspace" -w /workspace biteplan-build \
bash -c "flutter pub get && flutter test"
# Test singolo file
docker run --rm -v "$(pwd):/workspace" -w /workspace biteplan-build \
bash -c "flutter test test/features/meal_planner/qr_test.dart"
# Build APK (headless, da host)
bash docker/build/build.sh # debug → dist/biteplan-debug.apk
bash docker/build/build.sh --release # release → dist/biteplan-release.apk
```
## Architettura
```
lib/
├── main.dart
├── app.dart # MaterialApp, NavigationBar, AppBar con bottone info
├── core/
│ ├── constants/app_constants.dart # kDayIds, kMealSlots, kStorageKey*, kAppVersion
│ └── theme/app_theme.dart
├── shared/
│ ├── services/storage_service.dart # wrapper SharedPreferences (load/save)
│ └── widgets/
├── features/
│ ├── meal_planner/
│ │ ├── models/meal_plan.dart # MealPlan, DayPlan
│ │ ├── providers/meal_planner_provider.dart
│ │ ├── qr_codec.dart # buildQrPayload, parseMealPlanFromQr
│ │ └── presentation/
│ │ ├── pages/meal_planner_page.dart
│ │ ├── pages/qr_scan_page.dart
│ │ └── widgets/meal_card.dart, qr_share_sheet.dart
│ ├── converter/
│ │ ├── models/conversion_entry.dart # rawToCooked, cookedToRaw (metodi sul model)
│ │ ├── providers/converter_provider.dart
│ │ └── presentation/pages/converter_page.dart
│ ├── shopping_list/
│ │ ├── models/shopping_item.dart # quantity per aggregazione duplicati
│ │ ├── providers/shopping_list_provider.dart
│ │ └── presentation/
│ │ ├── pages/shopping_list_page.dart
│ │ └── widgets/shopping_item_tile.dart
│ └── guide/
│ └── presentation/
│ ├── pages/guide_page.dart # 3 tab: Pasti, Converti, Spesa
│ └── widgets/info_bottom_sheet.dart # aperto dal bottone info in AppBar
└── assets/data/conversions.json # 50+ alimenti × metodi cottura
```
**State management**: Provider (`ChangeNotifier`).
**Persistenza**: `shared_preferences`, chiavi `meals` e `shopping_list` (JSON serializzato).
**Conversione**: logica in `ConversionEntry``rawToCooked = raw * yieldFactor`, `cookedToRaw = cooked / yieldFactor`.
**UI**: Material 3, seed color `Color(0xFF2d6a4f)`, tutto in italiano.
**QR**: payload JSON `{ "v": 1, "meals": { ... } }`, limite 2953 byte (capacità QR con error correction L).
## Testing
110 test (unit + widget). Non richiedono device fisico.
```
test/
├── helpers/pump_app.dart # estensione pumpApp per widget test
└── features/
├── converter/
│ ├── models/conversion_entry_test.dart
│ └── providers/converter_provider_test.dart
├── meal_planner/
│ ├── models/meal_plan_test.dart
│ ├── providers/meal_planner_provider_test.dart
│ ├── widgets/meal_card_test.dart
│ └── qr_test.dart
└── shopping_list/
├── models/shopping_item_test.dart
├── providers/shopping_list_provider_test.dart
└── widgets/shopping_item_tile_test.dart
```
I test usano `SharedPreferences.setMockInitialValues({})` per isolare lo storage.