TIF_E41253368/REFERENSI_APLIKASI.md

18 KiB

Referensi Lengkap Aplikasi Panen Harga

Dokumen ini menjelaskan aplikasi Panen Harga, yaitu sistem prediksi harga cabai di Kabupaten Jember dengan visualisasi peta digital interaktif. Dokumen ini dapat digunakan sebagai referensi untuk menjelaskan tujuan aplikasi, arsitektur, fitur, alur data, teknologi, API, database, model LSTM, pengelolaan scraping, serta batasan sistem.

1. Identitas dan tujuan aplikasi

Nama aplikasi

Panen Harga

Tujuan

Aplikasi digunakan untuk:

  • menampilkan harga cabai berdasarkan pasar di Kabupaten Jember;
  • menampilkan lokasi pasar melalui peta digital;
  • menghasilkan prediksi harga menggunakan model LSTM yang sudah dilatih;
  • membantu pengguna membandingkan harga aktual dan hasil forecast;
  • menyediakan panel admin untuk memperbarui data secara manual;
  • menyediakan preprocessing terbatas untuk menangani gap data;
  • mencatat riwayat scraping dan proses pengolahan data.

Aplikasi ini bukan marketplace dan tidak melakukan transaksi jual beli. Fokusnya adalah informasi harga, visualisasi lokasi, dan prediksi harga.

Komoditas

Sistem mendukung tiga komoditas:

Slug API Nama
rawit Cabai Rawit
merah Cabai Merah Besar
keriting Cabai Merah Keriting

Pasar

Pasar yang terdaftar:

  • Pasar Tanjung
  • Pasar Kreongan
  • Pasar Tegal Besar
  • Pasar Mangli
  • Pasar Wirolegi

Ketersediaan model dapat berbeda untuk setiap komoditas. Saat ini model cabai merah keriting hanya tersedia untuk pasar yang memiliki artifact lengkap. Aplikasi tidak membuat prediksi palsu untuk pasar tanpa model atau data.

2. Teknologi dan tools

Backend

  • Bahasa: Python 3.9
  • Framework: Flask
  • Server development: Werkzeug melalui app.run
  • Database driver: PyMySQL
  • Data processing: pandas dan NumPy
  • Machine learning runtime: TensorFlow 2.10
  • Preprocessing dan scaler: scikit-learn
  • Pemuat scaler: joblib atau pickle
  • HTTP scraping: requests
  • Parsing tabel HTML: pandas dan lxml
  • Pengujian: pytest
  • CORS: flask-cors

Entry point backend adalah api/main.py. Aplikasi Flask dibuat melalui application factory create_app().

Frontend

  • Bahasa: JavaScript modern dengan JSX
  • Framework: React 19
  • Build tool: Vite
  • Lint: Oxlint
  • Peta: Leaflet dan React Leaflet
  • Grafik: Recharts
  • Ikon: Lucide React
  • Styling: CSS biasa melalui website/src/Public.css

Database

  • Database: MySQL/MariaDB
  • Pengelolaan lokal: phpMyAdmin, XAMPP, Laragon, atau WAMP
  • Nama database default: prediksicabe

Model dan artifact

Setiap kombinasi komoditas/pasar dapat memiliki:

  • model.h5: model LSTM yang sudah dilatih;
  • scaler.pkl: scaler yang digunakan saat training;
  • config.json: metadata model dan konfigurasi training.

API memuat artifact satu kali saat startup. API tidak menjalankan training ulang ketika aplikasi berjalan.

3. Struktur proyek

Struktur utama:

