TIF_E41253368/RINGKASAN_FITUR.md

345 lines
11 KiB
Markdown

# 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:
```json
{
"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:
```powershell
$env:VITE_API_BASE_URL="http://127.0.0.1:8000/api/v1"
```
Jika environment variable tersebut tidak diatur, frontend menggunakan default:
```text
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:
```powershell
cd api
pytest
```
Perintah menjalankan backend:
```powershell
cd api
python main.py
```
Atau dengan Flask CLI:
```powershell
cd api
flask --app main:app run --host 127.0.0.1 --port 8000
```
Perintah menjalankan frontend:
```powershell
cd website
npm install
npm run dev -- --host 127.0.0.1
```
Perintah build dan lint frontend:
```powershell
cd website
npm run build
npm run lint
```
## 7. Struktur File Penting
```text
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`.