# 4.1.4 Arsitektur dan Integrasi Sistem

---

## Paragraf 1 — Gambaran Arsitektur Sistem

Aplikasi JTA merupakan komponen antarmuka (*frontend*) dalam sebuah ekosistem IoT yang terdiri dari empat lapisan utama: perangkat keras sensor (ESP32 + SHT31), server backend (Node.js di Railway), layanan database dan autentikasi (Supabase), serta aplikasi mobile Flutter sebagai ujung akses pengguna. Data sensor mengalir dari ESP32 melalui protokol MQTT menuju backend, kemudian disimpan ke database Supabase. Aplikasi Flutter mengambil data tersebut melalui REST API dan menampilkannya secara near real-time kepada pengguna. Lingkup pengembangan pada laporan ini berfokus pada **aplikasi mobile Flutter** sebagai komponen antarmuka sistem.

![Gambaran Umum Arsitektur Sistem](C:/Users/user/.gemini/antigravity/brain/f5437a05-a1d5-4e3b-aa37-20e3f692fed9/diagram_arsitektur_overview_1778563146372.png)

**Gambar 4.x** — Gambaran umum arsitektur sistem JTA. Lingkup laporan ini adalah lapisan Aplikasi Flutter (paling kanan).

---

## Paragraf 2 — Arsitektur Internal Aplikasi Flutter

Aplikasi Flutter dikembangkan menggunakan pola arsitektur berlapis (*layered architecture*) yang memisahkan tanggung jawab antara tampilan, logika bisnis, dan akses data. Terdapat lima lapisan yang disusun secara hierarkis:

1. **Presentation Layer** — halaman dan widget yang ditampilkan ke pengguna (`MonitoringPage`, `ControlPage`, `SchedulePage`, dsb.)
2. **State Management (Riverpod)** — mengelola state aplikasi secara reaktif melalui `MonitoringNotifier`, `ControlNotifier`, dan `AuthNotifier`
3. **Repository Layer** — abstraksi antara notifier dan sumber data, diimplementasikan oleh `IotRepository` dan `AuthRepository`
4. **Service Layer** — bertanggung jawab atas komunikasi jaringan: `ApiIotService` untuk data sensor, `ApiControlService` untuk perintah kontrol, dan `AuthService` untuk autentikasi
5. **External Services** — REST API backend (Railway) dan Supabase (autentikasi + database)

![Arsitektur Internal Aplikasi Flutter](C:/Users/user/.gemini/antigravity/brain/f5437a05-a1d5-4e3b-aa37-20e3f692fed9/diagram_layer_flutter_1778563225044.png)

**Gambar 4.x** — Arsitektur internal aplikasi Flutter (JTA) dengan lima lapisan terpisah.

Pemisahan lapisan ini memudahkan pengujian dan penggantian implementasi—misalnya, `IotRepository` dapat menerima implementasi `ApiIotService` atau implementasi mock untuk keperluan pengujian tanpa mengubah kode di lapisan atas.

---

## Paragraf 3 — Koneksi dan Konfigurasi Layanan Eksternal

Aplikasi menggunakan dua layanan eksternal: **REST API backend** dan **Supabase**. Konfigurasi base URL API terpusat pada kelas `ApiConfig`, sehingga pergantian environment (lokal, staging, production) cukup dilakukan di satu titik:

```dart
// lib/core/api_config.dart
class ApiConfig {
  static const String baseUrl =
      'https://backendjamur-production.up.railway.app/api';
}
```

Seluruh request HTTP menggunakan package **`dio` (v5.4.0)** yang diinstansiasi per service. Endpoint yang dikonsumsi aplikasi meliputi:

| Endpoint | Metode | Fungsi |
|---|---|---|
| `/history/{deviceId}` | GET | Ambil data sensor terbaru & histori |
| `/history/{deviceId}/daily` | GET | Rata-rata sensor per hari |
| `/history/{deviceId}/hourly` | GET | Rata-rata sensor per jam |
| `/mode/{deviceId}` | GET / POST | Baca & ubah mode operasi |
| `/threshold/{deviceId}` | GET / POST | Baca & ubah batas suhu/kelembapan |
| `/schedule/{deviceId}` | GET / POST | Kelola jadwal irigasi |
| `/schedule/{deviceId}/now` | POST | Siram manual langsung |

Koneksi ke **Supabase** diinisialisasi satu kali saat aplikasi pertama dijalankan menggunakan package **`supabase_flutter` (v2.8.0)**. Supabase dimanfaatkan khusus untuk modul **autentikasi**—login, registrasi, dan persistensi sesi berbasis JWT—sementara akses data sensor sepenuhnya melalui REST API backend.

```dart
// lib/main.dart
await Supabase.initialize(
  url: 'https://tqibzvranbroouzdwhhh.supabase.co',
  anonKey: '<anon_key>',
);
```

Sesi login pengguna disimpan secara persisten oleh `supabase_flutter` sehingga pengguna tidak perlu login ulang setiap kali membuka aplikasi. Data `device_id` yang terikat ke akun pengguna diambil dari sesi ini dan digunakan sebagai parameter di setiap request API.

---

## Paragraf 4 — Mekanisme Pembaruan Data Sensor

Data sensor diperbarui secara near real-time melalui mekanisme **polling periodik** yang dikelola oleh `MonitoringNotifier`. Saat halaman monitoring dibuka, notifier melakukan inisialisasi awal dengan mengambil histori penuh dari API, kemudian mengaktifkan timer yang memanggil ulang API setiap **5 detik**. Hasilnya dikomparasi dengan data terakhir berdasarkan timestamp—hanya data baru yang ditambahkan ke state, sehingga grafik historis tidak memuat duplikat.

```dart
// Inisialisasi dan polling otomatis
_timer = Timer.periodic(const Duration(seconds: 5), (_) => fetchData());
```

Setiap respons API memperbarui `MonitoringState` melalui `state.copyWith()`, yang secara otomatis memicu rebuild hanya pada widget yang bergantung pada state tersebut (reaktivitas Riverpod). State juga menyertakan sinkronisasi status relay dan mode operasi ke `ControlNotifier` agar seluruh halaman aplikasi mencerminkan kondisi perangkat yang sesungguhnya.

![Mekanisme Polling Data Sensor](C:/Users/user/.gemini/antigravity/brain/f5437a05-a1d5-4e3b-aa37-20e3f692fed9/diagram_polling_flow_1778563276653.png)

**Gambar 4.x** — Alur pembaruan data sensor: dari inisialisasi hingga polling periodik 5 detik.

---

## Paragraf 5 — Penutup Sub-bab 4.1

Seluruh komponen aplikasi mobile JTA—mulai dari konfigurasi koneksi, arsitektur berlapis, manajemen state, hingga mekanisme pembaruan data—telah berhasil dikembangkan dan diintegrasikan dengan layanan backend dan Supabase. Pemisahan lapisan yang jelas antara presentation, state management, repository, dan service menjadikan aplikasi mudah dipelihara dan dikembangkan lebih lanjut. Pembahasan selanjutnya pada **Sub-bab 4.2 Implementasi Sistem** akan merinci tampilan antarmuka dan hasil implementasi fitur-fitur aplikasi secara keseluruhan.