C:\PrediksiHargaCabe\
├── api\
│   ├── main.py
│   ├── requirements.txt
│   ├── restart_backend.ps1
│   ├── README.md
│   ├── app\
│   │   ├── __init__.py
│   │   ├── config.py
│   │   ├── errors.py
│   │   ├── api\
│   │   │   └── routes.py
│   │   ├── data\
│   │   │   ├── markets.json
│   │   │   └── repository.py
│   │   └── services\
│   │       ├── forecaster.py
│   │       ├── model_registry.py
│   │       ├── prediction_service.py
│   │       └── siskaperbapo_scraper.py
│   ├── models\
│   │   ├── rawit\
│   │   ├── merah\
│   │   └── keriting\
│   └── tests\
├── database\
│   └── panen_harga.sql
├── website\
│   ├── package.json
│   └── src\
│       ├── App.jsx
│       ├── Public.css
│       └── services\
│           └── api.js
├── RINGKASAN_FITUR.md
└── REFERENSI_APLIKASI.md

4. Arsitektur aplikasi

Pengguna
   │
   ▼
React/Vite frontend :5173
   │ HTTP/JSON + session cookie
   ▼
Flask REST API :8000
   ├── PredictionService
   ├── ModelRegistry
   ├── PriceRepository
   └── SiskaperbapoScraper
   │
   ├── Artifact model LSTM
   └── MySQL prediksicabe

Frontend tidak mengakses database secara langsung. Semua data diambil melalui service layer pada website/src/services/api.js. Backend bertanggung jawab atas validasi, akses database, scraping, preprocessing, dan inference model.

5. Alur data utama

5.1 Data penelitian awal

Data CSV penelitian dapat dimasukkan satu kali ke MySQL menggunakan script import. Harga CSV dikonversi ke Rupiah penuh sebelum disimpan.

CSV penelitian
    ↓
import_csv_to_mysql.py
    ↓
price_history
    ↓
PriceRepository

5.2 Data scraping manual

Scraping tidak berjalan otomatis dan tidak memiliki scheduler.

Admin memilih komoditas dan tanggal
    ↓
POST /api/v1/admin/scraping/jobs
    ↓
Background thread
    ↓
SISKAPERBAPO
    ↓
Normalisasi harga
    ↓
price_history
    ↓
scraping_logs

Data baru dicatat menggunakan scraping_log_id, sehingga satu riwayat scraping dapat ditelusuri dan dihapus bersama data yang dihasilkannya.

5.3 Preprocessing

Preprocessing manual dapat dijalankan terhadap satu log scraping yang dipilih. Metode yang digunakan adalah interpolasi linear untuk gap internal yang memenuhi batas sistem. Gap di awal/akhir atau gap terlalu panjang tidak diisi secara sembarangan dan dilaporkan sebagai warning.

Pilih riwayat scraping
    ↓
POST /api/v1/admin/preprocessing/jobs
    ↓
Pemeriksaan gap
    ↓
Interpolasi linear yang diizinkan
    ↓
price_history + preprocessing_runs

Repository juga melakukan interpolasi internal terbatas ketika membaca series untuk inference. Perilaku ini berfungsi sebagai validasi/fallback agar gap kecil tidak langsung membuat prediksi gagal.

5.4 Inference prediksi

Alur inference:

Data historis terbaru dari database
    ↓
Pilih data valid terakhir sesuai time_step
    ↓
Konversi input ke satuan ribuan untuk model
    ↓
Transform dengan scaler.pkl
    ↓
Model H5 menghasilkan prediksi
    ↓
Inverse transform
    ↓
Konversi kembali ke Rupiah penuh
    ↓
Recursive forecast 1, 3, atau 7 hari
    ↓
Response API

Data scraping baru tidak melatih ulang model. Data tersebut hanya menjadi data aktual terbaru yang digunakan sebagai input inference.

6. Satuan harga dan presisi

Aturan penyimpanan database:

Semua harga positif di price_history disimpan dalam Rupiah penuh.

Contoh:

8234  → Rp8.234
8500  → Rp8.500
9275  → Rp9.275

Model dapat bekerja dalam satuan ribuan Rupiah sesuai artifact training. API melakukan penyesuaian satuan ketika inference dan mengembalikan hasil dalam Rupiah penuh.

Harga prediksi tidak dibulatkan ke ribuan. Frontend menampilkan maksimal dua angka desimal jika hasil model memiliki pecahan.

