# ๐Ÿ“‹ RINGKASAN LENGKAP - Phase 5: Laravel Model & Database ## ๐ŸŽฏ Objektif Tercapai Membuat **database layer** untuk menyimpan hasil klasifikasi gambar daun padi ke dalam Laravel menggunakan Eloquent Model. --- ## โœ… FILE YANG DIBUAT / DIUBAH ### ๐Ÿ“ **File Baru (NEW)** #### 1. `app/Models/Classification.php` ```php class Classification extends Model { protected $fillable = [ 'image_path', 'filename', 'predicted_class', 'confidence', 'all_predictions', 'disease_name', 'severity', 'notes', ]; protected $casts = [ 'all_predictions' => 'array', 'confidence' => 'float', ]; } ``` - Model untuk table `classifications` - Supports JSON casting untuk `all_predictions` - Timestamps otomatis (created_at, updated_at) #### 2. `database/migrations/2026_03_08_182722_create_classifications_table.php` ```php Schema::create('classifications', function (Blueprint $table) { $table->id(); $table->string('image_path')->nullable(); $table->string('filename'); $table->string('predicted_class'); $table->float('confidence'); $table->json('all_predictions'); $table->string('disease_name')->nullable(); $table->string('severity')->nullable(); $table->text('notes')->nullable(); $table->timestamps(); }); ``` - 10 columns untuk store data lengkap - JSON column untuk all_predictions - Nullable fields untuk optional data - **Status:** โœ… Executed successfully (347.26ms) #### 3. `app/Http/Controllers/ClassificationHistoryController.php` โญ NEW ```php class ClassificationHistoryController extends Controller { public function index() // GET /api/classifications public function show($id) // GET /api/classifications/{id} public function destroy($id) // DELETE /api/classifications/{id} public function stats() // GET /api/classifications/stats/summary } ``` - **index()**: List semua dengan pagination (15/page) - **show()**: Detail single record dengan all_predictions JSON - **destroy()**: Delete record + cleanup image file - **stats()**: Aggregate stats (total, average confidence, breakdown by disease) --- ### โœ๏ธ **File yang Diubah (UPDATED)** #### 1. `app/Http/Controllers/ClassificationController.php` **Perubahan:** Tambah `Classification::create()` untuk save data Sebelum (hanya return response): ```php return response()->json(['success' => true, 'data' => $result]); ``` Sesudah (save to database): ```php // Get disease info $diseaseInfo = getDiseaseInfo($result['predicted_class']); // Save to database Classification::create([ 'image_path' => $path, 'filename' => $file->getClientOriginalName(), 'predicted_class' => $result['predicted_class'], 'confidence' => $result['confidence'], 'all_predictions' => $result['all_predictions'], 'disease_name' => $diseaseInfo['name'] ?? null, 'severity' => $diseaseInfo['severity'] ?? null, 'notes' => null, ]); return response()->json(['success' => true, 'data' => $result]); ``` #### 2. `routes/api.php` **Perubahan:** Tambah classification history routes ```php // Classification endpoints Route::post('/classify', [ClassificationController::class, 'classify']); Route::post('/classify-and-save', [ClassificationController::class, 'classifyAndSave']); Route::get('/test', [ClassificationController::class, 'testConnection']); // History endpoints (NEW) Route::get('/', [ClassificationHistoryController::class, 'index']); Route::get('/{id}', [ClassificationHistoryController::class, 'show']); Route::delete('/{id}', [ClassificationHistoryController::class, 'destroy']); Route::get('/stats/summary', [ClassificationHistoryController::class, 'stats']); ``` Total: **7 endpoints** untuk classification & history --- ## ๐Ÿ“Š Database Schema ### Table: `classifications` ``` Column | Type | Nullable | Default --------------------|-----------|----------|---------- id | BIGINT | โœ— | PRIMARY KEY image_path | VARCHAR | โœ“ | NULL filename | VARCHAR | โœ— | predicted_class | VARCHAR | โœ— | confidence | FLOAT | โœ— | all_predictions | JSON | โœ— | disease_name | VARCHAR | โœ“ | NULL severity | VARCHAR | โœ“ | NULL notes | TEXT | โœ“ | NULL created_at | TIMESTAMP | โœ— | CURRENT_TIMESTAMP updated_at | TIMESTAMP | โœ— | CURRENT_TIMESTAMP ON UPDATE ``` --- ## ๐Ÿ”Œ API Endpoints ### Classification (Existing) | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/classification/test` | Test API connection | | POST | `/api/classification/classify` | Analyze image only | | POST | `/api/classification/classify-and-save` | Analyze + save to DB | ### Classifications History (NEW) | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/classifications` | List all (paginated) | | GET | `/api/classifications/{id}` | Get detail by ID | | DELETE | `/api/classifications/{id}` | Delete record + image | | GET | `/api/classifications/stats/summary` | Get statistics | --- ## ๐Ÿ”„ Data Flow ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Mobile App (Flutter) โ”‚ โ”‚ - Pick image from camera/gallery โ”‚ โ”‚ - Call: POST /classify-and-save โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Laravel API (Port 8000) โ”‚ โ”‚ ClassificationController::classifyAndSave() โ”‚ โ”‚ - Receive image โ”‚ โ”‚ - Forward to Python API โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Python API (Port 5000) โ”‚ โ”‚ api_server.py โ”‚ โ”‚ - Load TensorFlow model โ”‚ โ”‚ - Preprocess image โ”‚ โ”‚ - Predict disease โ”‚ โ”‚ - Return JSON result โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Laravel API (Port 8000) โ”‚ โ”‚ ClassificationController::classifyAndSave() โ”‚ โ”‚ - Save image to storage/app/classifications/ โ”‚ โ”‚ - Classification::create([...]) โ—„โ”€โ”€โ”€ SAVE TO DB โ”‚ โ”‚ - Return response to mobile โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Mobile App (Flutter) โ”‚ โ”‚ - Display classification result โ”‚ โ”‚ - Show disease info, severity, treatments โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## ๐Ÿ“ฆ Struktur Direktori ``` web_TA/ โ”œโ”€โ”€ app/ โ”‚ โ”œโ”€โ”€ Http/ โ”‚ โ”‚ โ””โ”€โ”€ Controllers/ โ”‚ โ”‚ โ”œโ”€โ”€ ClassificationController.php (โœ๏ธ Updated) โ”‚ โ”‚ โ””โ”€โ”€ ClassificationHistoryController.php (โœจ NEW) โ”‚ โ””โ”€โ”€ Models/ โ”‚ โ””โ”€โ”€ Classification.php (โœจ NEW) โ”‚ โ”œโ”€โ”€ database/ โ”‚ โ””โ”€โ”€ migrations/ โ”‚ โ””โ”€โ”€ 2026_03_08_182722_create_classifications_table.php (โœจ NEW) โ”‚ โ”œโ”€โ”€ routes/ โ”‚ โ””โ”€โ”€ api.php (โœ๏ธ Updated) โ”‚ โ””โ”€โ”€ storage/ โ””โ”€โ”€ app/ โ””โ”€โ”€ public/ โ””โ”€โ”€ classifications/ (stores images) ``` --- ## ๐Ÿงช Testing Endpoints ### 1. Test Save Classification ```bash curl -X POST http://127.0.0.1:8000/api/classification/classify-and-save \ -F "image=@rice_leaf.jpg" ``` **Expected Response:** ```json { "success": true, "data": { "predicted_class": "Bacterialblight", "confidence": "95.23%", "disease_info": "Bercak Bakteri..." } } ``` โœ“ Record akan tersimpan di table `classifications` ### 2. Get All Classifications ```bash curl http://127.0.0.1:8000/api/classifications?page=1 ``` **Expected:** List dengan pagination ### 3. Get Statistics ```bash curl http://127.0.0.1:8000/api/classifications/stats/summary ``` **Expected:** Total count, average confidence, breakdown by disease ### 4. Delete Classification ```bash curl -X DELETE http://127.0.0.1:8000/api/classifications/1 ``` **Expected:** Record + image deleted --- ## ๐Ÿ“ˆ Statistics Query ```php // Get statistics $total = Classification::count(); $avgConfidence = Classification::avg('confidence'); $byDisease = Classification::select('disease_name') ->groupBy('disease_name') ->selectRaw('count(*) as count') ->get(); ``` --- ## โœ… Verification Checklist - โœ… Model `Classification` dibuat - โœ… Migration dibuat dengan schema lengkap - โœ… Table `classifications` berhasil dijalankan (`php artisan migrate`) - โœ… ClassificationController save data ke model - โœ… ClassificationHistoryController dengan CRUD + stats - โœ… Routes ditambahkan untuk semua endpoints - โœ… JSON casting untuk `all_predictions` - โœ… Float casting untuk `confidence` - โœ… Timestamps otomatis (created_at, updated_at) - โœ… Image cleanup saat delete --- ## ๐Ÿš€ Next Steps 1. **Start Laravel Server**: `php artisan serve --port=8000` 2. **Start Python API**: `python api_server.py` (port 5000) 3. **Run Flutter**: `flutter run` (emulator/device) 4. **Test Full Integration**: - Upload gambar dari mobile - Verify record di database - Test history endpoints - Test statistics 5. **Create Dashboard** (optional): - Display classification history - Add filters by disease - Add date range search --- ## ๐Ÿ“ž Summary Endpoints ``` Classification: โ”œโ”€โ”€ GET /api/classification/test โ”œโ”€โ”€ POST /api/classification/classify โ””โ”€โ”€ POST /api/classification/classify-and-save Classifications History: โ”œโ”€โ”€ GET /api/classifications โ”œโ”€โ”€ GET /api/classifications/{id} โ”œโ”€โ”€ DELETE /api/classifications/{id} โ””โ”€โ”€ GET /api/classifications/stats/summary ``` --- ## ๐ŸŽ“ Key Features | Feature | Status | |---------|--------| | Model dengan Eloquent | โœ… | | Migration dengan schema | โœ… | | Auto save saat classify | โœ… | | Pagination di history | โœ… | | JSON storage | โœ… | | Image cleanup | โœ… | | Statistics endpoint | โœ… | | Timestamps | โœ… | --- **Phase Status:** โœ… **COMPLETE** **Files Modified:** 2 **Files Created:** 3 **Database Tables:** 1 (classifications) **API Endpoints:** 7 total **Last Execution:** `php artisan migrate` - 347.26ms DONE --- ## ๐Ÿ“„ Documentation Files - [MODEL_API_SETUP.md](./MODEL_API_SETUP.md) - Dokumentasi lengkap - [INTEGRATION_SUMMARY.md](./INTEGRATION_SUMMARY.md) - Summary integrasi full system - [SETUP_GUIDE.md](./SETUP_GUIDE.md) - Panduan setup awal