TIF_E41253368/RINGKASAN_FITUR.md

11 KiB

Ringkasan Fitur Prediksi Harga Cabai Jember

Dokumen ini merangkum fitur yang terdeteksi pada seluruh proyek PrediksiHargaCabe, terutama folder api dan website.

1. Gambaran Umum

Proyek terdiri dari dua bagian utama:

  • Backend api: REST API berbasis Flask untuk membaca data harga, memuat model LSTM tersimpan, menghasilkan prediksi, serta menyediakan data untuk peta.
  • Frontend website: aplikasi React + Vite untuk menampilkan peta pasar, harga aktual, prediksi, riwayat harga, dan indikator tren.

Walaupun beberapa instruksi atau dokumentasi lama menyebut FastAPI, implementasi backend yang aktif saat ini menggunakan Flask. Entry point-nya adalah api/main.py dan aplikasi dibuat melalui app.create_app().

2. Fitur Backend

2.1 Status API

  • GET /
    • Mengecek bahwa API aktif.
    • Mengembalikan pesan status dalam bahasa Indonesia.
  • GET /api/v1/health
    • Menampilkan status kesehatan API.
    • Menampilkan jumlah model yang berhasil dimuat.
    • Menampilkan daftar model yang berhasil dimuat per komoditas.
    • Menampilkan daftar artefak model yang dilewati beserta alasannya.

2.2 Informasi Komoditas dan Pasar

  • GET /api/v1/commodities
    • Mengembalikan komoditas yang memiliki model tersedia.
    • Menyertakan nama komoditas dan jumlah pasar yang tersedia.
  • GET /api/v1/markets
    • Mengembalikan lima pasar di Kabupaten Jember beserta koordinatnya.
    • Dapat difilter dengan query commodity.
    • Menandai komoditas yang tersedia untuk setiap pasar.

Komoditas yang didefinisikan backend:

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

Pasar yang didefinisikan backend:

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

2.3 Riwayat Harga

  • GET /api/v1/history?commodity={komoditas}&market={pasar}&days={jumlah_hari}
  • Mengambil riwayat harga dari CSV.
  • Nilai days default-nya 90 hari dan dibatasi antara 1 sampai 365 hari.
  • Data tanggal diurutkan dan data tanggal duplikat menggunakan nilai terakhir.
  • Nilai kosong atau tidak valid diproses sebagai data yang tidak tersedia.
  • Nilai nol diperlakukan sebagai data kosong, lalu nilai kosong di tengah rangkaian dapat diinterpolasi secara linear hingga dua titik.
  • Nilai harga dikonversi menggunakan PRICE_UNIT_SCALE, default 1000.

2.4 Prediksi Multi-Langkah

  • GET /api/v1/predict?commodity={komoditas}&market={pasar}&horizon={hari}
  • Horizon yang tersedia secara default: 1, 7, 24, dan 30 hari.
  • Prediksi menggunakan pendekatan recursive multi-step forecasting.
  • Hasil prediksi mencakup:
    • harga aktual terakhir;
    • tanggal prediksi;
    • harga setiap langkah;
    • perubahan harga dalam rupiah;
    • perubahan persentase;
    • harga minimum, maksimum, dan rata-rata;
    • tren up, down, atau flat;
    • umur data;
    • peringatan data lama atau prediksi di luar rentang training;
    • metadata metode dan time_step.
  • Hasil prediksi disimpan dalam cache berdasarkan komoditas, pasar, dan tanggal data terakhir.

2.5 Prediksi untuk Peta

  • GET /api/v1/predict/map?commodity={komoditas}&horizon={hari}
  • Menghasilkan ringkasan prediksi untuk seluruh pasar.
  • Setiap lokasi dapat berisi:
    • koordinat pasar;
    • ketersediaan model;
    • harga aktual terakhir;
    • harga prediksi;
    • perubahan harga;
    • persentase perubahan;
    • arah tren.
  • Jika model atau data suatu pasar tidak tersedia, lokasi tetap dikembalikan dengan status tidak tersedia dan alasan kegagalan.

