# FLOWCHART SISTEM KLASIFIKASI TOMAT - DETAIL ## 1. ALUR UMUM SISTEM (HIGH LEVEL) ```mermaid graph TD A["👤 User/Admin"] -->|Akses Web| B["🌐 Laravel Web Interface
(Frontend)"] B -->|GET /tomat/upload| C["Upload Page
Form Input Gambar"] C -->|User Select Image| D["Preview Gambar
& Validasi File"] D -->|Upload via AJAX
POST /tomat/classify| E["📨 Laravel Backend
(Controller)"] E -->|File Processing| F["Simpan Temp File
& Validasi"] F -->|HTTP Request
dengan File Binary| G["🐍 Flask API
Python Backend"] G -->|Preprocessing| H["Image Decode
& Resize 256x256"] H -->|Feature Extraction| I["Extract Color
Histogram HSV"] I -->|Array Fitur| J["🤖 Random Forest
Model"] J -->|Prediksi| K["Get Predictions
& Probabilities"] K -->|JSON Response| E E -->|Save ke Database| L["💾 Database
Predictions Table"] L -->|Render View| M["📊 Result Page
Tampil Hasil
& Confidence"] M -->|Display| A ``` --- ## 2. ALUR DETAIL: UPLOAD & KLASIFIKASI ```mermaid graph TD START["🔵 START: User Upload"] -->|Klik Upload Button| A["1️⃣ FILE INPUT VALIDATION"] A -->|Check File Extension| B{Format Valid?
PNG, JPG, JPEG, GIF} B -->|No| C["❌ Error: Invalid Format"] C --> END1["🔴 Show Error Message"] B -->|Yes| D{File Size
≤ 16MB?} D -->|No| C D -->|Yes| E["2️⃣ AJAX UPLOAD PROCESS"] E -->|FormData + File| F["Send POST /tomat/classify"] F --> G["3️⃣ LARAVEL BACKEND PROCESSING"] G --> H["Receive File Upload"] H --> I["Validate File Integrity"] I --> J["Temporary Save File"] J --> K["Prepare Request Body"] K --> L["4️⃣ PYTHON BACKEND REQUEST"] L -->|HTTP POST + File Binary| M["Flask App.py Receive"] M --> N["Parse File Stream"] N --> O["5️⃣ IMAGE PREPROCESSING"] O -->|cv2.imdecode| P["Decode Image dari Bytes"] P -->|Check Dimension| Q{Image Size
256x256?} Q -->|No| R["cv2.resize → 256x256"] Q -->|Yes| S["Use As-Is"] R --> T["6️⃣ FEATURE EXTRACTION"] S --> T T -->|cv2.cvtColor| U["Convert BGR → HSV"] U --> V["Calculate Histogram
8x8x8 bins per channel"] V --> W["Normalize Histogram"] W --> X["Concatenate Features
into 1D Array"] X --> Y["Total Features: 192"] Y --> Z["7️⃣ MODEL PREDICTION"] Z -->|Loaded Model| AA["Random Forest
Classifier"] AA -->|predict_proba| AB["Calculate Confidence
for Each Class"] AB --> AC{Prediction
Results} AC -->|Matang| AD["Kelas: MATANG"] AC -->|Mentah| AE["Kelas: MENTAH"] AC -->|Setengah Matang| AF["Kelas: SETENGAH_MATANG"] AD --> AG["8️⃣ PACKAGE RESPONSE"] AE --> AG AF --> AG AG -->|JSON Format| AH["Return:
class,
confidence %,
timestamp"] AH --> AI["9️⃣ LARAVEL SAVE RESULTS"] AI -->|Store in DB| AJ["Predictions Table:
user_id, filename,
class, confidence,
created_at"] AJ --> AK["🔟 RENDER RESULTS"] AK -->|JSON Response| AL["JavaScript:
Update DOM"] AL --> AM["Display Result Card:
Class, Confidence %,
Advice Text"] AM --> AN["Show History Link"] AN --> END2["✅ COMPLETE"] ``` --- ## 3. ALUR DATABASE & STORAGE ```mermaid graph TD A["Upload Image"] --> B["Store in Public Storage"] B --> C["storage/app/uploads/"] B --> D["Temporary Processing"] D --> E["Classification Process"] E --> F["✅ Success?"] F -->|Yes| G["Save Prediction Record"] G --> H["Database: predictions table"] H --> I["Fields:
user_id,
image_filename,
predicted_class,
confidence_score,
created_at"] F -->|No| J["Log Error"] J --> K["Cleanup Temp Files"] K --> L["Show Error to User"] I --> M["Save Image
to Dataset Folder"] M --> N{Class Type} N -->|Matang| O["matang/"] N -->|Mentah| P["mentah/"] N -->|Setengah| Q["setengah_matang/"] O --> R["Store Correctly
Classified Image"] P --> R Q --> R ``` --- ## 4. ALUR ADMIN DASHBOARD ```mermaid graph TD A["👨‍💼 Admin Login"] --> B["Verify Credentials"] B -->|Check Database| C{Credentials
Valid?} C -->|No| D["❌ Redirect to Login"] C -->|Yes| E["✅ Create Session"] E --> F["Admin Dashboard"] F --> G["7 Main Features"] G --> H["1. Dashboard Overview"] H --> H1["Stats Cards:
Total Predictions,
Accuracy Rate,
Today Predictions"] G --> I["2. Classification History"] I --> I1["Display All Predictions
with Filter & Search"] G --> J["3. System Statistics"] J --> J1["Charts & Graphs:
Prediction Distribution,
Confidence Trends"] G --> K["4. Manage Admin Users"] K --> K1["CRUD Operations:
Add/Edit/Delete
Admin Accounts"] G --> L["5. Model Information"] L --> L1["Display:
Model Type,
Classes,
Features Count"] G --> M["6. System Status"] M --> M1["Check:
Flask Service Status,
Database Status,
Storage Status"] G --> N["7. Logout"] N --> N1["Clear Session
Redirect to Login"] ``` --- ## 5. ALUR AUTENTIKASI ADMIN ```mermaid graph TD A["User Input:
Username &
Password"] --> B["POST /admin/login"] B --> C["Laravel: UploadController"] C --> D["Query Database:
Users Table"] D --> E{User
Found?} E -->|No| F["❌ Invalid Username"] F --> G["Redirect Login +
Error Message"] E -->|Yes| H{Password
Match?} H -->|No| F H -->|Yes| I{User Status
= Active?} I -->|No| J["❌ Account Inactive"] J --> G I -->|Yes| K["✅ Authentication Success"] K --> L["Create Session:
admin_logged_in=true,
admin_user_id,
admin_name"] L --> M["Redirect to
Admin Dashboard"] M --> N["Display Welcome Message"] ``` --- ## 6. ALUR MODEL TRAINING (Background Process) ```mermaid graph TD A["Start: create_model.py"] --> B["Load Dataset"] B --> C["Scan Folders:
matang/,
mentah/,
setengah_matang/"] C --> D["For Each Image"] D --> E["Read Image (cv2)"] E --> F["Extract HSV
Histogram Features"] F --> G["Store Features +
Label"] G --> H{All Images
Processed?} H -->|No| D H -->|Yes| I["Combine All Features
into Matrix (N, 192)"] I --> J["Train-Test Split
80/20"] J --> K["Train Random Forest
Classifier"] K --> L["Model Training"] L --> M["Extract Class Labels
via LabelEncoder"] M --> N["Evaluate Model:
- Predictions
- Accuracy
- Classification Report
- Confusion Matrix"] N --> O["Save Artifacts"] O --> P["model_tomat.pkl"] O --> Q["model_tomat_encoder.pkl"] O --> R["model_tomat_metadata.pkl"] P --> S["Ready for
Production"] Q --> S R --> S ``` --- ## 7. ALUR REQUEST-RESPONSE API PYTHON ```mermaid graph TD A["Request dari Laravel
POST /api/predict"] -->|Multipart FormData| B["Flask App Receive"] B --> C["Check Headers:
Content-Type: multipart/form-data"] C --> D{File dalam
Request?} D -->|No| E["❌ Error 400"] E --> E1["Return JSON:
error: 'No file provided'"] D -->|Yes| F["Parse File Object
from request.files"] F --> G{File Extension
Valid?} G -->|No| H["❌ Error 400"] H --> H1["Return JSON:
error: 'Invalid file type'"] G -->|Yes| I["Load Model
(if not loaded)"] I --> J["Preprocess Image
(decode, resize)"] J --> K["Extract Features
(HSV Histogram)"] K --> L["Check Features
Null?"] L -->|Yes| M["❌ Error 500"] M --> M1["Return JSON:
error: 'Feature extraction failed'"] L -->|No| N["Run Prediction"] N --> O["Get Class Label
Get Probabilities"] O --> P["Build Response JSON:
{'class': 'matang',
'confidence': 0.95,
'timestamp': 'xxx'}"] P --> Q["Return 200 OK +
JSON Response"] Q --> R["Back to Laravel"] ``` --- ## 8. ALUR LAYERS ARSITEKTUR ```mermaid graph LR A["PRESENTATION LAYER
🎨"] --> B["HTML/CSS/JS
Templates Blade"] B --> C["BUSINESS LOGIC LAYER
⚙️"] C --> D["Laravel Controllers
Route Handlers
Validation"] D --> E["DATA ACCESS LAYER
💾"] E --> F["Database
Queries"] F --> G["External Services
🔌"] G --> H["Flask API
Python ML Backend"] H --> I["ML ENGINE LAYER
🤖"] I --> J["Model Loading
Feature Extraction
Prediction"] J --> K["Model Files
.pkl files"] K --> L["DATA LAYER
💿"] L --> M["Datasets
Database
Storage"] ``` --- ## 9. ALUR VALIDASI & ERROR HANDLING ```mermaid graph TD A["Input Data"] --> B{Step 1:
File Upload
Validation} B -->|Extension Check| B1{"✓ Valid
Format?"} B1 -->|No| B2["❌ Extension Error"] B1 -->|Yes| B3{"✓ File Size
≤ 16MB?"} B3 -->|No| B4["❌ Size Error"] B3 -->|Yes| B5["✅ Pass Upload Validation"] B5 --> C{Step 2:
Image Processing
Validation} C -->|Decode Check| C1{"✓ Can Decode
Image?"} C1 -->|No| C2["❌ Corrupt Image Error"] C1 -->|Yes| C3{"✓ Valid
Dimensions?"} C3 -->|No| C4["Auto Resize
to 256x256"] C4 --> C5["✅ Pass Processing Validation"] C5 --> D{Step 3:
Feature Extraction
Validation} D -->|Extract Check| D1{"✓ Features
Not Null?"} D1 -->|No| D2["❌ Feature Extraction Error"] D1 -->|Yes| D3{"✓ Feature
Shape = 192?"} D3 -->|No| D4["❌ Feature Shape Error"] D3 -->|Yes| D5["✅ Pass Feature Validation"] D5 --> E{Step 4:
Prediction
Validation} E -->|Predict Check| E1{"✓ Model
Loaded?"} E1 -->|No| E2["❌ Model Not Found Error"] E1 -->|Yes| E3{"✓ Prediction
Success?"} E3 -->|No| E4["❌ Prediction Error"] E3 -->|Yes| E5["✅ All Validations Passed"] E5 --> F["Return Success Response"] B2 --> G["Return Error 400"] B4 --> G C2 --> H["Return Error 500"] D2 --> H D4 --> H E2 --> H E4 --> H C2 --> G G --> I["Show Error UI"] H --> I ``` --- ## 10. ALUR INTERAKSI USER-SISTEM ```mermaid sequenceDiagram participant User as 👤 User participant Web as 🌐 Laravel
Frontend participant Laravel as ⚙️ Laravel
Backend participant Flask as 🐍 Flask
Backend participant DB as 💾 Database participant Model as 🤖 ML Model User->>Web: Kunjungi /tomat/upload Web-->>User: Tampilkan upload page User->>Web: Pilih & upload gambar Web->>Web: Validasi file di browser User->>Web: Klik "Klasifikasi" button Web->>Laravel: POST /tomat/classify + file Laravel->>Laravel: Validasi file Laravel->>Flask: HTTP POST dengan file binary Flask->>Flask: Decode image Flask->>Flask: Resize 256x256 (if needed) Flask->>Flask: Extract HSV histogram Flask->>Model: Load trained model Model->>Model: predict_proba([features]) Model-->>Flask: [class, confidence] Flask-->>Laravel: JSON response Laravel->>DB: INSERT prediction record DB-->>Laravel: ID saved Laravel-->>Web: JSON response Web->>Web: Parse results Web->>User: Display result card User->>User: Lihat hasil & confidence % ``` --- ## 11. ALUR DATABASE SCHEMA ```mermaid graph TD A["📊 DATABASE SCHEMA"] A --> B["users table"] B --> B1["id: PK"] B1 --> B2["email: VARCHAR"] B2 --> B3["username: VARCHAR"] B3 --> B4["password: VARCHAR hash"] B4 --> B5["name: VARCHAR"] B5 --> B6["status: ENUM active/inactive"] B6 --> B7["created_at, updated_at"] A --> C["predictions table"] C --> C1["id: PK"] C1 --> C2["user_id: FK to users"] C2 --> C3["image_filename: VARCHAR"] C3 --> C4["predicted_class: ENUM matang/mentah/setengah_matang"] C4 --> C5["confidence_score: DECIMAL 0.00-1.00"] C5 --> C6["created_at, updated_at"] A --> D["uploads table (legacy)"] D --> D1["id: PK"] D1 --> D2["user_id: FK"] D2 --> D3["image_file: VARCHAR path"] D3 --> D4["classification_result: VARCHAR"] D4 --> D5["created_at, updated_at"] ``` --- ## 12. ALUR CACHE & PERFORMANCE ```mermaid graph TD A["Request Classification"] --> B{"Is Model
Loaded in
Memory?"} B -->|No| C["Load from
model_tomat.pkl"] C --> D["Cache in
Global Variable"] D --> E["Store in Memory"] B -->|Yes| F["Use Cached
Model"] E --> G["Process Image"] F --> G G --> H["Extract Features"] H --> I["Run Prediction"] I --> J["Return Result"] J --> K["Total Time:
~500-800ms
(with optimization)"] ``` --- ## 13. ALUR DEPLOYMENT & SETUP ```mermaid graph TD A["DEPLOYMENT WORKFLOW"] A --> B["1. Setup Laravel"] B --> B1["composer install"] B1 --> B2[".env configuration"] B2 --> B3["php artisan migrate"] A --> C["2. Setup Python ML Backend"] C --> C1["pip install requirements"] C1 --> C2["python create_model.py
(train model)"] C2 --> C3["Generate model_tomat.pkl"] A --> D["3. Create Directories"] D --> D1["storage/app/uploads/"] D1 --> D2["matang/"] D1 --> D3["mentah/"] D1 --> D4["setengah_matang/"] A --> E["4. Start Services"] E --> E1["npm run dev (Frontend)"] E1 --> E2["php artisan serve (Laravel)"] E2 --> E3["python app.py (Flask)"] E3 --> E4["✅ System Running"] ``` --- ## 14. ALUR FITUR EKSTRAKSI (DETAIL TEKNIS) ```mermaid graph TD A["Input: Image BGR
256x256x3"] --> B["Step 1: Color Space
Conversion"] B --> C["cv2.cvtColor
BGR → HSV"] C --> D["Output: Image HSV
256x256x3"] D --> E["Step 2: Histogram
Extraction"] E --> F["Channel 0: Hue"] F --> F1["cv2.calcHist
bins=8"] F1 --> F2["Normalized Histogram
shape: 8"] E --> G["Channel 1: Saturation"] G --> G1["cv2.calcHist
bins=8"] G1 --> G2["Normalized Histogram
shape: 8"] E --> H["Channel 2: Value"] H --> H1["cv2.calcHist
bins=8"] H1 --> H2["Normalized Histogram
shape: 8"] F2 --> I["Step 3: Concatenate"] G2 --> I H2 --> I I --> J["Final Feature Vector
shape: 192
(8+8+8)×3"] J --> K["Input to Model:
X_test.shape = (1, 192)"] ``` --- # RINGKASAN KOMPONEN SISTEM | Komponen | Teknologi | Fungsi | |----------|-----------|--------| | Frontend | HTML/CSS/JS, Blade Template | User Interface, Upload Form | | Backend Web | Laravel 11 | API, Database, Authentication | | Backend ML | Flask, Python | Image Processing, Prediction | | Model | Random Forest, joblib | Classification | | Database | SQLite/MySQL | Store predictions, users | | Features | HSV Histogram | Color-based classification | | Classes | 3 (Matang, Mentah, Setengah Matang) | Tomato ripeness levels | --- # TEKNOLOGI STACK ``` 🎨 Frontend: └─ HTML5 / CSS3 / JavaScript (Vanilla) └─ Alpine.js (optional) └─ Blade Templating Engine ⚙️ Backend Web: └─ PHP 8.x └─ Laravel 11 └─ Eloquent ORM └─ Laravel Routes & Controllers 🐍 Backend ML: └─ Python 3.8+ └─ Flask (API Server) └─ OpenCV (cv2) └─ scikit-learn (ML) └─ NumPy (Numerical) └─ joblib (Model persistence) 💾 Database: └─ MySQL / SQLite └─ Migrations for versioning 📦 Deployment: └─ Apache / Nginx (Laravel) └─ Gunicorn / uWSGI (Flask) ```