Files
traccia-calorica/docs/TECHNICAL.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

293 lines
9.0 KiB
Markdown

# Requisiti Tecnici — CalorieTracker (Precision Vitality)
> Documento di architettura e decisioni tecniche del progetto.
> Ultimo aggiornamento: 16/04/2026
---
## 1. Panoramica Architettura
```
┌─────────────────────────────────────────────┐
│ App Ionic/Angular │
│ ┌───────────┐ ┌───────────┐ ┌─────────┐ │
│ │ Journal │ │ Stats │ │ Search │ │
│ │ (Home) │ │ Day/Week │ │ │ │
│ └─────┬─────┘ └─────┬─────┘ └────┬────┘ │
│ │ │ │ │
│ ┌─────┴───────────────┴─────────────┴────┐ │
│ │ Core Services Layer │ │
│ │ MealService | CalorieEstimator | Auth │ │
│ └─────┬───────────────┬─────────────────┘ │
│ │ │ │
└────────┼───────────────┼────────────────────┘
│ │
┌────┴────┐ ┌──────┴──────┐
│Firestore│ │ Firebase CF │
│ (DB) │ │ (Proxy AI) │
└─────────┘ └──────┬──────┘
┌──────┴──────┐
│ Anthropic │
│ Claude API │
└─────────────┘
```
---
## 2. Stack Tecnologico
| Layer | Tecnologia | Versione | Motivazione |
|-------|------------|----------|-------------|
| Framework UI | Ionic | 7+ | Cross-platform, componenti nativi |
| Framework App | Angular | 17+ | Standalone components, signals |
| Mobile Runtime | Capacitor | 5+ | Build nativo Android/iOS |
| Database | Firebase Firestore | 10+ | Free tier, offline, real-time |
| Auth | Firebase Auth | 10+ | Anonymous + Google Sign-In |
| AI Proxy | Firebase Cloud Functions | Gen2 | Free tier, sicurezza API key |
| AI Model | Claude Haiku 4.5 | claude-haiku-4-5-20251001 | Economico, veloce, sufficiente per stime |
| Chart | Chart.js + ng2-charts | 4+ | Leggero (~200KB), well-maintained |
| Storage locale | @ionic/storage-angular | 4+ | Preferenze utente (obiettivo kcal) |
| Linguaggio | TypeScript | 5.3+ | Type safety |
---
## 3. Requisiti Ambiente di Sviluppo
| Requisito | Versione Minima | Note |
|-----------|-----------------|------|
| Node.js | 18+ | LTS raccomandato |
| npm | 9+ | Incluso con Node.js |
| Ionic CLI | 7+ | `npm i -g @ionic/cli` |
| Angular CLI | 17+ | Incluso come dipendenza |
| Java JDK | 17+ | Per build Android (Gradle) |
| Android SDK | API 33+ | Per build APK |
---
## 4. Configurazione Variabili d'Ambiente
### `environment.ts` (development)
```typescript
export const environment = {
production: false,
firebase: {
apiKey: '...',
authDomain: '...',
projectId: '...',
storageBucket: '...',
messagingSenderId: '...',
appId: '...'
},
cloudFunctionUrl: 'http://localhost:5001/PROJECT_ID/us-central1/estimateCalories',
defaultCalorieTarget: 2000
};
```
### `environment.prod.ts` (production)
```typescript
export const environment = {
production: true,
firebase: { /* config produzione */ },
cloudFunctionUrl: 'https://us-central1-PROJECT_ID.cloudfunctions.net/estimateCalories',
defaultCalorieTarget: 2000
};
```
**IMPORTANTE**: I file `environment.*.ts` sono nel `.gitignore`. Usare `environment.example.ts` come template.
---
## 5. Firebase Cloud Function — Proxy AI
### Architettura
```
Client → Cloud Function → Anthropic API → Cloud Function → Client
```
### Endpoint
- **URL**: `POST /estimateCalories`
- **Body**: `{ description: string }`
- **Response**: `{ calories: number, confidence: 'high'|'medium'|'low', explanation: string }`
- **Auth**: Firebase Auth token required (header `Authorization: Bearer <token>`)
### Implementazione Cloud Function
```typescript
// functions/src/index.ts
import { onRequest } from 'firebase-functions/v2/https';
import Anthropic from '@anthropic-ai/sdk';
export const estimateCalories = onRequest(
{ cors: true, region: 'europe-west1' },
async (req, res) => {
// 1. Verificare Firebase Auth token
// 2. Estrarre description dal body
// 3. Chiamare Claude con food dictionary nel system prompt
// 4. Parsare risposta JSON
// 5. Restituire risultato
}
);
```
### Sicurezza
- API key Anthropic in Secret Manager di Firebase
- Rate limiting: max 10 richieste/minuto per utente
- Validazione input: description max 500 caratteri
- Timeout: 10 secondi
---
## 6. Schema Dati Firestore
### Collection `users/{userId}/meals/{mealId}`
| Campo | Tipo | Obbligatorio | Descrizione |
|-------|------|-------------|-------------|
| id | string | Sì | Auto-generated document ID |
| timestamp | Timestamp | Sì | Data/ora del pasto |
| calories | number | Sì | Kcal totali |
| inputType | string | Sì | `'manual'` o `'llm'` |
| description | string | No | Descrizione testuale |
| llmConfidence | string | No | `'high'`, `'medium'`, `'low'` (solo se llm) |
| llmExplanation | string | No | Spiegazione AI (solo se llm) |
| createdAt | Timestamp | Sì | Data creazione documento |
### Indici Richiesti
```
Collection: users/{userId}/meals
- (timestamp DESC) — per query giornaliere e range
```
---
## 7. Servizi Angular Core
### `AuthService`
```typescript
- signInAnonymously(): Promise<User>
- getCurrentUser(): Observable<User | null>
- getUserId(): string
```
### `MealService`
```typescript
- addMeal(data: MealInput): Promise<string>
- getMealsForDate(date: Date): Observable<Meal[]>
- getMealsInRange(from: Date, to: Date): Observable<Meal[]>
- deleteMeal(mealId: string): Promise<void>
- getTotalCaloriesForDate(date: Date): Observable<number>
```
### `CalorieEstimatorService`
```typescript
- estimateCalories(description: string): Observable<CalorieEstimate>
```
### `StorageService`
```typescript
- getCalorieTarget(): Promise<number>
- setCalorieTarget(target: number): Promise<void>
```
---
## 8. Interfacce TypeScript
```typescript
interface Meal {
id: string;
timestamp: Date;
calories: number;
inputType: 'manual' | 'llm';
description?: string;
llmConfidence?: 'high' | 'medium' | 'low';
llmExplanation?: string;
createdAt: Date;
}
interface MealInput {
calories: number;
inputType: 'manual' | 'llm';
description?: string;
llmConfidence?: 'high' | 'medium' | 'low';
llmExplanation?: string;
}
interface CalorieEstimate {
calories: number;
confidence: 'high' | 'medium' | 'low';
explanation: string;
}
```
---
## 9. Design System — Mapping Tecnico
### Colori (CSS Custom Properties)
```css
:root {
--pv-primary: #006b1b;
--pv-primary-dim: #005d16;
--pv-accent: #FF7043;
--pv-error: #F44336;
--pv-surface: #f6f6f6;
--pv-surface-container-low: #f0f1f1;
--pv-surface-container-lowest: #ffffff;
--pv-on-surface: #2d2f2f;
--pv-on-surface-variant: #757575;
}
```
### Font (da importare)
```css
@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@400;700&family=Plus+Jakarta+Sans:wght@400;500;600&display=swap');
:root {
--pv-font-data: 'Lexend', sans-serif;
--pv-font-ui: 'Plus Jakarta Sans', sans-serif;
}
```
### Regole Chiave
1. **No borders** — separazione solo via background shifts
2. **No drop shadows su card** — usare tonal layering
3. **Border radius**: `1.5rem` (card principali), `1rem` (elementi nested)
4. **Spacing**: `24px` vertical padding nelle card
5. **Progress bar**: `12px` altezza, full roundedness, gradient `primary-fixed → primary`
6. **FAB**: gradient `primary → primary-dim` a 135°, shadow `0px 12px 32px rgba(0,107,27,0.15)`
---
## 10. Performance e Limiti
### Firestore (Spark Plan — Gratuito)
- 50.000 letture/giorno
- 20.000 scritture/giorno
- 1 GiB storage
- 10 GiB trasferimento/mese
### Claude API (Haiku)
- ~$0.25 per 1M input tokens
- ~$1.25 per 1M output tokens
- Stima: ~$0.001 per richiesta singola
- Budget suggerito: $5/mese per uso moderato
### Ottimizzazioni
- Cache locale food dictionary (caricato una volta)
- Observable Firestore per real-time (no polling)
- Lazy loading moduli Angular
- Offline persistence Firestore per uso senza rete
---
## 11. Sicurezza
| Rischio | Mitigazione |
|---------|-------------|
| API key Anthropic esposta | Firebase Cloud Function come proxy |
| Accesso dati cross-user | Firestore Security Rules basate su userId |
| Input injection nell'LLM | Sanitizzazione input + max 500 caratteri |
| Firebase config nel bundle | Le Firebase config sono safe da esporre (solo project identifier) |
| Rate abuse | Rate limiting nella Cloud Function (10 req/min/user) |