feat: add cookbook nesting and auto-filtering capabilities
Enables cookbooks to include other cookbooks and automatically organize content based on tags. This allows users to create hierarchical cookbook structures and maintain collections that automatically update as new content is added. Key features: - Cookbook nesting: Include child cookbooks within parent cookbooks - Auto-filtering by cookbook tags: Automatically include cookbooks matching specified tags - Auto-filtering by recipe tags: Automatically add recipes matching specified tags - Enhanced cookbook management UI with tag support - Comprehensive test coverage for new functionality Database schema updated with CookbookInclusion and CookbookTag tables. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -105,11 +105,111 @@ export interface Cookbook {
|
||||
coverImageUrl?: string;
|
||||
autoFilterCategories?: string[]; // Auto-add recipes matching these categories
|
||||
autoFilterTags?: string[]; // Auto-add recipes matching these tags
|
||||
autoFilterCookbookTags?: string[]; // Auto-add cookbooks matching these tags
|
||||
tags?: string[]; // Denormalized tag names for display
|
||||
recipeCount?: number; // Computed field for display
|
||||
cookbookCount?: number; // Computed field for display - count of included cookbooks
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CookbookWithRecipes extends Cookbook {
|
||||
recipes: Recipe[];
|
||||
cookbooks?: Cookbook[]; // Included cookbooks
|
||||
}
|
||||
|
||||
// Meal Planner Types
|
||||
export enum MealType {
|
||||
BREAKFAST = 'BREAKFAST',
|
||||
LUNCH = 'LUNCH',
|
||||
DINNER = 'DINNER',
|
||||
SNACK = 'SNACK',
|
||||
DESSERT = 'DESSERT',
|
||||
OTHER = 'OTHER'
|
||||
}
|
||||
|
||||
export interface MealPlan {
|
||||
id: string;
|
||||
userId?: string;
|
||||
date: Date | string;
|
||||
notes?: string;
|
||||
meals: Meal[];
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface Meal {
|
||||
id: string;
|
||||
mealPlanId: string;
|
||||
mealType: MealType;
|
||||
order: number;
|
||||
servings?: number;
|
||||
notes?: string;
|
||||
recipe?: MealRecipeWithDetails;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface MealRecipe {
|
||||
mealId: string;
|
||||
recipeId: string;
|
||||
}
|
||||
|
||||
export interface MealRecipeWithDetails extends MealRecipe {
|
||||
recipe: Recipe;
|
||||
}
|
||||
|
||||
export interface CreateMealPlanRequest {
|
||||
date: string;
|
||||
notes?: string;
|
||||
meals?: CreateMealRequest[];
|
||||
}
|
||||
|
||||
export interface CreateMealRequest {
|
||||
mealType: MealType;
|
||||
recipeId: string;
|
||||
servings?: number;
|
||||
notes?: string;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export interface UpdateMealPlanRequest {
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface UpdateMealRequest {
|
||||
mealType?: MealType;
|
||||
servings?: number;
|
||||
notes?: string;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export interface MealPlanQueryParams {
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
}
|
||||
|
||||
export interface ShoppingListItem {
|
||||
ingredientName: string;
|
||||
totalAmount: number;
|
||||
unit: string;
|
||||
recipes: string[];
|
||||
}
|
||||
|
||||
export interface ShoppingListRequest {
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
}
|
||||
|
||||
export interface ShoppingListResponse {
|
||||
items: ShoppingListItem[];
|
||||
dateRange: {
|
||||
start: string;
|
||||
end: string;
|
||||
};
|
||||
recipeCount: number;
|
||||
}
|
||||
|
||||
export interface MealPlanResponse extends ApiResponse<MealPlan> {}
|
||||
export interface MealPlansResponse extends ApiResponse<MealPlan[]> {}
|
||||
export interface ShoppingListApiResponse extends ApiResponse<ShoppingListResponse> {}
|
||||
|
||||
Reference in New Issue
Block a user