Skip to content

Commit b575b34

Browse files
committed
feat(ai): add watermelon validation to prevent non-watermelon analysis
- Add isWatermelon and detectedObject fields to AI schema - Update AI prompt to validate object before analysis - Add NOT_A_WATERMELON error handling in analyze API - Update use-analysis hook to show user-friendly error message - Prevent saving non-watermelon analysis to database Requirements: 1.2, 1.3, 2.1
1 parent d63ee05 commit b575b34

4 files changed

Lines changed: 39 additions & 1 deletion

File tree

app/api/analyze/route.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,24 @@ export async function POST(request: NextRequest) {
150150

151151
console.log(`[Analysis API] AI analysis completed in ${aiResponseTime}ms`);
152152
console.log(`[Analysis API] Result: ${aiResult.maturityStatus} (${aiResult.confidence}% confidence)`);
153+
154+
// Check if the detected object is a watermelon
155+
if (!aiResult.isWatermelon) {
156+
console.log(`[Analysis API] Not a watermelon detected: ${aiResult.detectedObject}`);
157+
158+
return NextResponse.json(
159+
{
160+
success: false,
161+
error: {
162+
code: 'NOT_A_WATERMELON',
163+
message: 'Objek yang terdeteksi bukan semangka.',
164+
detectedObject: aiResult.detectedObject || 'Objek tidak dikenali',
165+
reasoning: aiResult.reasoning,
166+
},
167+
},
168+
{ status: 400 }
169+
);
170+
}
153171
} catch (error) {
154172
console.error('[Analysis API] AI analysis failed:', error);
155173

lib/ai/providers.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { z } from 'zod';
1919
* Ensures consistent response format across all AI providers
2020
*/
2121
export const analysisSchema = z.object({
22+
isWatermelon: z.boolean().describe('Apakah objek dalam gambar adalah semangka'),
23+
detectedObject: z.string().optional().describe('Objek yang terdeteksi jika bukan semangka'),
2224
maturityStatus: z.enum(['Matang', 'Belum Matang']).describe('Status kematangan semangka'),
2325
confidence: z.number().min(0).max(100).describe('Tingkat kepercayaan analisis (0-100)'),
2426
sweetnessLevel: z.number().min(1).max(10).describe('Perkiraan tingkat kemanisan (1-10)'),
@@ -71,7 +73,14 @@ export const aiProviders: AIProvider[] = [
7173
* Analysis prompt in Indonesian for watermelon assessment
7274
* Used consistently across all AI providers
7375
*/
74-
export const analysisPrompt = `Analisis gambar semangka ini dan berikan penilaian yang akurat:
76+
export const analysisPrompt = `Analisis gambar ini dan berikan penilaian yang akurat:
77+
78+
**LANGKAH 1: VALIDASI OBJEK**
79+
Pertama, tentukan apakah objek dalam gambar adalah SEMANGKA atau bukan.
80+
- Jika BUKAN semangka, set isWatermelon = false dan sebutkan objek yang terdeteksi di field detectedObject
81+
- Jika ADALAH semangka, set isWatermelon = true dan lanjutkan ke analisis detail
82+
83+
**LANGKAH 2: ANALISIS SEMANGKA (hanya jika isWatermelon = true)**
7584
7685
**Kriteria Penilaian:**
7786
@@ -104,6 +113,8 @@ export const analysisPrompt = `Analisis gambar semangka ini dan berikan penilaia
104113
- Pola garis-garis pada kulit
105114
106115
**Penting:**
116+
- SELALU validasi apakah objek adalah semangka terlebih dahulu
117+
- Jika bukan semangka, jelaskan objek apa yang terdeteksi
107118
- Berikan penjelasan dalam Bahasa Indonesia yang mudah dipahami petani
108119
- Jelaskan alasan di balik setiap penilaian
109120
- Berikan tips praktis jika diperlukan

lib/hooks/use-analysis.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ export function useAnalysis(): UseAnalysisReturn {
156156

157157
if (!response.ok) {
158158
const errorData = await response.json();
159+
160+
// Check if it's a NOT_A_WATERMELON error
161+
if (errorData.error?.code === 'NOT_A_WATERMELON') {
162+
const detectedObject = errorData.error.detectedObject || 'Objek tidak dikenali';
163+
throw new Error(`Bukan semangka! Terdeteksi: ${detectedObject}`);
164+
}
165+
159166
throw new Error(errorData.error?.message || 'Gagal menganalisis gambar');
160167
}
161168

lib/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ export interface AIAnalysisInput {
235235
}
236236

237237
export interface AIAnalysisOutput {
238+
isWatermelon: boolean;
239+
detectedObject?: string;
238240
maturityStatus: MaturityStatus;
239241
confidence: number;
240242
sweetnessLevel: number;

0 commit comments

Comments
 (0)