Files
traccia-calorica/docs/REQUIREMENTS.md
emanuele 7fd03a99ba chore: initial project setup with documentation and design assets
Add project foundation: CLAUDE.md, requirements tracking system,
technical architecture docs, Firestore setup guide, device testing guide,
and Stitch design mockups for Precision Vitality app.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:44:35 +02:00

313 lines
11 KiB
Markdown

# 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`