8.1 KiB
8.1 KiB
⚡ QUICK REFERENCE CARD
🚀 Start All Servers (Run in separate terminals)
# Terminal 1: Laravel API
cd "d:\PROJECT TA\web_TA"
php artisan serve --port=8000
→ Running on: http://127.0.0.1:8000
# Terminal 2: Python API
cd "d:\PROJECT TA\rice leaf diseases dataset"
python api_server.py
→ Running on: http://127.0.0.1:5000
# Terminal 3: Flutter App
cd "d:\PROJECT TA\mobile_TA\padi_app"
flutter run
→ Launches app on emulator/device
🧪 Quick Tests (Use curl or Postman)
Test Connection
curl http://127.0.0.1:8000/api/classification/test
Classify Image
curl -X POST http://127.0.0.1:8000/api/classification/classify \
-F "image=@rice_leaf.jpg"
Classify & Save
curl -X POST http://127.0.0.1:8000/api/classification/classify-and-save \
-F "image=@rice_leaf.jpg" \
-F "notes=Test"
List All Classifications
curl http://127.0.0.1:8000/api/classifications
Get Statistics
curl http://127.0.0.1:8000/api/classifications/stats/summary
Delete Classification
curl -X DELETE http://127.0.0.1:8000/api/classifications/1
📊 Database Queries (php artisan tinker)
php artisan tinker
# Count records
>>> DB::table('classifications')->count()
# Get latest classification
>>> DB::table('classifications')->latest()->first()
# Get specific classification
>>> App\Models\Classification::find(1)
# List all with pagination
>>> App\Models\Classification::paginate(15)
# Get by disease
>>> App\Models\Classification::where('disease_name', 'Bercak Bakteri')->get()
# Get high confidence
>>> App\Models\Classification::where('confidence', '>=', 0.9)->get()
# Get statistics
>>> DB::table('classifications')->selectRaw('disease_name, count(*) as count')->groupBy('disease_name')->get()
# Clear all (WARNING: DELETES ALL DATA)
>>> DB::table('classifications')->truncate()
# Exit tinker
>>> exit
📁 Key Files
Models & Database
- Model:
app/Models/Classification.php - Migration:
database/migrations/2026_03_08_182722_create_classifications_table.php - Controller (History):
app/Http/Controllers/ClassificationHistoryController.php - Controller (Classification):
app/Http/Controllers/ClassificationController.php - Routes:
routes/api.php
Mobile
- Service:
lib/services/classification_service.dart - UI Screen:
lib/screen/dashboard_klasifikasi.dart - Result Screen:
lib/screen/result_screen.dart
Documentation
- Setup:
web_TA/MODEL_API_SETUP.md - Phase Summary:
web_TA/PHASE5_SUMMARY.md - Testing Guide:
TESTING_GUIDE.md - Next Steps:
NEXT_STEPS.md
📌 API Endpoints (7 Total)
Classification:
GET /api/classification/test
POST /api/classification/classify
POST /api/classification/classify-and-save
History:
GET /api/classifications
GET /api/classifications/{id}
DELETE /api/classifications/{id}
GET /api/classifications/stats/summary
🔧 Common Issues & Fixes
| Issue | Fix |
|---|---|
| Port 5000/8000 in use | netstat -an | findstr :5000 to find process |
| Database not connected | Check .env credentials: php artisan tinker → DB::connection()->getPdo() |
| Flutter API timeout | Check API URL for emulator (10.0.2.2) vs device (192.168.x.x) |
| Image not saving | Check storage/app/public is writable: chmod 775 storage/ |
| Migration failed | Reset: php artisan migrate:rollback then php artisan migrate |
✅ Verification Commands
# Check Laravel status
php artisan migrate:status
# Check model fillable properties
php artisan tinker
>>> (new App\Models\Classification())->getFillable()
# Check table structure
php artisan tinker
>>> DB::table('classifications')->getColumns()
# Check routes
php artisan route:list | grep classifications
# Check for errors
php artisan optimize:clear
📱 Mobile API URL Configuration
For Android Emulator
// classification_service.dart
static const String baseUrl = 'http://10.0.2.2:8000/api/classification';
/* 10.0.2.2 = Your computer's localhost from emulator */
For Physical Device
// Findyour computer IP first:
// ipconfig → Look for IPv4 Address (e.g., 192.168.1.100)
static const String baseUrl = 'http://192.168.1.100:8000/api/classification';
// Replace IP with your actual computer IP
🚄 Performance Metrics
| Operation | Time |
|---|---|
| Classify image | 2-3 sec |
| Save to DB | < 100ms |
| Get list | ~150ms |
| Get detail | ~50ms |
| Delete | ~200ms |
| Get stats | ~300ms |
🎯 Testing Checklist
□ Server 1: Laravel runs on :8000
□ Server 2: Python API runs on :5000
□ Server 3: Flutter app launches
□ Test connection: GET /test succeeds
□ Test classify: POST /classify returns result
□ Test save: POST /classify-and-save saves to DB
□ Test history: GET /classifications shows data
□ Test stats: GET /stats returns numbers
□ Test mobile: App classifies and shows result
□ Test error handling: Server down shows error
💾 Database Backup/Restore
# Backup current database
mysqldump -u root -p classification_db > backup_$(date +%Y%m%d_%H%M%S).sql
# Restore from backup
mysql -u root -p classification_db < backup_20260309_100000.sql
# Clear all classifications
php artisan tinker
>>> DB::table('classifications')->truncate()
📞 Documentation Quick Links
| Document | Purpose |
|---|---|
| MODEL_API_SETUP.md | Complete API specification |
| PHASE5_SUMMARY.md | What was created this phase |
| TESTING_GUIDE.md | How to test endpoints |
| NEXT_STEPS.md | What to do next |
| PHASE5_COMPLETE.md | Executive summary |
🎓 Important Concepts
Fillable Array
Prevents accidental mass assignment security vulnerability
$fillable = ['field1', 'field2']; // Only these can be mass assigned
Type Casting
Automatic conversion of data types
$casts = [
'all_predictions' => 'array', // JSON → PHP array
'confidence' => 'float', // String → float
];
Timestamps
Laravel automatically manages created_at & updated_at
// No need to set manually
Classification::create([...]); // Timestamps auto-set
Pagination
Automatically splits large datasets
Classification::paginate(15); // Returns 15 per page
JSON Column
Store complex data as JSON in database
all_predictions: {
"Bacterialblight": 0.95,
"Brownspot": 0.04,
"Leafsmut": 0.01
}
🔐 Security Notes
- ✅ CSRF protection enabled (Laravel default)
- ✅ Mass assignment protected ($fillable)
- ✅ Database credentials in .env
- ⚠️ TODO: Add API authentication
- ⚠️ TODO: Add authorization checks
- ⚠️ TODO: Add rate limiting
📊 System Capacity
| Metric | Limit |
|---|---|
| Concurrent requests | 100+ (depends on server) |
| Classifications stored | Unlimited (10GB DB ~1M records) |
| Image file size | 10MB max (configurable) |
| Response time | < 5 seconds (target) |
| Pagination | 15 per page |
🎯 Success = All This Works
- ✅ Can start all 3 servers
- ✅ Can upload image from mobile
- ✅ Get classification result
- ✅ Data saved in database
- ✅ Can view history
- ✅ Can get statistics
- ✅ Can delete records
📞 Quick Troubleshooting
App crashes on startup?
flutter clean
flutter pub get
flutter run -v # verbose mode shows error
Classification takes too long?
- Check Python API is running
- Check image size (large = slow)
- Check network latency
Data not saving?
- Check database connection:
php artisan tinker→DB::connection()->getPdo() - Check
storagefolder writable - Check migrations executed:
php artisan migrate:status
Cannot connect to API from mobile?
- Emulator using 10.0.2.2, not 127.0.0.1
- Device using actual IP, not localhost
- Firewall might block port 5000/8000
Status: ✅ Ready to Test
Last Updated: March 9, 2026
Phase: 5 Complete