Mif_E31230483_KlasifikasiTomat/FLOWCHART_ASCII_VISUAL.txt

707 lines
45 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ 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
═══════════════════════════════════════════════════════════════════════════════