2.6 Pemuatan Model dan Scaler

  • Model dan scaler dimuat ketika aplikasi dibuat melalui ModelRegistry.
  • Model Keras dimuat menggunakan compile=False.
  • Scaler dimuat menggunakan joblib, dengan fallback ke pickle.
  • Setiap konfigurasi model dapat menentukan nama file model dan scaler melalui config.json.
  • Path artefak divalidasi agar tidak keluar dari folder pasar.
  • Model yang tidak lengkap atau gagal dimuat dilewati dan dicatat pada informasi health.
  • API tidak melakukan training atau model.fit() ketika melayani prediksi.

Artefak yang tersedia:

  • Cabai Rawit: model untuk lima pasar.
  • Cabai Merah Besar: model untuk lima pasar.
  • Cabai Merah Keriting: model untuk Pasar Kreongan, Pasar Mangli, dan Pasar Wirolegi.
  • Setiap kombinasi model menggunakan file model Keras .h5, scaler .pkl, dan konfigurasi .json jika lengkap.

2.7 Validasi dan Error Handling

Backend memiliki format error terstruktur:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Pesan kesalahan",
    "details": {}
  }
}

Validasi yang tersedia meliputi:

  • komoditas tidak dikenal;
  • pasar tidak dikenal;
  • model tidak tersedia;
  • parameter query wajib;
  • horizon tidak valid;
  • jumlah data historis tidak mencukupi;
  • file CSV tidak ditemukan;
  • kolom tanggal atau kolom pasar tidak ditemukan;
  • kesalahan internal server.

2.8 CORS dan Konfigurasi

Konfigurasi backend dapat diubah melalui environment variable:

  • MODELS_DIR: lokasi folder model;
  • DATA_DIR: lokasi CSV;
  • PRICE_UNIT_SCALE: skala harga, default 1000;
  • ALLOWED_HORIZONS: daftar horizon yang dipisahkan koma, default 1,3,7;
  • MAX_HORIZON: batas horizon maksimum, default 7;
  • CORS_ORIGINS: origin frontend yang diizinkan;
  • STALE_DATA_DAYS: ambang data dianggap lama;
  • TREND_THRESHOLD_PCT: ambang perubahan untuk menentukan tren.

Nilai default CORS_ORIGINS saat ini adalah * untuk kemudahan pengembangan. Untuk deployment produksi, sebaiknya diisi dengan daftar origin frontend yang spesifik.

3. Fitur Frontend

3.1 Dashboard Publik

Frontend menampilkan dashboard bernama Panen Harga dengan fokus pada harga cabai Kabupaten Jember.

Fitur dashboard:

  • indikator koneksi API;
  • pilihan komoditas;
  • pilihan horizon 1, 7, 24, atau 30 hari;
  • pencarian pasar;
  • notifikasi kesalahan dan tombol coba lagi;
  • tampilan tanggal data terakhir;
  • tata letak responsif untuk layar desktop dan mobile.

3.2 Peta Interaktif

  • Menggunakan React Leaflet dan OpenStreetMap.
  • Menampilkan marker untuk lokasi pasar.
  • Marker dapat dipilih untuk membuka detail lokasi.
  • Peta otomatis memusatkan tampilan ke pasar yang dipilih.
  • Marker dibedakan berdasarkan status terpilih dan ketersediaan model/data.
  • Popup marker menampilkan nama pasar dan prediksi harga.
  • Daftar pasar di samping peta dapat digunakan sebagai alternatif pemilihan lokasi.

3.3 Panel Detail Pasar

Untuk pasar yang dipilih, frontend menampilkan:

  • nama pasar;
  • koordinat;
  • komoditas;
  • indikator tren naik, turun, atau datar;
  • prediksi pada horizon yang dipilih;
  • harga aktual terakhir;
  • tanggal data terakhir;
  • tabel prediksi per langkah;
  • perubahan harga per langkah;
  • peringatan jika data sudah lama atau prediksi berada di luar rentang training.

Untuk horizon lebih dari tujuh hari, tabel visual menampilkan tujuh langkah pertama dan mengarahkan pengguna ke endpoint API untuk data lengkap.

