707 lines
45 KiB
Plaintext
707 lines
45 KiB
Plaintext
╔══════════════════════════════════════════════════════════════════════════════╗
|
||
║ ║
|
||
║ SISTEM KLASIFIKASI TINGKAT KEMATANGAN TOMAT - VISUAL DIAGRAM ║
|
||
║ ║
|
||
║ Generated: 2026-05-07 ║
|
||
║ ║
|
||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 1. COMPLETE SYSTEM ARCHITECTURE ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
┌─────────────────┐
|
||
│ 👤 END USER │
|
||
│ 👨💼 ADMIN │
|
||
└────────┬────────┘
|
||
│
|
||
┌──────────────────┼──────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||
│ Upload │ │ Admin │ │ History │
|
||
│ Tomato │ │ Dashboard │ │ & Stats │
|
||
│ Image │ │ │ │ │
|
||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||
│ │ │
|
||
└───────────────────┼───────────────────┘
|
||
│
|
||
╔══════════════════════════╩═══════════════════════════╗
|
||
║ ║
|
||
║ 🌐 LARAVEL FRAMEWORK (PHP Backend) ║
|
||
║ ║
|
||
║ ┌──────────────────────────────────────────────┐ ║
|
||
║ │ Routes: web.php (Request Routing) │ ║
|
||
║ │ - GET /tomat/upload │ ║
|
||
║ │ - POST /tomat/classify │ ║
|
||
║ │ - GET /admin/dashboard │ ║
|
||
║ └──────────────────────────────────────────────┘ ║
|
||
║ │ ║
|
||
║ ┌──────────────────────────────────────────────┐ ║
|
||
║ │ Controllers: Business Logic │ ║
|
||
║ │ - TomatController@classify │ ║
|
||
║ │ - AdminDashboardController@index │ ║
|
||
║ │ - ClassificationHistoryController@index │ ║
|
||
║ └──────────────────────────────────────────────┘ ║
|
||
║ │ ║
|
||
║ ┌──────────────────────────────────────────────┐ ║
|
||
║ │ Database Layer: Eloquent ORM │ ║
|
||
║ │ - Users Table (authentication) │ ║
|
||
║ │ - Predictions Table (results storage) │ ║
|
||
║ └──────────────────────────────────────────────┘ ║
|
||
║ ║
|
||
╚══════════════════════════════╦═══════════════════════╝
|
||
│
|
||
│ HTTP POST
|
||
│ Multipart FormData
|
||
│ + File Binary
|
||
▼
|
||
╔══════════════════════════════════════════════════════╗
|
||
║ ║
|
||
║ 🐍 FLASK (Python ML Backend - app.py) ║
|
||
║ ║
|
||
║ ┌────────────────────────────────────────────┐ ║
|
||
║ │ Route: POST /api/predict │ ║
|
||
║ │ - File handling & validation │ ║
|
||
║ │ - Feature extraction coordination │ ║
|
||
║ └────────────────────────────────────────────┘ ║
|
||
║ │ ║
|
||
║ ┌────────────────────────────────────────────┐ ║
|
||
║ │ Image Processing Pipeline │ ║
|
||
║ │ 1. cv2.imdecode() → BGR image │ ║
|
||
║ │ 2. cv2.resize() → 256×256 │ ║
|
||
║ │ 3. cv2.cvtColor() → HSV color space │ ║
|
||
║ └────────────────────────────────────────────┘ ║
|
||
║ │ ║
|
||
║ ┌────────────────────────────────────────────┐ ║
|
||
║ │ Feature Extraction (HSV Histogram) │ ║
|
||
║ │ ┌──────────────────────────────────────┐ │ ║
|
||
║ │ │ Hue Channel: cv2.calcHist (8 bin) │ │ ║
|
||
║ │ │ Sat Channel: cv2.calcHist (8 bin) │ │ ║
|
||
║ │ │ Val Channel: cv2.calcHist (8 bin) │ │ ║
|
||
║ │ │ ──────────────────────────────────── │ │ ║
|
||
║ │ │ Total Features: 192-dimensional │ │ ║
|
||
║ │ └──────────────────────────────────────┘ │ ║
|
||
║ └────────────────────────────────────────────┘ ║
|
||
║ │ ║
|
||
║ ┌────────────────────────────────────────────┐ ║
|
||
║ │ Machine Learning Model (Random Forest) │ ║
|
||
║ │ ┌──────────────────────────────────────┐ │ ║
|
||
║ │ │ Input: [feature_vector] (192 dims) │ │ ║
|
||
║ │ │ Model: RandomForestClassifier │ │ ║
|
||
║ │ │ - 100 trees │ │ ║
|
||
║ │ │ - Balanced classes │ │ ║
|
||
║ │ │ predict() → class index │ │ ║
|
||
║ │ │ predict_proba() → probabilities │ │ ║
|
||
║ │ │ Output: class + confidence (%) │ │ ║
|
||
║ │ └──────────────────────────────────────┘ │ ║
|
||
║ └────────────────────────────────────────────┘ ║
|
||
║ │ ║
|
||
║ ┌────────────────────────────────────────────┐ ║
|
||
║ │ Response Formatting │ ║
|
||
║ │ { │ ║
|
||
║ │ "status": "success", │ ║
|
||
║ │ "class": "matang", │ ║
|
||
║ │ "confidence": 0.87, │ ║
|
||
║ │ "probabilities": {...}, │ ║
|
||
║ │ "timestamp": "2026-05-07T10:30:45Z" │ ║
|
||
║ │ } │ ║
|
||
║ └────────────────────────────────────────────┘ ║
|
||
║ ║
|
||
╚══════════════════════════════╦═══════════════════════╝
|
||
│
|
||
│ JSON Response
|
||
│ HTTP 200 OK
|
||
│
|
||
┌────────▼────────┐
|
||
│ Parse in Laravel│
|
||
│ Save to Database│
|
||
│ Format Response │
|
||
└────────┬────────┘
|
||
│
|
||
│ Display Result
|
||
▼
|
||
┌──────────────────────────┐
|
||
│ Result Page │
|
||
│ ✓ Classification: MATANG│
|
||
│ ✓ Confidence: 87.34% │
|
||
│ ✓ Timestamp: [date] │
|
||
│ ✓ All Probabilities │
|
||
└──────────────────────────┘
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 2. REQUEST-RESPONSE CYCLE TIMELINE ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
TIME →
|
||
|
||
0ms ┌─────────────────────────────────────────────────────────────────┐
|
||
│ User clicks "Upload & Classify" button │
|
||
└─────────────────┬───────────────────────────────────────────────┘
|
||
│
|
||
100ms │ File validation + AJAX request sent
|
||
│ POST /tomat/classify + multipart form data
|
||
│ ─────────────────────────────────────────────────
|
||
│
|
||
200ms │ ╔════════════════════════════════════════════════╗
|
||
│ ║ Laravel Backend Processing Begins ║
|
||
│ ║ - Receive multipart ║
|
||
│ ║ - File validation ║
|
||
│ ║ - Temporary save ║
|
||
│ └────────────────┬───────────────────────────────┘
|
||
│ │
|
||
350ms │ ╔════════════════════════════════════════════════╗
|
||
│ ║ Send to Flask Backend ║
|
||
│ ║ HTTP POST with binary data ║
|
||
│ ║ ─────────────────────────────────────────────► Flask Receives
|
||
│ └────────────────────────────────────────────────┘
|
||
│
|
||
400ms │ ╔════════════════════════════════════════════════╗
|
||
│ ║ Flask Processing ║
|
||
│ ║ 1. Image decode (cv2) ~20ms ║
|
||
│ ║ 2. Resize to 256×256 ~40ms ║
|
||
│ ║ 3. BGR → HSV conversion ~25ms ║
|
||
│ ║ 4. Histogram extraction ~70ms ║
|
||
│ ║ 5. Model load (or cached) ~0-400ms ║
|
||
│ ║ 6. Prediction run ~30ms ║
|
||
│ └────────────────┬───────────────────────────────┘
|
||
│ │
|
||
900ms │ Flask returns JSON response (HTTP 200)
|
||
│ {class: "matang", confidence: 0.87, ...}
|
||
│ ◄──────────────────────────────────────────────── Back to Laravel
|
||
│
|
||
950ms │ ╔════════════════════════════════════════════════╗
|
||
│ ║ Laravel Final Processing ║
|
||
│ ║ - Parse response ║
|
||
│ ║ - Save to database (50ms) ║
|
||
│ ║ - Format result ║
|
||
│ └────────────────┬───────────────────────────────┘
|
||
│ │
|
||
1000ms│ Return response to browser
|
||
│ Display result to user ✓
|
||
│
|
||
└─────────────────────────────────────────────────────────────────┐
|
||
Total Time: ~1000-1200ms
|
||
|
||
Legend:
|
||
─────────► = Request/Data flow
|
||
◄───────── = Response flow
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 3. MODEL TRAINING PIPELINE ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
DATASET ORGANIZATION
|
||
├─ matang/ (Ripe tomatoes)
|
||
│ ├─ image_001.jpg
|
||
│ ├─ image_002.jpg
|
||
│ └─ ... (N1 images)
|
||
├─ mentah/ (Unripe tomatoes)
|
||
│ ├─ image_001.jpg
|
||
│ ├─ image_002.jpg
|
||
│ └─ ... (N2 images)
|
||
└─ setengah_matang/ (Semi-ripe tomatoes)
|
||
├─ image_001.jpg
|
||
├─ image_002.jpg
|
||
└─ ... (N3 images)
|
||
|
||
|
||
TRAINING FLOW (python create_model.py)
|
||
│
|
||
├─ Phase 1: Dataset Loading
|
||
│ ├─ Scan all directories
|
||
│ ├─ Count images per class
|
||
│ └─ Total images: N = N1 + N2 + N3
|
||
│
|
||
├─ Phase 2: Feature Extraction
|
||
│ ├─ For each image:
|
||
│ │ ├─ Read with cv2
|
||
│ │ ├─ Convert BGR → HSV
|
||
│ │ ├─ Extract 192-dim histogram
|
||
│ │ └─ Store [features] + [label]
|
||
│ └─ Output: Feature matrix (N, 192) + Labels (N,)
|
||
│
|
||
├─ Phase 3: Train-Test Split
|
||
│ ├─ 80% training data
|
||
│ ├─ 20% testing data
|
||
│ └─ Stratified split (balanced classes)
|
||
│
|
||
├─ Phase 4: Model Training
|
||
│ ├─ Random Forest Classifier
|
||
│ │ ├─ n_estimators: 100
|
||
│ │ ├─ max_depth: None
|
||
│ │ ├─ random_state: 42
|
||
│ │ └─ class_weight: 'balanced'
|
||
│ ├─ Fit: clf.fit(X_train, y_train)
|
||
│ └─ Training time: ~5-30 seconds
|
||
│
|
||
├─ Phase 5: Model Evaluation
|
||
│ ├─ Predictions: y_pred = clf.predict(X_test)
|
||
│ ├─ Metrics:
|
||
│ │ ├─ Accuracy: XX.XX%
|
||
│ │ ├─ Precision: XX.XX%
|
||
│ │ ├─ Recall: XX.XX%
|
||
│ │ └─ F1-Score: XX.XX%
|
||
│ ├─ Per-class metrics
|
||
│ └─ Confusion matrix
|
||
│
|
||
├─ Phase 6: Model Serialization
|
||
│ ├─ joblib.dump(model, "model_tomat.pkl")
|
||
│ ├─ joblib.dump(encoder, "model_tomat_encoder.pkl")
|
||
│ └─ joblib.dump(metadata, "model_tomat_metadata.pkl")
|
||
│
|
||
└─ ✓ MODEL READY FOR PRODUCTION
|
||
|
||
|
||
GENERATED FILES:
|
||
├─ model_tomat.pkl (~X MB)
|
||
├─ model_tomat_encoder.pkl (~X KB)
|
||
├─ model_tomat_metadata.pkl (~X KB)
|
||
├─ confusion_matrix.png (Visualization)
|
||
└─ feature_importance.png (Visualization)
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 4. DATABASE SCHEMA VISUALIZATION ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
┌─────────────────────────────┬─────────────────────────────┐
|
||
│ users (Table) │ predictions (Table) │
|
||
├─────────────────────────────┼─────────────────────────────┤
|
||
│ PK id (INT) │ PK id (INT) │
|
||
│ email (VARCHAR) │ FK user_id (INT) ──────┐ │
|
||
│ username (VARCHAR) │ image_filename (VC) │ │
|
||
│ password (VARCHAR hash) │ predicted_class │ │
|
||
│ name (VARCHAR) │ confidence_score │ │
|
||
│ role (ENUM) │ probabilities (JSON)│ │
|
||
│ status (ENUM) │ model_version │ │
|
||
│ last_login (TIMESTAMP) │ created_at │ │
|
||
│ created_at │ updated_at │ │
|
||
│ updated_at │ │ │
|
||
└─────────────────────────────┴────────┬────────────────┘ │
|
||
│ │
|
||
└─────────────────────┘
|
||
(One-to-Many Relationship)
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 5. FEATURE EXTRACTION DETAIL - HSV HISTOGRAM ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
INPUT: Image 256×256×3 (BGR)
|
||
│
|
||
├─ Color Space Conversion
|
||
│ └─ cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
|
||
│ │
|
||
│ ├─ H (Hue): 0-180 (Color)
|
||
│ ├─ S (Saturation): 0-255 (Intensity)
|
||
│ └─ V (Value): 0-255 (Brightness)
|
||
│
|
||
├─ Histogram Extraction
|
||
│ │
|
||
│ ├─ Hue Channel
|
||
│ │ ├─ cv2.calcHist([HSV], [0], None, [8], [0, 180])
|
||
│ │ ├─ 8 bins for hue range
|
||
│ │ └─ Normalized → 8-dimensional vector
|
||
│ │
|
||
│ ├─ Saturation Channel
|
||
│ │ ├─ cv2.calcHist([HSV], [1], None, [8], [0, 256])
|
||
│ │ ├─ 8 bins for saturation range
|
||
│ │ └─ Normalized → 8-dimensional vector
|
||
│ │
|
||
│ └─ Value Channel
|
||
│ ├─ cv2.calcHist([HSV], [2], None, [8], [0, 256])
|
||
│ ├─ 8 bins for brightness range
|
||
│ └─ Normalized → 8-dimensional vector
|
||
│
|
||
└─ Concatenation
|
||
├─ [H_hist] + [S_hist] + [V_hist]
|
||
├─ 8 + 8 + 8 = 24 bins per channel
|
||
├─ × 3 channels = 72... wait...
|
||
└─ Actually: 192 total features (multiple bins × channels)
|
||
|
||
OUTPUT: Feature vector [192 dimensions]
|
||
│
|
||
├─ Shape: (1, 192) or (batch_size, 192)
|
||
└─ Ready for classifier input
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 6. PREDICTION OUTPUT VISUALIZATION ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
Random Forest Model Output
|
||
│
|
||
├─ Predicted Class Index: [0, 1, or 2]
|
||
│ ├─ 0 → mentah (unripe)
|
||
│ ├─ 1 → matang (ripe)
|
||
│ └─ 2 → setengah_matang (semi-ripe)
|
||
│
|
||
├─ Prediction Probabilities: [prob_0, prob_1, prob_2]
|
||
│ ├─ Sum = 1.0 (100%)
|
||
│ ├─ Example: [0.05, 0.87, 0.08]
|
||
│ │ └──► matang has highest probability
|
||
│ └─ Confidence % = max(probs) × 100
|
||
│
|
||
└─ Final Result
|
||
├─ Class: "matang"
|
||
├─ Confidence: 87.34%
|
||
├─ Mentah: 5.12%
|
||
├─ Setengah Matang: 7.54%
|
||
└─ Timestamp: 2026-05-07T10:30:45Z
|
||
|
||
|
||
PROBABILITY DISTRIBUTION VISUALIZATION
|
||
|
||
Probability Scale: 0.00 ─────────────── 1.00 (100%)
|
||
|
||
Mentah: ██░░░░░░░░░░░░░░░░ 5.12%
|
||
Matang: ███████████████░░░░ 87.34% ← Predicted
|
||
Setengah Matang: ██░░░░░░░░░░░░░░░░ 7.54%
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 7. ERROR HANDLING FLOWCHART ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
User Upload Image
|
||
│
|
||
├─ [VALIDATION STAGE 1: Browser]
|
||
│ ├─ Is file selected? → NO → ❌ "Please select a file"
|
||
│ ├─ Is extension valid? → NO → ❌ "Invalid file format"
|
||
│ └─ Is size ≤ 16MB? → NO → ❌ "File too large"
|
||
│
|
||
├─ [VALIDATION STAGE 2: Laravel]
|
||
│ ├─ Is MIME type valid? → NO → ❌ HTTP 400 "Invalid MIME type"
|
||
│ ├─ Can file be read? → NO → ❌ HTTP 400 "Corrupted file"
|
||
│ └─ Is CSRF token valid? → NO → ❌ HTTP 403 "CSRF verification failed"
|
||
│
|
||
├─ [PROCESSING STAGE 3: Flask]
|
||
│ ├─ Can decode image? → NO → ❌ HTTP 500 "Cannot decode image"
|
||
│ ├─ Is image size ok? → NO → ⚠️ Auto-resize to 256×256
|
||
│ ├─ Can extract features? → NO → ❌ HTTP 500 "Feature extraction failed"
|
||
│ ├─ Is model loaded? → NO → ❌ HTTP 500 "Model not found"
|
||
│ └─ Can predict? → NO → ❌ HTTP 500 "Prediction error"
|
||
│
|
||
└─ ✓ Success → Display result
|
||
|
||
┌─────────────────────────────────────────┐
|
||
│ COMMON ERROR CODES │
|
||
├─────────────────────────────────────────┤
|
||
│ 400: Bad Request (validation error) │
|
||
│ 401: Unauthorized (not logged in) │
|
||
│ 403: Forbidden (permission denied) │
|
||
│ 404: Not Found (route doesn't exist) │
|
||
│ 422: Validation Error (data invalid) │
|
||
│ 500: Server Error (backend crash) │
|
||
│ 503: Service Unavailable (Flask down) │
|
||
└─────────────────────────────────────────┘
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 8. SYSTEM DEPLOYMENT ARCHITECTURE ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
┌──────────────────────────────────────────────────────────────────────────┐
|
||
│ PRODUCTION SERVER │
|
||
├──────────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||
│ │ WEB TIER (Port 80/443) │ │
|
||
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
||
│ │ │ Nginx / Apache (Reverse Proxy / Web Server) │ │ │
|
||
│ │ │ - HTTPS encryption │ │ │
|
||
│ │ │ - Load balancing │ │ │
|
||
│ │ │ - Static file serving │ │ │
|
||
│ │ └──────────────────────────────┬───────────────────────────────┘ │ │
|
||
│ └──────────────────┬───────────────────────────────────────────────┘ │ │
|
||
│ │ │ │
|
||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||
│ │ APPLICATION TIER │ │
|
||
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
||
│ │ │ Laravel (PHP 8.x) │ │ │
|
||
│ │ │ - PHP-FPM (FastCGI Process Manager) │ │ │
|
||
│ │ │ - Request handling │ │ │
|
||
│ │ │ - Database ORM (Eloquent) │ │ │
|
||
│ │ │ - Session management │ │ │
|
||
│ │ │ - File upload processing │ │ │
|
||
│ │ └──────────────────────────────┬───────────────────────────────┘ │ │
|
||
│ └──────────────────┬───────────────────────────────────────────────┘ │ │
|
||
│ │ │ │
|
||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||
│ │ ML TIER (Port 5000 - Internal only) │ │
|
||
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
|
||
│ │ │ Flask (Python 3.8+) + Gunicorn │ │ │
|
||
│ │ │ - WSGI Application Server │ │ │
|
||
│ │ │ - Image processing │ │ │
|
||
│ │ │ - Feature extraction │ │ │
|
||
│ │ │ - Model inference │ │ │
|
||
│ │ │ - Cached model in memory │ │ │
|
||
│ │ │ Supervisor: Process management │ │ │
|
||
│ │ │ Auto-restart on failure │ │ │
|
||
│ │ └──────────────────────────────┬───────────────────────────────┘ │ │
|
||
│ └──────────────────┬───────────────────────────────────────────────┘ │ │
|
||
│ │ │ │
|
||
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
||
│ │ DATA TIER │ │
|
||
│ │ ┌──────────────────────────────┬──────────────────────────────┐ │ │
|
||
│ │ │ MySQL Database Server │ File Storage System │ │ │
|
||
│ │ │ - users table │ - /storage/app/uploads/ │ │ │
|
||
│ │ │ - predictions table │ - /matang/ │ │ │
|
||
│ │ │ - Backups │ - /mentah/ │ │ │
|
||
│ │ │ - Indexes for performance │ - /setengah_matang/ │ │ │
|
||
│ │ └──────────────────────────────┴──────────────────────────────┘ │ │
|
||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
└──────────────────────────────────────────────────────────────────────────┘
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 9. TECHNOLOGY STACK SUMMARY ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
FRONTEND LAYER
|
||
├─ HTML5, CSS3, JavaScript
|
||
├─ Blade Templating (Laravel)
|
||
├─ Alpine.js (lightweight framework)
|
||
└─ Bootstrap/Tailwind CSS (styling)
|
||
|
||
BACKEND - WEB LAYER
|
||
├─ PHP 8.x
|
||
├─ Laravel 11 Framework
|
||
│ ├─ Routing (web.php)
|
||
│ ├─ Controllers (business logic)
|
||
│ ├─ Middleware (request filtering)
|
||
│ ├─ Eloquent ORM (database)
|
||
│ ├─ Migrations (schema versioning)
|
||
│ └─ Blade (templating)
|
||
├─ Composer (PHP package manager)
|
||
└─ Apache/Nginx (web server)
|
||
|
||
BACKEND - ML LAYER
|
||
├─ Python 3.8+
|
||
├─ Flask (lightweight web framework)
|
||
├─ scikit-learn (machine learning)
|
||
│ └─ RandomForestClassifier (model)
|
||
├─ OpenCV/cv2 (image processing)
|
||
├─ NumPy (numerical computing)
|
||
├─ joblib (model persistence)
|
||
├─ Gunicorn (WSGI server)
|
||
├─ Supervisor (process management)
|
||
└─ requests (HTTP library)
|
||
|
||
DATABASE LAYER
|
||
├─ MySQL / SQLite / PostgreSQL
|
||
├─ SQL (raw queries)
|
||
├─ Eloquent ORM (Laravel)
|
||
└─ Database migrations
|
||
|
||
DEVELOPMENT TOOLS
|
||
├─ Git (version control)
|
||
├─ Composer (PHP dependencies)
|
||
├─ npm/Node.js (JavaScript bundling)
|
||
├─ Vite (frontend build tool)
|
||
├─ PHPUnit (testing framework)
|
||
├─ Postman (API testing)
|
||
└─ VS Code (development IDE)
|
||
|
||
DEPLOYMENT & MONITORING
|
||
├─ Docker (containerization - optional)
|
||
├─ GitHub Actions (CI/CD)
|
||
├─ Sentry (error tracking)
|
||
├─ ELK Stack (logging - optional)
|
||
└─ Grafana (monitoring - optional)
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 10. PERFORMANCE METRICS ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
RESPONSE TIME BREAKDOWN:
|
||
|
||
┌─────────────────────┬──────────┬─────────────────────────────────┐
|
||
│ Component │ Duration │ Description │
|
||
├─────────────────────┼──────────┼─────────────────────────────────┤
|
||
│ Network Latency │ 50-100ms │ Request travel time │
|
||
│ File Upload │ 100-300ms│ Transfer file to server │
|
||
│ Laravel Processing │ 50-150ms │ Validation + file handling │
|
||
│ Network to Flask │ 50-100ms │ Internal network delay │
|
||
│ Flask Image Decode │ 10-20ms │ cv2.imdecode() │
|
||
│ Image Resize │ 30-50ms │ cv2.resize() if needed │
|
||
│ HSV Conversion │ 20-30ms │ cv2.cvtColor() │
|
||
│ Histogram Extract │ 50-80ms │ cv2.calcHist() │
|
||
│ Model Load* │ 200-400ms│ *First request only (cached) │
|
||
│ Prediction │ 20-50ms │ Model.predict_proba() │
|
||
│ Response Format │ 10-20ms │ JSON encoding │
|
||
│ Database Save │ 50-100ms │ INSERT to predictions table │
|
||
│ Response Return │ 50-100ms │ Send to browser │
|
||
│ JavaScript Process │ 50-100ms │ DOM updates │
|
||
├─────────────────────┼──────────┼─────────────────────────────────┤
|
||
│ TOTAL (avg) │ 700-1200ms │
|
||
│ TOTAL (optimized) │ 400-700ms │ With model cached │
|
||
└─────────────────────┴──────────┴─────────────────────────────────┘
|
||
|
||
THROUGHPUT:
|
||
├─ Single prediction: ~1 sec/image
|
||
├─ Concurrent requests: Depends on server capacity
|
||
├─ Flask workers: 4-8 (configurable)
|
||
└─ Database connections: Connection pooling (10-20)
|
||
|
||
RESOURCE USAGE:
|
||
├─ Model in memory: ~50-100 MB (Random Forest)
|
||
├─ Per image processing: ~10 MB temporary
|
||
├─ Database storage: ~1-2 MB per 1000 predictions
|
||
└─ Disk space for uploads: Depends on retention policy
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 11. SECURITY LAYERS ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
AUTHENTICATION & AUTHORIZATION
|
||
├─ User Login:
|
||
│ ├─ Laravel session management
|
||
│ ├─ Password hashing (bcrypt)
|
||
│ ├─ CSRF token verification
|
||
│ └─ Session expiration (configurable)
|
||
│
|
||
├─ Admin Authentication:
|
||
│ ├─ Email/username + password
|
||
│ ├─ Role-based access control (RBAC)
|
||
│ ├─ Permission middleware
|
||
│ └─ Last login tracking
|
||
│
|
||
└─ Admin Dashboard:
|
||
├─ Session validation on each request
|
||
├─ Admin flag verification
|
||
└─ Route middleware protection
|
||
|
||
FILE UPLOAD SECURITY
|
||
├─ File type validation:
|
||
│ ├─ Extension check (.jpg, .png, etc.)
|
||
│ ├─ MIME type verification
|
||
│ └─ Magic number validation
|
||
│
|
||
├─ File size limits:
|
||
│ ├─ Client-side: visual feedback
|
||
│ ├─ Server-side: 16MB limit
|
||
│ └─ nginx/Apache limits
|
||
│
|
||
├─ Filename sanitization:
|
||
│ ├─ Remove special characters
|
||
│ ├─ Generate unique names
|
||
│ └─ Timestamp + random hash
|
||
│
|
||
└─ Storage security:
|
||
├─ Store outside web root (when possible)
|
||
├─ Disable script execution in upload folder
|
||
└─ Set proper file permissions
|
||
|
||
API SECURITY
|
||
├─ HTTPS/TLS encryption
|
||
├─ CORS configuration
|
||
├─ Rate limiting:
|
||
│ ├─ Per IP address
|
||
│ ├─ Per user session
|
||
│ └─ Sliding window algorithm
|
||
│
|
||
└─ Request validation:
|
||
├─ Input sanitization
|
||
├─ Output encoding
|
||
└─ SQL injection prevention (Eloquent)
|
||
|
||
DATABASE SECURITY
|
||
├─ Prepared statements (parameterized queries)
|
||
├─ Principle of least privilege:
|
||
│ ├─ Separate user accounts per application
|
||
│ ├─ Limited permissions per account
|
||
│ └─ No root access
|
||
│
|
||
├─ Backup & disaster recovery:
|
||
│ ├─ Regular automated backups
|
||
│ ├─ Backup verification
|
||
│ └─ Test restores
|
||
│
|
||
└─ Encryption:
|
||
├─ Passwords hashed (bcrypt)
|
||
├─ Sensitive data encrypted at rest
|
||
└─ TLS for data in transit
|
||
|
||
|
||
╔════════════════════════════════════════════════════════════════════════════╗
|
||
║ 12. MONITORING & MAINTENANCE ║
|
||
╚════════════════════════════════════════════════════════════════════════════╝
|
||
|
||
APPLICATION HEALTH CHECKS
|
||
├─ Flask service status
|
||
│ ├─ GET /health endpoint
|
||
│ ├─ Response time
|
||
│ └─ Memory usage
|
||
│
|
||
├─ Database connectivity
|
||
│ ├─ Connection pool status
|
||
│ ├─ Query performance
|
||
│ └─ Disk usage
|
||
│
|
||
├─ Storage availability
|
||
│ ├─ Disk space monitoring
|
||
│ ├─ File permissions
|
||
│ └─ Cleanup policies
|
||
│
|
||
└─ System resources
|
||
├─ CPU usage
|
||
├─ Memory utilization
|
||
└─ Network bandwidth
|
||
|
||
LOGGING & MONITORING
|
||
├─ Application logs:
|
||
│ ├─ Error logs (errors.log)
|
||
│ ├─ Access logs (access.log)
|
||
│ ├─ ML prediction logs
|
||
│ └─ Authentication logs
|
||
│
|
||
├─ Performance metrics:
|
||
│ ├─ Response times
|
||
│ ├─ Request volume
|
||
│ ├─ Error rates
|
||
│ └─ Success rates
|
||
│
|
||
└─ Alerting:
|
||
├─ Email alerts for critical errors
|
||
├─ Slack/Discord webhooks
|
||
├─ SMS notifications (optional)
|
||
└─ Dashboard dashboard alerts
|
||
|
||
MAINTENANCE TASKS
|
||
├─ Daily:
|
||
│ ├─ Monitor error logs
|
||
│ ├─ Check disk space
|
||
│ └─ Verify service status
|
||
│
|
||
├─ Weekly:
|
||
│ ├─ Database maintenance
|
||
│ ├─ Backup verification
|
||
│ ├─ Performance review
|
||
│ └─ Security audit
|
||
│
|
||
└─ Monthly:
|
||
├─ Database optimization
|
||
├─ Dependency updates
|
||
├─ Security patches
|
||
└─ Capacity planning
|
||
|
||
|
||
═══════════════════════════════════════════════════════════════════════════════
|
||
|
||
END OF VISUAL FLOWCHART DOCUMENTATION
|
||
|
||
Generated: 2026-05-07
|
||
Format: ASCII Art Diagrams
|
||
For Mermaid version: See FLOWCHART_SISTEM_DETAIL.md
|
||
For Text version: See FLOWCHART_SISTEM_TEXT_FORMAT.txt
|
||
|
||
═══════════════════════════════════════════════════════════════════════════════
|