Para Aktor Utama
Komponen, layanan, dan cara pengorganisasiannya.
Kenali Setiap Komponen dengan Membaca Kodenya
Tutorial ini memandu Anda menelusuri komponen-komponen utama sistem, satu per satu. Di akhir tutorial, Anda akan mengetahui apa yang dilakukan setiap bagian, di mana letaknya, dan bagaimana hubungannya dengan bagian lain.
Pintu Depan — app.py
app.py adalah tempat aplikasi dimulai. File ini membuat objek aplikasi FastAPI, mengimpor 13 router, mendaftarkan masing-masing dengan app.include_router(), mengatur CORS middleware, memasang file statis untuk frontend, dan mendefinisikan startup event yang menginisialisasi database, penjadwal alert, worker antrian, dan perbaikan analisis macet.
Buka file tersebut dan lihat bagian atas:
Sekarang lihat startup event:
File Processor
file_processor_simple.py bertanggung jawab untuk memvalidasi dan mengurai unggahan. Ketika pengguna mengirimkan file geospasial, komponen ini mengambil alih. Komponen ini menerima tiga format file: GeoJSON, KML, dan Shapefile ZIP.
Salah satu fitur terpentingnya adalah perbaikan otomatis. Jika geometri yang diunggah tidak valid (poligon yang saling berpotongan, ring yang tidak tertutup), processor memanggil shapely.make_valid() untuk memperbaikinya secara diam-diam daripada menolak unggahan.
Processor mengembalikan objek PlotData yang berisi:
- geometry — geometri GeoJSON yang telah divalidasi/diperbaiki
- feature_count — jumlah fitur dalam file
- total_area_hectares — total luas semua fitur
- bounds — bounding box geometri
Forest Analyzer
forest_analyzer_with_alerts.py (45KB) adalah otak dari seluruh sistem. Ini adalah bagian logika bisnis terbesar dan komponen yang mengubah data mentah menjadi keputusan kepatuhan EUDR.
Komponen ini menggabungkan empat sumber data menjadi satu hasil:
- Data hutan GEE — Hansen Global Forest Change untuk persentase tutupan hutan
- Alert GLAD — deteksi deforestasi optik (Landsat, 30m)
- Alert RADD — deteksi deforestasi radar (Sentinel-1, 10m)
- Risiko negara — daftar negara berisiko tinggi (BR, ID, CD, PE, CO, BO, VE, MY)
Ambang batas dimuat dari file konfigurasi, bukan di-hardcode, sehingga dapat disesuaikan tanpa mengubah kode. Titik masuk utamanya adalah:
Layanan Alert
Sistem memiliki dua layanan alert yang bekerja secara independen tetapi menghasilkan hasil yang kompatibel:
GLAD (glad_alert_service.py, 35KB) — Menggunakan dataset Hansen Global Forest Change melalui Google Earth Engine. Resolusi: 30m. Cakupan: global, sejak 2001. Ini berbasis optik (Landsat), yang berarti awan dapat menghalangi deteksi.
RADD (radd_alert_service.py) — Menggunakan citra radar Sentinel-1 melalui Google Earth Engine. Resolusi: 10m. Cakupan: wilayah tropis, sejak 2019. Karena menggunakan radar, ia dapat bekerja menembus awan dan di malam hari.
Kedua layanan mengkueri GEE dan mengembalikan bentuk data yang sama:
Report Generator
report_generator.py (76KB) adalah file terbesar di seluruh codebase. File ini menggunakan ReportLab untuk membangun laporan PDF multi-halaman yang berfungsi sebagai dokumen kepatuhan utama.
Satu laporan mencakup:
- Ringkasan kepatuhan — keputusan, tingkat risiko, metrik utama
- Citra satelit — tiga periode waktu (baseline 2018, periode alert, saat ini)
- Peta NDVI — perubahan kesehatan vegetasi dari waktu ke waktu
- Tabel perbandingan GLAD/RADD — analisis alert berdampingan
- Klasifikasi tutupan lahan — rincian ESA WorldCover
Bekerja dengan Komponen
Cara menemukan di mana sebuah fitur diimplementasikan
Codebase mengikuti konvensi folder yang konsisten. Mengetahui konvensi ini membawa Anda ke file yang tepat dalam hitungan detik.
- Untuk logika bisnis (pekerjaan sesungguhnya), lihat di
backend/services/. Di sinilah analisis, alert, laporan, dan email diimplementasikan. - Untuk endpoint HTTP (URL apa yang ada, parameter apa yang diterima), lihat di
backend/api/. Setiap file di sini adalah router yang memanggil layanan. - Untuk bentuk data (field apa yang dimiliki objek), lihat di
backend/models/. Anda akan menemukanPlotData,AnalysisResult,ComplianceStatus, dan lainnya di sini. - Untuk integrasi sumber data eksternal (GEE, Planetary Computer, CDSE), lihat di
backend/providers/. Setiap provider mengimplementasikan antarmuka yang sama. - Untuk infrastruktur (koneksi database, konfigurasi), lihat di
backend/utils/.
Cara menambahkan endpoint API baru
- Buat fungsi endpoint Anda di file yang sesuai di dalam
backend/api/. Jika endpoint Anda berkaitan dengan analisis, tambahkan keapi/analysis.py. Jika itu domain baru, buat file baru. - Tambahkan decorator untuk mendaftarkan rute:
@router.get("/your-path")atau@router.post("/your-path"). - Jika Anda membuat file baru, impor routernya di
app.pydan daftarkan denganapp.include_router(your_router, prefix="/api/your-domain"). - Jika Anda menggunakan file yang sudah ada, router sudah terdaftar — endpoint baru Anda langsung tersedia.
Cara menelusuri bug melalui lapisan-lapisan
- Mulai dari lapisan API. Temukan endpoint di
backend/api/yang menangani request yang gagal. Periksa parameter apa yang diterima dan fungsi layanan apa yang dipanggil. - Ikuti ke layanan. Buka fungsi layanan di
backend/services/. Baca logikanya. Periksa data apa yang diharapkan dan apa yang dikembalikan. - Periksa model data. Buka kelas yang relevan di
backend/models/. Verifikasi bahwa nama field dan tipe cocok dengan apa yang dihasilkan layanan dan apa yang dikembalikan API. - Periksa kueri database. Jika bug melibatkan data tersimpan, lihat SQL di
backend/utils/database.pyatau kueri inline di layanan. Verifikasi nama kolom cocok dengan model. - Tambahkan logging di setiap lapisan. Modul
loggingPython sudah diimpor di sebagian besar file. Tambahkan panggilanlogger.info()di setiap batas untuk melihat di mana data berubah bentuk secara tidak terduga.
Mengapa Struktur Ini?
Pemisahan Tanggung Jawab
Codebase menggunakan arsitektur berlapis dengan empat lapisan berbeda:
Lapisan API
Penanganan HTTP. Menerima request, memvalidasi input, memanggil layanan, memformat response. Berada di backend/api/.
Lapisan Layanan
Logika bisnis. Melakukan pekerjaan sesungguhnya — menganalisis hutan, menghasilkan alert, membuat PDF. Berada di backend/services/.
Lapisan Model
Bentuk data. Mendefinisikan seperti apa plot, hasil analisis, atau alert. Berada di backend/models/.
Lapisan Database
Penyimpanan. Koneksi PostGIS, pengaturan skema, kueri. Berada di backend/utils/.
Bayangkan seperti rumah sakit. Meja resepsionis (lapisan API) tidak melakukan operasi — ia memeriksa janji temu Anda dan mengarahkan Anda ke departemen yang tepat. Tim bedah (lapisan layanan) melakukan pekerjaan sesungguhnya, menggunakan rekam medis standar (model) dan ruang arsip (database). Setiap departemen memiliki tanggung jawab yang jelas, dan mencampurnya akan menciptakan kekacauan.
Pemisahan ini berarti Anda dapat mengubah tampilan PDF tanpa menyentuh endpoint API. Anda dapat mengganti database tanpa menulis ulang logika bisnis. Setiap lapisan memiliki satu tugas, dan menjalankan tugas itu dengan baik.
Lapisan Layanan Adalah Tempat Beban Utama
Jika Anda melihat ukuran file, polanya jelas:
| File | Ukuran | Tujuan |
|---|---|---|
report_generator.py | 76KB | Pembuatan PDF dengan citra satelit, NDVI, tutupan lahan |
forest_analyzer_with_alerts.py | 45KB | Mesin kepatuhan inti |
glad_alert_service.py | 35KB | Deteksi deforestasi optik via GEE |
analysis_queue_worker.py | 28KB | Pemrosesan job latar belakang |
File-file layanan ini adalah produknya. Lapisan API hanyalah pembungkus tipis — sebagian besar fungsi endpoint kurang dari 30 baris. Fungsi-fungsi tersebut memvalidasi input, memanggil metode layanan, dan mengembalikan hasilnya. Semua pengetahuan domain, semua aturan tentang apa yang merupakan deforestasi, semua logika untuk menggabungkan data GLAD dan RADD — semuanya ada di layanan.
Ini disengaja. Jika Anda memindahkan logika bisnis ke lapisan API, Anda tidak dapat menggunakannya kembali dari worker antrian latar belakang. Dengan menyimpannya di layanan, baik API sinkron maupun antrian async dapat memanggil metode analyze_plot() yang sama.
Mengapa 13 Router?
Setiap router menangani satu domain: analisis, autentikasi, laporan, alert, manajemen antrian, pemasok, plot, organisasi, metrik, rantai pasok, pemrosesan batch, dasbor, dan analisis lanjutan (dengan WebSocket).
Ini adalah praktik standar FastAPI. Menempatkan semua endpoint dalam satu file akan menciptakan file raksasa 3000 baris yang mustahil dinavigasi. Router terpisah berarti:
- Setiap file terfokus dan mudah dibaca (biasanya 100-300 baris)
- Developer berbeda dapat mengerjakan domain berbeda tanpa konflik merge
- Pengujian dapat menargetkan satu router pada satu waktu
- Prefix URL bersifat eksplisit:
/api/analysis,/api/auth,/api/alerts
Direktori Komponen
File Utama
| File | Peran | Ukuran | Metode Utama |
|---|---|---|---|
app.py |
Titik masuk | ~300 baris | startup_event() |
forest_analyzer_with_alerts.py |
Mesin analisis inti | 45KB | analyze_plot() |
glad_alert_service.py |
Deteksi deforestasi optik | 35KB | get_alerts_for_geometry_gee() |
radd_alert_service.py |
Deteksi deforestasi radar | — | get_alerts_for_geometry() |
report_generator.py |
Pembuatan PDF | 76KB | generate_compliance_report() |
analysis_queue_worker.py |
Pemroses job latar belakang | 28KB | _worker_loop() |
email_service.py |
Notifikasi | — | send_analysis_complete_email() |
file_processor_simple.py |
Penguraian unggahan | — | process_file() |
Struktur Folder
| Folder | Tujuan |
|---|---|
backend/api/ | Endpoint HTTP |
backend/services/ | Logika bisnis |
backend/models/ | Kelas data |
backend/providers/ | Adapter sumber data eksternal |
backend/utils/ | Infrastruktur (DB, konfigurasi) |
frontend/public/ | Antarmuka browser (HTML, JS) |