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:
2026-01-09 05:04:01 +00:00
parent 5707e42c0f
commit 32322f71dc
12 changed files with 1285 additions and 49 deletions

View File

@@ -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> {}