feat: implement recipe analysis service and data models
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
- Added RecipeAnalysisService to handle recipe ingredient analysis, including methods for checking ingredient availability and calculating quantities. - Introduced new TypeScript definitions for recipe analysis results, including ingredient status and summary. - Created corresponding Dart models for recipe analysis, including RecipeIngredientAnalysis, RecipeAnalysisSummary, and RecipeShoppingCandidate. - Updated Flutter UI to reflect changes in ingredient availability status. - Fixed color opacity issue in recipe image card.
This commit is contained in:
+176
-175
@@ -17,6 +17,7 @@ export declare class RecipesService {
|
||||
private readonly logger;
|
||||
constructor(prisma: PrismaService, aiService: AiService);
|
||||
private throwRecipeNotFound;
|
||||
private normalizeIngredientName;
|
||||
private assertProductsActive;
|
||||
private findRecipeByIdOrThrow;
|
||||
private assertAndClaimRecipeOwner;
|
||||
@@ -73,6 +74,8 @@ export declare class RecipesService {
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -80,54 +83,52 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
shares: {
|
||||
userId: number;
|
||||
}[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
})[]>;
|
||||
findOne(id: number, userId: number): Promise<{
|
||||
owner: {
|
||||
@@ -137,6 +138,8 @@ export declare class RecipesService {
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -144,59 +147,59 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
shares: {
|
||||
userId: number;
|
||||
}[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
update(id: number, updateRecipeDto: CreateRecipeDto, userId: number): Promise<{
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -204,51 +207,49 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
remove(id: number, userId: number): Promise<void>;
|
||||
updateImage(id: number, sourceUrl: string, userId: number): Promise<{
|
||||
@@ -259,6 +260,8 @@ export declare class RecipesService {
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -266,54 +269,52 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
shares: {
|
||||
userId: number;
|
||||
}[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
setVisibility(id: number, userId: number, isPublic: boolean): Promise<{
|
||||
owner: {
|
||||
@@ -323,6 +324,8 @@ export declare class RecipesService {
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -330,54 +333,52 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
shares: {
|
||||
userId: number;
|
||||
}[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
shareWithUser(id: number, ownerId: number, username: string): Promise<{
|
||||
owner: {
|
||||
@@ -387,6 +388,8 @@ export declare class RecipesService {
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -394,54 +397,52 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
shares: {
|
||||
userId: number;
|
||||
}[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
unshareWithUser(id: number, ownerId: number, username: string): Promise<{
|
||||
owner: {
|
||||
@@ -451,6 +452,8 @@ export declare class RecipesService {
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -458,59 +461,59 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
shares: {
|
||||
userId: number;
|
||||
}[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
create(createRecipeDto: CreateRecipeDto, userId: number): Promise<{
|
||||
ingredients: ({
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -518,55 +521,55 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
})[];
|
||||
} & {
|
||||
isPublic: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
instructions: string | null;
|
||||
imageUrl: string | null;
|
||||
servings: number | null;
|
||||
isPublic: boolean;
|
||||
ownerId: number | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}>;
|
||||
addIngredient(id: number, ingredient: CreateIngredientDto, userId: number): Promise<{
|
||||
product: ({
|
||||
nutrition: {
|
||||
id: number;
|
||||
productId: number;
|
||||
calories: number | null;
|
||||
protein: number | null;
|
||||
fat: number | null;
|
||||
@@ -574,38 +577,36 @@ export declare class RecipesService {
|
||||
salt: number | null;
|
||||
sugar: number | null;
|
||||
fiber: number | null;
|
||||
id: number;
|
||||
productId: number;
|
||||
} | null;
|
||||
} & {
|
||||
category: string | null;
|
||||
status: string;
|
||||
name: string;
|
||||
categoryId: number | null;
|
||||
canonicalName: string | null;
|
||||
id: number;
|
||||
normalizedName: string;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
name: string;
|
||||
ownerId: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
status: string;
|
||||
normalizedName: string;
|
||||
category: string | null;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
categoryId: number | null;
|
||||
isPrivate: boolean;
|
||||
}) | null;
|
||||
} & {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
recipeId: number;
|
||||
productId: number | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
rawName: string;
|
||||
rawLine: string | null;
|
||||
quantity: Prisma.Decimal | null;
|
||||
unit: string | null;
|
||||
note: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
matchConfidence: number | null;
|
||||
matchSource: string | null;
|
||||
alternativeProductIds: Prisma.JsonValue | null;
|
||||
recipeId: number;
|
||||
analysisStatus: string | null;
|
||||
}>;
|
||||
suggestRecipesFromInventory(userId: number): Promise<{
|
||||
|
||||
Reference in New Issue
Block a user