AI Analysis: enforce 7-day rate limit per candidate

This commit is contained in:
jeremy bayse
2026-03-25 19:02:26 +01:00
parent 40c8aa2e5a
commit 7a05b7e6b3
4 changed files with 22 additions and 32 deletions

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Models\Candidate; use App\Models\Candidate;
use App\Services\AIAnalysisService; use App\Services\AIAnalysisService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Carbon\Carbon;
class AIAnalysisController extends Controller class AIAnalysisController extends Controller
{ {
@@ -21,6 +22,16 @@ class AIAnalysisController extends Controller
abort(403); abort(403);
} }
// Restriction: Une analyse tous les 7 jours maximum par candidat
if ($candidate->ai_analysis && isset($candidate->ai_analysis['analyzed_at'])) {
$lastAnalysis = Carbon::parse($candidate->ai_analysis['analyzed_at']);
if ($lastAnalysis->diffInDays(now()) < 7) {
return response()->json([
'error' => "Une analyse a déjà été effectuée il y a moins de 7 jours. Merci de patienter avant de relancer l'IA."
], 422);
}
}
try { try {
$analysis = $this->aiService->analyze($candidate, $request->provider); $analysis = $this->aiService->analyze($candidate, $request->provider);

View File

@@ -115,8 +115,9 @@ class AIAnalysisService
default => $this->callOllama($prompt), default => $this->callOllama($prompt),
}; };
// Inject provider name for display // Inject metadata for display and tracking
$analysis['provider'] = $provider; $analysis['provider'] = $provider;
$analysis['analyzed_at'] = now()->toIso8601String();
return $analysis; return $analysis;
} }

View File

@@ -365,14 +365,19 @@ const runAI = async () => {
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-8 overflow-hidden relative"> <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-8 overflow-hidden relative">
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8"> <div class="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8">
<div> <div>
<h3 class="font-bold text-lg mb-4 flex items-center gap-3"> <h3 class="font-bold text-lg mb-4 flex items-center gap-3 flex-wrap">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9l-.707.707M12 21v-1m4.243-4.243l-.707-.707m2.828-9.9l-.707.707" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9l-.707.707M12 21v-1m4.243-4.243l-.707-.707m2.828-9.9l-.707.707" />
</svg> </svg>
Analyse IA complète Analyse IA complète
<span v-if="aiAnalysis?.provider" class="text-xs px-2 py-0.5 rounded-full bg-slate-100 text-slate-500 uppercase font-bold border border-slate-200"> <div class="flex items-center gap-2">
{{ aiAnalysis.provider }} <span v-if="aiAnalysis?.provider" class="text-xs px-2 py-0.5 rounded-full bg-slate-100 text-slate-500 uppercase font-bold border border-slate-200">
</span> {{ aiAnalysis.provider }}
</span>
<span v-if="aiAnalysis?.analyzed_at" class="text-[10px] text-slate-400 italic font-normal">
Effectuée le {{ new Date(aiAnalysis.analyzed_at).toLocaleDateString('fr-FR') }}
</span>
</div>
</h3> </h3>
<p class="text-xs text-slate-400 mt-1 uppercase font-bold tracking-widest">Choisir l'IA pour l'analyse du matching</p> <p class="text-xs text-slate-400 mt-1 uppercase font-bold tracking-widest">Choisir l'IA pour l'analyse du matching</p>
</div> </div>

View File

@@ -1,27 +0,0 @@
<?php
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
$apiKey = env('GEMINI_API_KEY');
if (!$apiKey) {
echo "API Key not found in .env\n";
exit;
}
echo "Testing Gemini models with key: " . substr($apiKey, 0, 5) . "...\n";
$response = Http::get("https://generativelanguage.googleapis.com/v1/models?key=" . $apiKey);
if ($response->successful()) {
$models = $response->json('models');
foreach ($models as $model) {
echo "- " . $model['name'] . " (" . implode(", ", $model['supportedGenerationMethods']) . ")\n";
}
} else {
echo "Failed to list models: " . $response->status() . " - " . $response->body() . "\n";
}