This commit is contained in:
Aerilyn Weber 2026-05-14 18:38:50 +09:00
parent 029940b079
commit e396f5088c
36 changed files with 4199 additions and 22 deletions

View file

@ -0,0 +1,131 @@
import { apiClient } from './api-client';
import type { z } from 'zod/v4';
import type {
MealPlanResponseSchema,
MealPlanListResponseSchema,
CreateMealPlanInput,
UpdateMealPlanInput,
MealPlanStatus,
} from '@meshitrack/shared';
export type MealPlanResponse = z.infer<typeof MealPlanResponseSchema>;
export type MealPlanListResponse = z.infer<typeof MealPlanListResponseSchema>;
export interface MealPlanQuery {
cursor?: string;
limit?: number;
}
export interface RecipeSuggestion {
recipeId: string;
recipeName: string;
totalScore: number;
scores: {
coverage: number;
urgency: number;
nutrition: number;
variety: number;
};
reasoning: string[];
}
export interface ShoppingGapReport {
mealPlanId: string;
missingItems: Array<{
productId: string;
productName: string;
category: string;
requiredQuantity: number;
pantryQuantity: number;
missingQuantity: number;
unit: string;
}>;
}
export async function listMealPlans(
householdId: string,
query?: MealPlanQuery
): Promise<MealPlanListResponse> {
const params = new URLSearchParams();
if (query?.cursor) params.set('cursor', query.cursor);
if (query?.limit) params.set('limit', String(query.limit));
const qs = params.toString();
return apiClient.get<MealPlanListResponse>(
`/households/${householdId}/meal-plans${qs ? `?${qs}` : ''}`
);
}
export async function getMealPlanByWeek(
householdId: string,
weekStartDate: string
): Promise<MealPlanResponse | { message: string }> {
return apiClient.get<MealPlanResponse | { message: string }>(
`/households/${householdId}/meal-plans/week/${weekStartDate}`
);
}
export async function getMealPlan(
householdId: string,
id: string
): Promise<MealPlanResponse> {
return apiClient.get<MealPlanResponse>(
`/households/${householdId}/meal-plans/${id}`
);
}
export async function createMealPlan(
householdId: string,
data: CreateMealPlanInput
): Promise<MealPlanResponse> {
return apiClient.post<MealPlanResponse>(
`/households/${householdId}/meal-plans`,
data
);
}
export async function updateMealPlan(
householdId: string,
id: string,
data: UpdateMealPlanInput
): Promise<MealPlanResponse> {
return apiClient.patch<MealPlanResponse>(
`/households/${householdId}/meal-plans/${id}`,
data
);
}
export async function updateMealPlanStatus(
householdId: string,
id: string,
status: MealPlanStatus
): Promise<MealPlanResponse> {
return apiClient.patch<MealPlanResponse>(
`/households/${householdId}/meal-plans/${id}/status`,
{ status }
);
}
export async function deleteMealPlan(
householdId: string,
id: string
): Promise<void> {
return apiClient.delete(`/households/${householdId}/meal-plans/${id}`);
}
export async function getSuggestions(
householdId: string,
limit = 5
): Promise<RecipeSuggestion[]> {
return apiClient.get<RecipeSuggestion[]>(
`/households/${householdId}/meal-plans/suggestions?limit=${limit}`
);
}
export async function getShoppingGap(
householdId: string,
id: string
): Promise<ShoppingGapReport> {
return apiClient.get<ShoppingGapReport>(
`/households/${householdId}/meal-plans/${id}/gap`
);
}

View file

@ -0,0 +1,45 @@
import { apiClient } from './api-client';
import type { z } from 'zod/v4';
import type {
NutritionTargetResponseSchema,
SetNutritionTargetInput,
} from '@meshitrack/shared';
export type NutritionTargetResponse = z.infer<typeof NutritionTargetResponseSchema>;
export async function getActiveNutritionTarget(
householdId: string
): Promise<NutritionTargetResponse | { message: string }> {
return apiClient.get<NutritionTargetResponse | { message: string }>(
`/households/${householdId}/nutrition-targets`
);
}
export async function getNutritionTargetHistory(
householdId: string
): Promise<NutritionTargetResponse[]> {
return apiClient.get<NutritionTargetResponse[]>(
`/households/${householdId}/nutrition-targets/history`
);
}
export async function setNutritionTarget(
householdId: string,
data: SetNutritionTargetInput
): Promise<NutritionTargetResponse> {
return apiClient.post<NutritionTargetResponse>(
`/households/${householdId}/nutrition-targets`,
data
);
}
export async function calculateTargetPreset(
householdId: string,
calories: number,
strategy: 'maintenance' | 'loss' | 'gain'
): Promise<SetNutritionTargetInput> {
return apiClient.post<SetNutritionTargetInput>(
`/households/${householdId}/nutrition-targets/presets`,
{ calories, strategy }
);
}