Nilai 0, kosong, dan nilai tidak valid diperlakukan sebagai data kosong, bukan harga aktual yang valid.

7. Fitur dashboard publik

Dashboard publik berada pada route utama website.

7.1 Pemilihan filter

Pengguna dapat memilih:

  • jenis cabai;
  • pasar;
  • horizon prediksi 1, 3, atau 7 hari.

Prediksi tidak dijalankan otomatis ketika halaman pertama kali dibuka. Pengguna harus menekan tombol Prediksi.

7.2 Data terakhir

Bagian Data terakhir menampilkan tanggal data terbaru untuk setiap komoditas. Sistem mencari pasar aktif yang memiliki ketersediaan komoditas tersebut, sehingga komoditas tidak bergantung pada pasar yang kosong.

7.3 Peta interaktif

Peta menggunakan Leaflet dan OpenStreetMap tile layer. Fitur peta:

  • marker lokasi pasar;
  • marker terpilih;
  • tooltip nama pasar dan harga;
  • popup harga aktual, forecast, perubahan, dan tren;
  • pemusatan peta ke pasar yang dipilih;
  • mode Aktual dan Forecast;
  • legenda status harga;
  • peringkat pasar berdasarkan harga aktual atau forecast.

Pasar yang tidak memiliki model atau data tidak dipaksakan menjadi hasil prediksi.

7.4 Grafik dan tabel

Dashboard menampilkan:

  • riwayat harga aktual;
  • grafik aktual dan forecast;
  • tabel forecast per tanggal;
  • perubahan harga dalam Rupiah;
  • perubahan persentase;
  • indikator tren;
  • indikator harga di bagian bawah dashboard.

7.5 Indikator harga

Indikator harga mengambil data dari response prediksi, bukan membuat prediksi sendiri di frontend. Indikator menampilkan:

  • Naik;
  • Turun;
  • Stabil;
  • perubahan Rupiah pada langkah terakhir;
  • perubahan persentase pada langkah terakhir.

8. Fitur panel admin

Panel admin menggunakan route #/admin.

8.1 Autentikasi

Fitur autentikasi:

  • register;
  • login;
  • logout;
  • session cookie;
  • role user dan admin.

Endpoint admin memerlukan role admin.

8.2 Ringkasan

Ringkasan menampilkan informasi operasional:

  • jumlah data harga;
  • jumlah komoditas;
  • jumlah pasar;
  • status pembaruan terakhir;
  • jumlah data terbaru dari scraping terakhir.

8.3 Dataset harga

Halaman Dataset harga menyediakan:

  • tabel data harga;
  • filter komoditas;
  • filter pasar;
  • pagination;
  • harga dan tanggal data.

8.4 Perbarui data

Fitur Perbarui data menyediakan:

  • pilihan komoditas scraping;
  • tanggal mulai dan tanggal akhir;
  • progress bar scraping;
  • log riwayat scraping;
  • jenis cabai pada setiap log;
  • status scraping;
  • jumlah data baru;
  • detail data yang masuk;
  • filter detail berdasarkan komoditas dan pasar;
  • pagination;
  • tombol hapus log;
  • modal konfirmasi penghapusan.

8.5 Preprocessing

Section preprocessing berada di bagian bawah halaman Perbarui data. Admin dapat:

  1. memilih satu riwayat scraping;
  2. melihat jenis cabai dan jumlah data pada dropdown;
  3. menjalankan preprocessing;
  4. melihat progress;
  5. melihat jumlah baris yang diisi;
  6. melihat warning gap yang tidak dapat diisi.

9. Endpoint API

Prefix API:

/api/v1

Endpoint publik

Method Endpoint Keterangan
GET / Status API dasar
GET /api/v1/health Status API dan artifact model
GET /api/v1/commodities Daftar komoditas tersedia
GET /api/v1/markets Daftar pasar dan ketersediaan komoditas
GET /api/v1/history Riwayat harga
GET /api/v1/predict Prediksi satu pasar
GET /api/v1/predict/map Prediksi ringkas seluruh pasar

