From 2d6e4db390cd7eccfeb16529b7a381061ac354a4 Mon Sep 17 00:00:00 2001 From: Leon Morival Date: Thu, 21 May 2026 12:54:56 +0200 Subject: [PATCH] feat: ai prompt change --- app/Services/AiMealPostGenerator.php | 36 +++++++++++++++++++-- tests/Feature/GenerateAiMealPostTest.php | 40 ++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/app/Services/AiMealPostGenerator.php b/app/Services/AiMealPostGenerator.php index d92265f..b53e772 100644 --- a/app/Services/AiMealPostGenerator.php +++ b/app/Services/AiMealPostGenerator.php @@ -9,6 +9,7 @@ use App\Enums\MealPostVisibility; use App\Models\MealPosts; use App\Models\User; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; @@ -86,19 +87,48 @@ class AiMealPostGenerator private function mealPrompt(): string { - $season = now()->locale('fr')->translatedFormat('F'); + $recentMainIngredients = $this->recentMainIngredientsToAvoid(); + $avoidRecentIngredients = $recentMainIngredients === [] + ? '- Aucun ingredient recent a eviter pour cette generation.' + : '- Evite les ingredients principaux deja utilises dans les 10 derniers repas: '.implode(', ', $recentMainIngredients).'.'; return <<with([ + 'ingredients' => function (HasMany $query): void { + $query->where('position', '<=', 3); + }, + ]) + ->latest('eaten_at') + ->limit(10) + ->get() + ->flatMap(fn (MealPosts $mealPost): array => $mealPost->ingredients + ->pluck('ingredient') + ->all()) + ->map(fn (mixed $ingredient): string => $this->cleanString($ingredient, 255)) + ->filter() + ->unique(fn (string $ingredient): string => Str::lower($ingredient)) + ->values() + ->all(); + } + private function imagePrompt(array $draft): string { $prompt = $this->cleanString($draft['image_prompt'] ?? '', 1500); diff --git a/tests/Feature/GenerateAiMealPostTest.php b/tests/Feature/GenerateAiMealPostTest.php index 4e00008..7bf8dbf 100644 --- a/tests/Feature/GenerateAiMealPostTest.php +++ b/tests/Feature/GenerateAiMealPostTest.php @@ -19,6 +19,33 @@ it('generates an ai meal post with an image', function () { config()->set('meal_posts.ai_generation.image_path', 'meal-posts/ai-generated'); config()->set('meal_posts.ai_generation.image_quality', 'medium'); + foreach (range(1, 11) as $index) { + $mealPost = MealPosts::factory()->create([ + 'eaten_at' => now()->subMinutes(11 - $index), + ]); + + $mealPost->ingredients()->createMany([ + [ + 'position' => 1, + 'ingredient' => $index === 1 ? 'Topinambour ancien' : "Ingredient recent {$index}", + 'quantity' => 120, + 'unit' => IngredientUnit::GRAM->value, + ], + [ + 'position' => 2, + 'ingredient' => $index === 11 ? 'Asperges' : "Accompagnement recent {$index}", + 'quantity' => 80, + 'unit' => IngredientUnit::GRAM->value, + ], + [ + 'position' => 4, + 'ingredient' => "Garniture ignoree {$index}", + 'quantity' => 10, + 'unit' => IngredientUnit::GRAM->value, + ], + ]); + } + MealMaker::fake([ [ 'title' => 'Bowl de saumon croustillant', @@ -53,7 +80,10 @@ it('generates an ai meal post with an image', function () { $this->artisan('meal-posts:generate-ai') ->assertExitCode(0); - $mealPost = MealPosts::query()->with('user', 'ingredients')->firstOrFail(); + $mealPost = MealPosts::query() + ->where('ai_generated', true) + ->with('user', 'ingredients') + ->firstOrFail(); expect($mealPost->ai_generated)->toBeTrue() ->and($mealPost->title)->toBe('Bowl de saumon croustillant') @@ -75,7 +105,13 @@ it('generates an ai meal post with an image', function () { ]); MealMaker::assertPrompted( - fn ($prompt): bool => str_contains($prompt->prompt, 'Genere un plat aleatoire') + fn ($prompt): bool => str_contains($prompt->prompt, 'Genere un plat completement aleatoire') + && str_contains($prompt->prompt, 'sans tenir compte du mois actuel') + && str_contains($prompt->prompt, 'Evite les ingredients principaux deja utilises dans les 10 derniers repas') + && str_contains($prompt->prompt, 'Ingredient recent 2') + && str_contains($prompt->prompt, 'Asperges') + && ! str_contains($prompt->prompt, 'Topinambour ancien') + && ! str_contains($prompt->prompt, 'Garniture ignoree 11') ); Image::assertGenerated(