diff --git a/apps/mana/apps/web/src/lib/modules/nutriphi/api.ts b/apps/mana/apps/web/src/lib/modules/nutriphi/api.ts index 99b64a778..a721bc6f5 100644 --- a/apps/mana/apps/web/src/lib/modules/nutriphi/api.ts +++ b/apps/mana/apps/web/src/lib/modules/nutriphi/api.ts @@ -9,7 +9,11 @@ import { authStore } from '$lib/stores/auth.svelte'; import { getManaApiUrl } from '$lib/api/config'; -import type { NutritionData } from './types'; +// Wire format is the single source of truth in @mana/shared-types — +// the backend validates AI responses with these same Zod schemas. +import type { MealAnalysis } from '@mana/shared-types'; + +export type MealAnalysisResult = MealAnalysis; export interface UploadMealPhotoResult { mediaId: string; @@ -18,21 +22,6 @@ export interface UploadMealPhotoResult { storagePath: string; } -export interface AnalyzedFood { - name: string; - quantity?: string; - calories?: number; -} - -export interface MealAnalysisResult { - foods?: AnalyzedFood[]; - totalNutrition?: NutritionData; - description?: string; - confidence?: number; - warnings?: string[]; - suggestions?: string[]; -} - async function authHeader(): Promise> { const token = await authStore.getAccessToken(); return token ? { Authorization: `Bearer ${token}` } : {}; diff --git a/apps/mana/apps/web/src/lib/modules/nutriphi/types.ts b/apps/mana/apps/web/src/lib/modules/nutriphi/types.ts index b06b02c9b..fcec12449 100644 --- a/apps/mana/apps/web/src/lib/modules/nutriphi/types.ts +++ b/apps/mana/apps/web/src/lib/modules/nutriphi/types.ts @@ -1,28 +1,21 @@ /** * NutriPhi module types for the unified app. + * + * NutritionData and AnalyzedFood are re-exported from @mana/shared-types + * because they double as the AI wire format (same Zod schema lives in + * packages/shared-types/src/ai-schemas.ts and is used by the backend + * generateObject() validator). Module-local types like LocalMeal compose + * those shared shapes with storage-specific BaseRecord fields. */ import type { BaseRecord } from '@mana/local-store'; +import type { NutritionData, AnalyzedFood } from '@mana/shared-types'; + +export type { NutritionData, AnalyzedFood }; export type MealType = 'breakfast' | 'lunch' | 'dinner' | 'snack'; export type InputType = 'photo' | 'text'; -export interface NutritionData { - calories: number; - protein: number; - carbohydrates: number; - fat: number; - fiber: number; - sugar: number; -} - -/** A single food item identified by Gemini Vision in a meal photo. */ -export interface AnalyzedFood { - name: string; - quantity?: string | null; - calories?: number | null; -} - export interface LocalMeal extends BaseRecord { date: string; mealType: MealType; diff --git a/apps/mana/apps/web/src/lib/modules/planta/api.ts b/apps/mana/apps/web/src/lib/modules/planta/api.ts index 10e130c34..01d1560f2 100644 --- a/apps/mana/apps/web/src/lib/modules/planta/api.ts +++ b/apps/mana/apps/web/src/lib/modules/planta/api.ts @@ -8,6 +8,11 @@ import { authStore } from '$lib/stores/auth.svelte'; import { getManaApiUrl } from '$lib/api/config'; +// Wire format is the single source of truth in @mana/shared-types — +// the backend validates AI responses with the same Zod schema. +import type { PlantIdentification } from '@mana/shared-types'; + +export type IdentifyResult = PlantIdentification; export interface UploadPhotoResult { storagePath: string; @@ -16,16 +21,6 @@ export interface UploadPhotoResult { plantId: string | null; } -export interface IdentifyResult { - scientificName?: string; - commonNames?: string[]; - confidence?: number; - healthAssessment?: string; - wateringAdvice?: string; - lightAdvice?: string; - generalTips?: string[]; -} - async function authHeader(): Promise> { const token = await authStore.getAccessToken(); return token ? { Authorization: `Bearer ${token}` } : {};