Contoh:

GET /api/v1/history?commodity=rawit&market=pasar_tanjung&days=30
GET /api/v1/predict?commodity=rawit&market=pasar_tanjung&horizon=7
GET /api/v1/predict/map?commodity=rawit&horizon=7

Endpoint autentikasi

Method Endpoint Keterangan
GET /api/v1/auth/me User session saat ini
POST /api/v1/auth/register Registrasi user
POST /api/v1/auth/login Login
POST /api/v1/auth/logout Logout

Endpoint admin

Method Endpoint Keterangan
GET /api/v1/admin/overview Ringkasan operasional
GET /api/v1/admin/models Metadata/status model
GET /api/v1/admin/scraping/logs Riwayat scraping
GET /api/v1/admin/scraping/logs/<id>/records Detail data dari log
POST /api/v1/admin/scraping/jobs Memulai scraping
GET /api/v1/admin/scraping/jobs/<id> Status scraping
DELETE /api/v1/admin/scraping/logs/<id> Hapus log dan data terkait
DELETE /api/v1/admin/scraping/history Hapus history scraping
POST /api/v1/admin/preprocessing/jobs Memulai preprocessing
GET /api/v1/admin/preprocessing/jobs/<id> Status preprocessing
GET /api/v1/prices Dataset harga dengan pagination

Format error API:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Pesan untuk pengguna",
    "details": {}
  }
}

10. Struktur database

Schema lengkap tersedia pada database/panen_harga.sql.

Tabel utama

Tabel Fungsi
commodities Master jenis cabai
markets Master pasar dan koordinat
price_history Harga aktual per komoditas, pasar, dan tanggal
scraping_logs Riwayat proses scraping
preprocessing_runs Riwayat proses preprocessing
users Akun dan role
training_runs Metadata training jika dikelola di luar API
model_versions Metadata versi model
predictions Struktur penyimpanan forecast jika digunakan

Relasi penting:

commodities 1 ─── * price_history
markets     1 ─── * price_history
scraping_logs 1 ─── * price_history
commodities 1 ─── * training_runs
commodities 1 ─── * model_versions

Kunci unik price_history adalah kombinasi:

commodity_id + market_id + price_date

Karena itu scraping tanggal yang sama akan memperbarui data yang sudah ada, bukan membuat duplikat baru.

11. Konfigurasi environment

Variabel penting backend:

Variabel Default Fungsi
DATA_SOURCE mysql Sumber data aktif
MYSQL_HOST 127.0.0.1 Host MySQL
MYSQL_PORT 3306 Port MySQL
MYSQL_DATABASE prediksicabe Nama database
MYSQL_USER root User database
MYSQL_PASSWORD kosong Password database
MODELS_DIR api/models Folder artifact
DATA_DIR folder api Folder CSV
PRICE_UNIT_SCALE 1000 Skala CSV lama ke Rupiah
ALLOWED_HORIZONS 1,3,7 Horizon yang diizinkan
MAX_HORIZON 7 Batas horizon
CORS_ORIGINS localhost:5173 Origin frontend
STALE_DATA_DAYS 30 Ambang data lama
TREND_THRESHOLD_PCT 1 Ambang status tren
SISKAPERBAPO_TIMEOUT 30 Timeout request scraper

Untuk produksi, ganti SECRET_KEY default dan batasi CORS_ORIGINS hanya pada origin frontend yang dipercaya.

12. Cara menjalankan aplikasi

12.1 Menjalankan backend

Gunakan environment Conda yang sudah tersedia:

cd C:\PrediksiHargaCabe\api
C:\Users\alfia\anaconda3\envs\tf_gpu39\python.exe main.py

Atau gunakan script restart:

cd C:\PrediksiHargaCabe\api
powershell -ExecutionPolicy Bypass -File .\restart_backend.ps1