3.4 Riwayat Harga

  • Menampilkan ringkasan harga aktual terbaru.
  • Menampilkan riwayat 30 hari untuk pasar yang dipilih.
  • Menggunakan visualisasi sparkline sederhana berbasis elemen HTML/CSS.
  • Menampilkan tanggal awal dan tanggal akhir riwayat.

3.5 State dan Loading UI

Frontend memiliki state untuk:

  • daftar komoditas;
  • daftar pasar;
  • prediksi peta;
  • pasar terpilih;
  • horizon;
  • pencarian pasar;
  • detail prediksi;
  • riwayat harga;
  • status loading;
  • status error;
  • filter mobile.

Tersedia tampilan loading saat menghubungkan ke API dan tampilan kosong ketika data API belum tersedia.

4. Alur Integrasi Frontend dan Backend

  1. Frontend memanggil /commodities dan /markets ketika halaman dibuka.
  2. Frontend memanggil /predict/map ketika komoditas atau horizon berubah.
  3. Frontend memanggil /predict dan /history ketika pasar, komoditas, atau horizon berubah.
  4. Respons API dipetakan ke marker, daftar pasar, panel detail, dan riwayat harga.
  5. Error dari backend dibaca dari format error.message dan ditampilkan kepada pengguna.

Base URL frontend dapat diubah dengan:

$env:VITE_API_BASE_URL="http://127.0.0.1:8000/api/v1"

Jika environment variable tersebut tidak diatur, frontend menggunakan default:

http://127.0.0.1:8000/api/v1

5. Data dan Model

Data input yang ditemukan di backend:

  • CSV Cabai Rawit;
  • CSV Cabai Merah Keriting;
  • CSV Cabai Merah Besar.

Data tersebut digunakan oleh CsvPriceRepository, bukan database relasional.

Folder model tersimpan di api/models dan dikelompokkan berdasarkan komoditas lalu pasar. Model di-load dari file yang dirujuk oleh config.json; nama file tidak ditebak secara bebas ketika konfigurasi tersedia.

6. Pengujian

Backend memiliki pengujian untuk:

  • proses recursive forecasting;
  • perlindungan agar hasil prediksi tidak negatif;
  • pemuatan registry dengan artefak tidak lengkap;
  • kontrak endpoint health;
  • validasi komoditas;
  • validasi horizon;
  • format error API.

Perintah pengujian:

cd api
pytest

Perintah menjalankan backend:

cd api
python main.py

Atau dengan Flask CLI:

cd api
flask --app main:app run --host 127.0.0.1 --port 8000

Perintah menjalankan frontend:

cd website
npm install
npm run dev -- --host 127.0.0.1

Perintah build dan lint frontend:

cd website
npm run build
npm run lint

7. Struktur File Penting

api/
├── main.py
├── requirements.txt
├── app/
│   ├── __init__.py
│   ├── config.py
│   ├── errors.py
│   ├── api/
│   │   ├── routes.py
│   │   └── schemas.py
│   ├── data/
│   │   ├── markets.json
│   │   └── repository.py
│   └── services/
│       ├── forecaster.py
│       ├── model_registry.py
│       └── prediction_service.py
├── models/
└── tests/

website/
├── package.json
├── vite.config.js
├── index.html
└── src/
    ├── App.jsx
    ├── main.jsx
    ├── services/api.js
    ├── data/mockData.js
    ├── Public.css
    └── assets/

8. Catatan Implementasi Saat Ini

  • Backend aktual adalah Flask dengan prefix API /api/v1.
  • Dokumentasi website/README.md masih menyebut fase mock data dan integrasi backend belum dilakukan, tetapi kode website/src/services/api.js dan website/src/App.jsx saat ini sudah memanggil API backend secara langsung.
  • website/src/data/mockData.js masih tersimpan sebagai data contoh/warisan, tetapi bukan sumber data utama pada alur dashboard saat ini.
  • Folder node_modules, cache Python, dan website/dist merupakan dependensi atau hasil build; folder tersebut tidak dianggap sebagai fitur aplikasi inti.
  • Halaman publik yang aktif pada implementasi saat ini adalah satu dashboard React. Rute hash seperti #/home, #/map, #/about, dan #/admin yang tertulis di README belum terlihat di komponen App.jsx.