Skip to content

Feat: Import dan Pengelolaan Data Lokasi (Tipe Lokasi) Multi-Desa via API Database Gabungan - #1302

Open
pandigresik wants to merge 1 commit into
rilis-devfrom
002-tipe-lokasi-import
Open

pandigresik wants to merge 1 commit into
rilis-devfrom
002-tipe-lokasi-import

Conversation

@pandigresik

Copy link
Copy Markdown
Contributor

Pull Request: Feat: Import dan Pengelolaan Data Lokasi (Tipe Lokasi) Multi-Desa via API Database Gabungan

Description

Menambahkan fitur impor massal dan pengelolaan Data Lokasi (plan) di OpenKab yang disimpan ke API database gabungan (bukan database lokal), sehingga OpenSID dapat memakai Jenis/Kategori yang seragam. Template Excel kini memuat Nama Desa sebagai kolom per-baris (dropdown ke sheet "Daftar Desa") sehingga satu file dapat memuat banyak desa, dilengkapi CRUD manual, filter wilayah berjenjang, dan hapus massal.

Changes made:

  1. Import Template (baru): app/Exports/LokasiTemplateExport.php menghasilkan .xlsx dengan kolom Nama Desa | Nama Lokasi | Latitude | Longitude | Keterangan, sheet referensi "Daftar Desa", dan dropdown (data validation) pada kolom Nama Desa.
  2. Parser & Validasi Import (baru): app/Imports/LokasiImport.php mendeteksi baris header, memvalidasi per baris (Nama Desa wajib, Nama Lokasi wajib/max 50, koordinat), dan menolak baris kosong/tidak valid tanpa menggagalkan seluruh file.
  3. Controller pengelolaan lokasi: app/Http/Controllers/PlanController.php — import batch, unduh template, detail (untuk modal edit), store/update/hapus manual, dan hapus massal; memetakan Nama Desa → config_id per baris, tolak nama tidak dikenal/ganda, dan pre-check duplikat per desa (insert-only).
  4. FormRequest + Rule: app/Http/Requests/Peta/* (ImportLokasiRequest, DownloadTemplateLokasiRequest, StoreLokasiRequest, UpdateLokasiRequest, BulkDestroyLokasiRequest) dan app/Rules/ValidKodeDesa.php.
  5. Service API generik: app/Services/BaseApiService.php menambah apiCall/apiGet/apiPost/apiPut/apiDelete; app/Services/PemetaanService.php menambah planImport, planBulkDelete, serta memperbaiki endpoint planUpdate.
  6. Filter wilayah & hapus massal (UI): resources/views/peta/lokasi/filter.blade.php (pola seperti /penduduk: Kabupaten→Kecamatan→Desa + Status + Jenis/Kategori, tombol Tampilkan/Reset), table.blade.php (kolom Desa + checkbox), dan js/app.blade.php (DataTable, aksi hapus massal satu request).
  7. Batas koordinat Indonesia: app/Support/Coordinate.php (lat −11..6, lng 95..141) dipakai di StoreLokasiRequest, UpdateLokasiRequest, dan LokasiImport.
  8. Routes: routes/web.php menambah GET /plan/import/template, POST /plan/import, GET /plan/detail/{id}, POST /plan/store, PUT /plan/update/{id}, DELETE /plan/hapus (massal), DELETE /plan/hapus/{id}.
  9. Tes: tests/Feature/Peta/LokasiImportTest.php (21 tes) dan smoke test browser (tests/Browser/SmokeLokasiTest.php, SmokeLokasiImportTest.php).

Reason for change:

  • Point 1: OpenSID membutuhkan data lokasi geospasial terpusat; OpenKab menjadi pintu penambahan data via import massal sesuai kebutuhan OpenSID.
  • Point 2: Memuat banyak desa dalam satu file penting karena pengguna umumnya mengimpor satu jenis fasilitas (mis. sekolah) untuk semua desa, sehingga desa harus bisa dipilih per baris.
  • Point 3: Validasi per baris + ringkasan hasil menjaga integritas data dan memberi umpan balik jelas saat import gagal sebagian.

Impact of change:

✅ Efisiensi: Import massal multi-desa dalam satu file dan satu panggilan batch ke API.
✅ Konsistensi data: Jenis/Kategori mengikuti master terpusat; duplikat dicegah per desa (insert-only).
✅ Keamanan: Semua operasi tulis (termasuk hapus massal) melalui server-side proxy dengan bearer token; API key tidak terekspos ke browser.
✅ Usability: Filter wilayah berjenjang (pola /penduduk), kolom Desa, dan hapus massal memudahkan pengelolaan.

Related Issue

#1295

Steps to Reproduce

Before (problem):

  1. Buka menu Data Lokasi (/plan).
  2. Tidak tersedia fungsi import template, filter wilayah, kolom Desa, maupun hapus massal.
  3. Edit data lokasi gagal (route POST /plan/update/{id} tidak cocok dengan request _method=PUT; endpoint update API keliru).
  4. ❌ Data lokasi tidak dapat dikelola massal dan edit tidak berfungsi.

After (solution):

  1. Buka Data Lokasi (/plan) → klik Import.
  2. Pilih Jenis & Kategori → Download Template → buka .xlsx.
  3. Pilih Nama Desa per baris (dropdown), isi data, unggah, klik Import → tampil ringkasan berhasil/gagal.
  4. Klik Edit pada baris → form terisi (desa/jenis/kategori otomatis terisi) → simpan → ✅ perubahan tersimpan via API.
  5. Klik ikon filter → pilih Kabupaten/Kecamatan/Desa → Tampilkan → ✅ tabel tersaring.
  6. Centang beberapa baris → Hapus Terpilih → konfirmasi → ✅ satu request DELETE /api/v1/plan/?ids[]=....

Testing on related features:

  • Unduh template & dropdown Nama Desa ✅
  • Import multi-desa & ringkasan hasil ✅
  • CRUD manual (tambah/edit/hapus) ✅
  • Filter wilayah, Status, Jenis/Kategori ✅
  • Hapus massal ✅

Checklist

Technical Details

Technical Explanation

Alur import:

  1. GET /plan/import/template?jenis&kategori → LokasiTemplateExport menulis xlsx: sheet Data Lokasi (baris konteks Jenis/Kategori + header kolom) dan sheet Daftar Desa; dropdown Nama Desa disuntikkan ke XML xlsx (rentang kolom A).
  2. POST /plan/import (multipart) → LokasiImport memvalidasi per baris → PlanController::processImport():
    • memetakan nama_desa → config_id per baris (tolak kosong/tidak dikenal/ganda),
    • pre-check duplikat per desa (config_id + ref_point + nama, insert-only),
    • mengirim satu payload batch ke POST /api/v1/plan/import.

Payload import (batch):

{
  "data": [
    { "config_id": 1, "nama": "Kantor Desa", "desk": "pusat", "lat": "-6.2", "lng": "106.8", "ref_point": 10 },
    { "config_id": 2, "nama": "Posyandu",    "desk": "",      "lat": "-6.3", "lng": "106.7", "ref_point": 10 }
  ]
}

CRUD manual & hapus massal (server-side proxy via BaseApiService bearer token):

  • POST /api/v1/plan/store → item plan { config_id, nama, desk, lat, lng, ref_point }
  • PUT /api/v1/plan/update/{id} → payload yang sama
  • DELETE /api/v1/plan/hapus/{id} → hapus satu
  • DELETE /api/v1/plan/?ids[]=1&ids[]=2 → hapus massal (satu request)

Filter tabel dikirim ke GET /api/v1/plan sebagai filter[status], filter[point], filter[subpoint], filter[kode_kabupaten], filter[kode_kecamatan], filter[kode_desa].

Batas koordinat Indonesia (App\Support\Coordinate): lintang −11..6, bujur 95..141 (dipakai pada validasi FormRequest dan import per baris).

Configuration changes

Tidak ada perubahan konfigurasi baru. Menggunakan konfigurasi API database gabungan yang sudah ada (databaseGabunganUrl + bearer API key pada tabel settings).

Dependencies

https://github.com/OpenSID/API-Database-Gabungan/pull/471

Testing

Manual Testing

  • Unduh template menampilkan Nama Desa per baris dengan dropdown dari sheet "Daftar Desa"
  • Import file multi-desa (nama desa berbeda per baris) → ringkasan sukses
  • Baris dengan Nama Desa kosong / tidak dikenal / ganda ditolak dengan pesan jelas
  • Import duplikat di desa yang sama ditolak; nama sama di desa berbeda diizinkan
  • Tambah/Edit/Hapus manual via API
  • Filter Kabupaten→Kecamatan→Desa (tombol Tampilkan/Reset)
  • Hapus massal mengirim satu request DELETE /api/v1/plan/?ids[]=...
  • Validasi koordinat di luar wilayah Indonesia ditolak
  • Regression Testing - test existing features are not broken

Automated Testing

  • Feature/Peta/LokasiImportTest — template export, parser, mapping nama desa, payload batch, insert-only, detail & update, bulk delete, render halaman (21 tes)
  • Browser Smoke — SmokeLokasiTest, SmokeLokasiImportTest

Screenshots / Video

simplescreenrecorder-2026-10-12_10.10.58.mp4

Breaking Changes

Perubahan kontrak API database gabungan (perlu koordinasi dengan pemilik API):

  1. POST /api/v1/plan/import menerima payload batch { data: [ { config_id, nama, desk, lat, lng, ref_point } ] } (config_id/ref_point integer; desk = keterangan). Tidak lagi memakai kode_desa/nama_desa/jenis/kategori/sumber di level batch.
  2. DELETE /api/v1/plan/ (bulk) menerima query string array ids[].
  3. PUT /api/v1/plan/update/{id} memakai item plan { config_id, nama, desk, lat, lng, ref_point }.
  4. GET /api/v1/plan disarankan mengembalikan nama_desa per baris untuk kolom "Desa".

Migration Guide

Tidak diperlukan migrasi database lokal (data lokasi disimpan di API database gabungan). Perlu pembaruan/peluncuran endpoint API di sisi database gabungan sebelum fitur dipakai di produksi.


Additional notes: Fitur bergantung pada kesiapan endpoint API database gabungan (plan/import, plan/store, plan/update, plan/ bulk delete, dan nama_desa pada GET /plan). Mohon konfirmasi kontrak API sebelum merge/rilis.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI PR Review sedang antri di server...

Proses review akan segera dimulai di background — hasil akan muncul sebagai komentar setelah selesai.
Powered by CrewAI · PR #1302

@pandigresik pandigresik changed the title Import lokasi Feat: Import dan Pengelolaan Data Lokasi (Tipe Lokasi) Multi-Desa via API Database Gabungan Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant