# Requisiti — CalorieTracker (Precision Vitality) > Documento di riferimento per tutti i requisiti funzionali e sistemistici del progetto. > Ultimo aggiornamento: 16/04/2026 --- ## Indice Requisiti | ID | Tipo | Priorità | Titolo | Dipendenze | |----|------|----------|--------|------------| | REQ-001 | SISTEMISTICO | CRITICA | Scaffolding Ionic + Capacitor | — | | REQ-002 | SISTEMISTICO | CRITICA | Setup Firebase Firestore | REQ-001 | | REQ-003 | EVOLUTIVO | ALTA | Home screen + FAB | REQ-002 | | REQ-004 | EVOLUTIVO | ALTA | Modal input numerico | REQ-003 | | REQ-005 | EVOLUTIVO | ALTA | Modal input LLM | REQ-003, REQ-006 | | REQ-006 | EVOLUTIVO | ALTA | Servizio Claude API | REQ-001 | | REQ-007 | EVOLUTIVO | ALTA | CRUD pasti Firestore | REQ-002 | | REQ-008 | EVOLUTIVO | MEDIA | Statistiche giornaliere | REQ-007 | | REQ-009 | EVOLUTIVO | MEDIA | Statistiche settimanali | REQ-007 | | REQ-010 | EVOLUTIVO | MEDIA | Ricerca pasti | REQ-007 | | REQ-011 | REWORK | MEDIA | Design brief Google Stitch | — | --- ## REQ-001 — Scaffolding Ionic + Capacitor **Tipo**: SISTEMISTICO | **Priorità**: CRITICA **Obiettivo**: Scaffolding del progetto Ionic 7+ con Capacitor 5+. Configurazione build nativa Android/iOS. Setup ambiente con struttura cartelle, linting e variabili d'ambiente. **Stato Target**: - Progetto Ionic Angular inizializzato con routing e tab layout (Journal, Stats, Plans, Profile) - Capacitor configurato per Android e iOS - Variabili ambiente: `ANTHROPIC_API_KEY`, `FIREBASE_*` - Struttura moduli: `core/`, `shared/`, `features/home`, `features/stats`, `features/search` - Proxy sviluppo configurato per CORS Anthropic API **Passi Implementativi**: 1. `ionic start calorie-tracker tabs --type=angular --capacitor` 2. Aggiungere `@capacitor/android` e `@capacitor/ios` 3. Configurare `capacitor.config.ts` con appId e server URL 4. Creare struttura moduli `features/` con lazy loading 5. Aggiungere `@ionic/storage-angular` per cache locale 6. Configurare `environment.ts` e `environment.prod.ts` 7. Verificare build `ionic build` + `npx cap sync` **Criteri Accettazione**: - [ ] `ionic serve` avvia l'app senza errori - [ ] `ionic build` produce `www/` senza errori - [ ] `npx cap sync` completa senza errori - [ ] Struttura a 4 tab visibile nel browser (Journal, Stats, Plans, Profile) - [ ] Variabili d'ambiente lette correttamente in `environment.ts` --- ## REQ-002 — Setup Firebase Firestore **Tipo**: SISTEMISTICO | **Priorità**: CRITICA | **Dipende da**: REQ-001 **Obiettivo**: Setup Firebase con Firestore come database. Schema dati, regole sicurezza e SDK Angular. **Schema Firestore**: ``` users/{userId}/ meals/{mealId}/ - id: string - timestamp: Timestamp - calories: number - inputType: 'manual' | 'llm' - description?: string - llmConfidence?: 'high' | 'medium' | 'low' - llmExplanation?: string - createdAt: Timestamp ``` **Regole Sicurezza**: - Lettura/scrittura solo all'utente autenticato proprietario - Nessun accesso cross-user **Auth**: Anonymous auth abilitato (upgrade Google Sign-In futuro) **Passi Implementativi**: 1. Creare Firebase project su console 2. Abilitare Firestore in modalità produzione 3. Abilitare Anonymous Authentication 4. Scaricare `google-services.json` e `GoogleService-Info.plist` 5. Installare `@angular/fire` e configurare in `app.module.ts` 6. Definire regole Firestore in `firestore.rules` 7. Creare `FirestoreService` con CRUD per collection `meals` 8. Testare lettura/scrittura da `ionic serve` **Criteri Accettazione**: - [ ] Scrittura documento su Firestore funzionante - [ ] Lettura documenti da Firestore funzionante - [ ] Regole sicurezza bloccano accesso non autenticato - [ ] `FirestoreService` espone: `addMeal()`, `getMealsByDate()`, `getMealsRange()` - [ ] Offline persistence abilitata e testata --- ## REQ-003 — Home Screen + FAB **Tipo**: EVOLUTIVO | **Priorità**: ALTA | **Dipende da**: REQ-002 **Obiettivo**: Home screen (tab Journal) con totale kcal giornaliero, lista pasti e FAB per aggiunta. **Specifiche UI** (da design Precision Vitality): - Header: data odierna centrata (es. "MERCOLEDÌ 16 APRILE") - Titolo: "Il tuo progresso giornaliero" - Numero kcal grande (56px, Lexend Bold, verde `#006b1b`) - Label "calorie oggi" - Barra progresso: kcal / obiettivo (default 2000) - Sezione "Diario Alimentare": lista card pasti (ora, descrizione, kcal) - Badge "AI" (arancione) o "M" (grigio) su ogni pasto - FAB arancione `#FF7043` in basso a destra con icona "+" - Empty state: "Nessun pasto registrato oggi. Inizia!" **Criteri Accettazione**: - [ ] Totale kcal odierno visibile e aggiornato real-time - [ ] Lista pasti del giorno visibile e scrollabile - [ ] FAB visibile e cliccabile su tutti i device - [ ] Empty state quando nessun pasto registrato - [ ] Aggiornamento immediato dopo salvataggio nuovo pasto --- ## REQ-004 — Modal Input Numerico **Tipo**: EVOLUTIVO | **Priorità**: ALTA | **Dipende da**: REQ-003 **Obiettivo**: Modal per inserimento diretto kcal con tastiera numerica. **Specifiche UI** (da design): - Titolo: "Inserisci calorie" - Icona fulmine verde - Motivazionale: "Ogni dato conta per il tuo obiettivo." - Campo numerico grande (font 40px), placeholder "0", label "KCAL" - Campo "Descrizione (opzionale)" - Bottone "Salva" verde a tutta larghezza - Suggerimenti veloci: 150 (Spuntino), 450 (Pranzo), 600 (Cena) **Validazione**: valore > 0 e ≤ 9999 **Criteri Accettazione**: - [ ] Modal si apre dal FAB - [ ] Tastiera numerica nativa su mobile - [ ] Validazione blocca valori ≤ 0 e > 9999 - [ ] Salvataggio corretto su Firestore - [ ] Toast conferma dopo salvataggio - [ ] Modal si chiude e Home aggiorna totale --- ## REQ-005 — Modal Input LLM (Descrizione Pasto) **Tipo**: EVOLUTIVO | **Priorità**: ALTA | **Dipende da**: REQ-003, REQ-006 **Obiettivo**: Modal per descrizione testuale del pasto con stima AI. **Specifiche UI** (da design): - Titolo: "Descrivi il pasto" - Sottotitolo: "Usa il linguaggio naturale per stimare i tuoi nutrienti in pochi secondi." - Textarea "IL TUO PASTO" con placeholder - Bottone "Stima calorie" arancione - Risultato: badge "ALTA PRECISIONE" / "MEDIA" / "BASSA" - Kcal stimate in grande + breakdown (carbi, proteine, grassi) - Campo kcal modificabile - Bottone "Salva" verde **Criteri Accettazione**: - [ ] Textarea accetta input testuale - [ ] Bottone "Stima calorie" chiama API (REQ-006) - [ ] Loading spinner durante chiamata - [ ] Risultato kcal e badge confidence corretti - [ ] Campo kcal modificabile dopo stima - [ ] Salvataggio su Firestore con `inputType: 'llm'` - [ ] Gestione errore timeout (messaggio + retry) --- ## REQ-006 — Servizio Claude API **Tipo**: EVOLUTIVO | **Priorità**: ALTA | **Dipende da**: REQ-001 **Obiettivo**: Servizio Angular per stima calorica via Claude API con proxy sicuro. **Architettura**: Firebase Cloud Function come proxy (API key mai nel bundle) **Specifiche**: - Model: `claude-haiku-4-5-20251001` - Max tokens: 256 - Food dictionary incluso nel system prompt - Parser JSON robusto (strip markdown code blocks) - Timeout: 10 secondi - Risposta: `{ calories, confidence, explanation }` **Criteri Accettazione**: - [ ] Stima kcal corretta per descrizioni test - [ ] Food dictionary nel system prompt - [ ] API key non nel bundle app - [ ] Parser gestisce JSON wrapped in markdown - [ ] Timeout 10s con errore esplicito --- ## REQ-007 — CRUD Pasti Firestore **Tipo**: EVOLUTIVO | **Priorità**: ALTA | **Dipende da**: REQ-002 **Obiettivo**: Servizio Angular per CRUD pasti su Firestore. **Metodi**: - `addMeal(data)` — scrittura con timestamp e userId - `getMealsForDate(date)` — query filtrata per giorno (Observable) - `getMealsInRange(from, to)` — query per range date - `deleteMeal(mealId)` — hard delete - `getTotalCaloriesForDate(date)` — aggregazione client-side **Criteri Accettazione**: - [ ] `addMeal()` scrive documento corretto - [ ] `getMealsForDate()` restituisce solo pasti del giorno richiesto - [ ] `getMealsInRange()` restituisce pasti nel range - [ ] `deleteMeal()` rimuove documento - [ ] Observable aggiorna componenti senza reload - [ ] Funziona offline --- ## REQ-008 — Statistiche Giornaliere **Tipo**: EVOLUTIVO | **Priorità**: MEDIA | **Dipende da**: REQ-007 **Obiettivo**: Vista giornaliera nel tab Stats con totale kcal, breakdown pasti e progresso obiettivo. **Specifiche UI**: - Tab selector: "Oggi" | "Settimana" - Navigazione tra giorni (frecce) - Totale kcal, barra progresso (verde/rosso) - Lista pasti con swipe-to-delete - Obiettivo calorico: salvato in @ionic/storage (default 2000) **Criteri Accettazione**: - [ ] Totale kcal giornaliero corretto - [ ] Navigazione tra giorni funzionante - [ ] Barra progresso aggiornata real-time - [ ] Colore cambia se obiettivo superato - [ ] Swipe-to-delete funzionante --- ## REQ-009 — Statistiche Settimanali **Tipo**: EVOLUTIVO | **Priorità**: MEDIA | **Dipende da**: REQ-007 **Obiettivo**: Grafico a barre 7 giorni con media settimanale. **Specifiche UI** (da design): - Periodo corrente (es. "14-20 apr") con frecce navigazione - Grafico barre: barre verdi ≤ obiettivo, rosse > obiettivo - Asse X: LUN, MAR, MER... (giorno corrente evidenziato) - Legenda: "In target" (verde), "Eccesso" (rosso) - Card "RIEPILOGO PRESTAZIONI": media kcal/giorno - Indicatori: variazione % vs settimana precedente, giorni in target **Criteri Accettazione**: - [ ] Grafico a barre con dati reali - [ ] Colori corretti sopra/sotto obiettivo - [ ] Media settimanale calcolata - [ ] Navigazione settimane funzionante - [ ] Tap su barra apre dettaglio giornaliero - [ ] Grafico responsive --- ## REQ-010 — Ricerca Pasti **Tipo**: EVOLUTIVO | **Priorità**: MEDIA | **Dipende da**: REQ-007 **Obiettivo**: Tab ricerca per trovare pasti passati per testo o intervallo date. **Specifiche**: - Searchbar con debounce 300ms - Filtro date opzionale (da/a) - Risultati: data, ora, kcal, descrizione, badge tipo - Funzione "Ri-registra": crea nuovo pasto con stesse kcal e timestamp corrente - Ordinamento: data DESC - Range: ultimi 30 giorni (client-side) **Criteri Accettazione**: - [ ] Ricerca per testo funzionante con debounce - [ ] Filtro date funzionante - [ ] Badge tipo visibili - [ ] "Ri-registra" crea nuovo documento - [ ] Empty state "Nessun risultato" --- ## REQ-011 — Design Brief Google Stitch **Tipo**: REWORK | **Priorità**: MEDIA **Stato**: COMPLETATO — I mockup sono disponibili in `stitch_calorietracker_design_brief_brief/` **Schermate generate**: 1. Home (Journal) — `home_calorietracker/` 2. Bottom sheet scelta input — `scelta_input_calorietracker/` 3. Modal input numerico — `inserisci_calorie_calorietracker/` 4. Modal descrizione LLM — `descrizione_ai_calorietracker/` 5. Statistiche settimanali — `statistiche_calorietracker/` **Design System**: `vitality_pulse/DESIGN.md`