Backend berjalan di:

http://127.0.0.1:8000

12.2 Menjalankan frontend

cd C:\PrediksiHargaCabe\website
npm run dev

Frontend Vite biasanya berjalan di:

http://localhost:5173

12.3 Build frontend

cd C:\PrediksiHargaCabe\website
npm run lint
npm run build

12.4 Pengujian backend

cd C:\PrediksiHargaCabe\api
C:\Users\alfia\anaconda3\envs\tf_gpu39\python.exe -m pytest

13. Keamanan dan batasan operasional

  • Endpoint admin dilindungi autentikasi dan role admin.
  • Password disimpan dalam bentuk hash.
  • Frontend tidak terhubung langsung ke database.
  • Scheduler scraping otomatis belum diaktifkan.
  • Training ulang otomatis belum diaktifkan.
  • API tidak menjalankan model.fit().
  • Data input scraping tidak boleh dianggap sebagai hasil evaluasi model baru.
  • Data terbaru hasil scraping adalah data operasional untuk inference.
  • Jangan mengklaim model sebagai “global optimum”. Gunakan istilah: “konfigurasi terbaik yang diperoleh dari skema eksperimen yang diterapkan pada dataset penelitian.”

14. Batasan model dan interpretasi hasil

Recursive forecasting

Prediksi lebih dari satu hari menggunakan hasil prediksi sebelumnya sebagai input berikutnya. Akibatnya, error dapat terakumulasi pada horizon yang lebih panjang.

Ketersediaan artifact

Tidak semua komoditas harus tersedia pada semua pasar. Kombinasi tanpa artifact lengkap ditampilkan sebagai tidak tersedia.

Data lama

API dapat memberikan warning data_stale apabila tanggal data terakhir melewati ambang STALE_DATA_DAYS.

Model deployment tidak sama dengan training ulang

Scraping baru tidak mengubah bobot model. Jika penelitian memerlukan model baru, training harus dilakukan melalui proses eksperimen terpisah, divalidasi, lalu artifact baru dideploy secara sadar.

15. Cara menjelaskan aplikasi saat presentasi

Urutan penjelasan yang disarankan:

  1. Jelaskan masalah: harga cabai berbeda antar pasar dan berubah dari waktu ke waktu.
  2. Jelaskan sumber data: dataset penelitian dan data SISKAPERBAPO.
  3. Jelaskan tiga komoditas dan pasar yang diamati.
  4. Tunjukkan peta digital pasar.
  5. Pilih komoditas dan pasar.
  6. Pilih horizon prediksi.
  7. Tekan tombol Prediksi.
  8. Jelaskan harga aktual terakhir, forecast, grafik, tabel, dan indikator tren.
  9. Jelaskan bahwa model menggunakan artifact LSTM yang sudah divalidasi.
  10. Jelaskan bahwa scraping memperbarui data aktual, bukan melatih ulang model.
  11. Tunjukkan panel admin untuk log scraping dan preprocessing.
  12. Jelaskan keterbatasan model dan pasar yang artifact-nya belum tersedia.

16. Ringkasan satu paragraf

Panen Harga adalah aplikasi web berbasis React dan Flask yang menggunakan model LSTM tersimpan untuk memprediksi harga tiga komoditas cabai di pasar-pasar Kabupaten Jember. Data harga disimpan dalam MySQL menggunakan Rupiah penuh, sedangkan model dan scaler dimuat dari artifact saat backend dimulai. Pengguna dapat memilih komoditas, pasar, dan horizon prediksi, kemudian melihat hasilnya melalui peta Leaflet, ranking pasar, grafik riwayat, grafik forecast, tabel prediksi, dan indikator tren. Admin dapat melakukan scraping manual dari SISKAPERBAPO, memantau progress, melihat log, menghapus hasil scraping, dan menjalankan preprocessing terbatas. Sistem tidak melakukan scheduler maupun training ulang otomatis sehingga artifact model penelitian tetap terkendali.