diff --git a/README.md b/README.md
index efff123..eb21adb 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Dokumentasi Fungsional: WebGIS Miskin & Ibadah
+# Dokumentasi Fungsional: WebGIS Pemetaan Kemiskinan
Proyek ini adalah sistem informasi geografis (WebGIS) berbasis web yang dirancang untuk memetakan sebaran rumah ibadah dan keluarga kurang mampu (miskin). Sistem ini memungkinkan pengguna untuk melakukan analisis spasial berdasarkan radius untuk mengetahui dampak atau jangkauan layanan rumah ibadah terhadap komunitas di sekitarnya.
@@ -20,8 +20,10 @@ Menggunakan library **Leaflet.js**, sistem menyediakan antarmuka peta yang respo
### 2. Manajemen Data (CRUD)
Sistem mendukung pengelolaan data secara penuh:
- **Tambah Data via Peta**: Klik pada lokasi di peta untuk memunculkan formulir input data baru.
+- **Edit Data via Form**: Klik tombol "Edit" pada popup marker di peta atau pada baris di tabel data untuk membuka formulir edit. Mendukung pembaruan semua field teks untuk Rumah Ibadah (nama, jenis, pengurus, telepon, jemaah, radius, keterangan) dan Keluarga Miskin (nama KK, jumlah jiwa, pekerjaan, pendapatan, kondisi, keterangan).
- **Update Lokasi (Drag & Drop)**: Marker dapat digeser (drag) untuk memperbarui koordinat lokasi di database secara real-time.
- **Hapus Data**: Menghapus data melalui popup pada marker atau melalui tabel data.
+- **Ownership Rumah Ibadah**: Pengurus Rumah Ibadah hanya dapat mengubah atau menghapus data rumah ibadah yang mereka tambahkan sendiri. Administrator dapat mengubah semua data.
- **Data Tabular**: Halaman khusus yang menampilkan seluruh data dalam bentuk tabel dengan statistik ringkasan.
### 3. Analisis Spasial Radius
@@ -33,9 +35,9 @@ Fitur unggulan untuk menganalisis sebaran keluarga miskin di sekitar rumah ibada
## Arsitektur Teknis
-Proyek ini telah dimigrasikan ke framework **Laravel 11** dengan struktur sebagai berikut:
+Proyek ini telah dimigrasikan ke framework **Laravel 13** dengan struktur sebagai berikut:
-- **Backend**:
+- **Backend**:
- **Laravel Eloquent**: Digunakan untuk interaksi database yang aman dan efisien.
- **RESTful API**: Menyediakan endpoint `/api/ibadah` dan `/api/miskin` untuk komunikasi frontend-backend.
- **Migrations**: Skema database yang terstruktur dan mudah dikelola.
@@ -45,6 +47,87 @@ Proyek ini telah dimigrasikan ke framework **Laravel 11** dengan struktur sebaga
- **JavaScript (Vanilla)**: Menangani logika peta dan interaksi API tanpa beban framework berat.
- **Database**: MySQL/MariaDB untuk penyimpanan data spasial dan atribut.
+## Cara Menjalankan Project
+
+Cara utama untuk menjalankan project ini adalah menggunakan **Docker Compose**. Setup Docker sudah mencakup Laravel app, Vite dev server, dan MySQL.
+
+### Prasyarat
+
+- Docker Desktop sudah terinstall dan berjalan.
+- Port `8000`, `5173`, dan `3307` sedang tidak dipakai aplikasi lain.
+
+### Menjalankan dengan Docker
+
+Jalankan perintah berikut dari root project:
+
+```powershell
+docker compose up -d --build
+```
+
+Container `app` akan otomatis:
+
+- menginstall dependency Composer jika `vendor` belum ada di volume Docker,
+- membuat file `.env` dari `.env.docker.example` jika `.env` belum ada,
+- generate `APP_KEY` jika masih kosong,
+- membersihkan config cache,
+- menjalankan migration ke database MySQL.
+
+Container `vite` akan otomatis menginstall dependency Node jika `node_modules` belum ada di volume Docker, lalu menjalankan Vite dev server.
+
+Setelah container berjalan, buka:
+
+- Aplikasi: `http://localhost:8000`
+- Vite dev server: `http://localhost:5173`
+- MySQL dari host: `127.0.0.1:3307`
+- MySQL dari container Laravel: `mysql:3306`
+
+### Konfigurasi Database
+
+Konfigurasi database development menggunakan MySQL:
+
+```env
+DB_CONNECTION=mysql
+DB_HOST=mysql
+DB_PORT=3306
+DB_DATABASE=webgis_miskin
+DB_USERNAME=webgis
+DB_PASSWORD=secret
+```
+
+Credential MySQL root:
+
+```text
+MYSQL_ROOT_PASSWORD=root
+```
+
+### Perintah yang Sering Dipakai
+
+```powershell
+docker compose ps
+docker compose logs -f app
+docker compose logs -f vite
+docker compose exec app php artisan migrate:status
+docker compose exec app php artisan migrate
+docker compose exec app php artisan test
+docker compose down
+```
+
+Untuk menghapus database MySQL Docker dan mulai dari database kosong:
+
+```powershell
+docker compose down -v
+```
+
+### Menjalankan Artisan di Docker
+
+Semua perintah Artisan dijalankan lewat service `app`.
+
+```powershell
+docker compose exec app php artisan route:list
+docker compose exec app php artisan migrate:fresh
+docker compose exec app php artisan cache:clear
+```
+
## Daftar Halaman
1. **Beranda (`/`)**: Halaman landing dengan latar belakang peta animasi dan navigasi cepat.
@@ -52,4 +135,4 @@ Proyek ini telah dimigrasikan ke framework **Laravel 11** dengan struktur sebaga
3. **Data Tabular (`/data`)**: Manajemen data dalam format tabel dengan ringkasan statistik total.
---
-*Dokumentasi ini dibuat untuk menjelaskan kapabilitas sistem WebGIS Miskin & Ibadah versi Laravel.*
+*Dokumentasi ini dibuat untuk menjelaskan kapabilitas sistem WebGIS Pemetaan Kemiskinan versi Laravel.*
diff --git a/app/Http/Controllers/IbadahController.php b/app/Http/Controllers/IbadahController.php
index 290b487..141dc28 100644
--- a/app/Http/Controllers/IbadahController.php
+++ b/app/Http/Controllers/IbadahController.php
@@ -16,12 +16,18 @@ class IbadahController extends Controller
{
$validated = $request->validate([
'nama' => 'required|string',
- 'alamat' => 'required|string',
+ 'jenis' => 'nullable|string',
+ 'alamat' => 'nullable|string',
'latitude' => 'required|numeric',
'longitude' => 'required|numeric',
'radius' => 'nullable|integer',
+ 'jumlah_jemaah' => 'nullable|integer',
+ 'pengurus' => 'nullable|string',
+ 'telepon' => 'nullable|string',
+ 'keterangan' => 'nullable|string',
]);
+ $validated['user_id'] = auth()->id();
$ibadah = RumahIbadah::create($validated);
return response()->json(['success' => true, 'data' => $ibadah]);
}
@@ -29,12 +35,22 @@ class IbadahController extends Controller
public function update(Request $request, $id)
{
$ibadah = RumahIbadah::findOrFail($id);
+
+ if (!auth()->user()->hasRole('administrator') && $ibadah->user_id !== auth()->id()) {
+ return response()->json(['message' => 'Tidak diizinkan mengubah data ini.'], 403);
+ }
+
$validated = $request->validate([
'nama' => 'required|string',
- 'alamat' => 'required|string',
+ 'jenis' => 'nullable|string',
+ 'alamat' => 'nullable|string',
'latitude' => 'required|numeric',
'longitude' => 'required|numeric',
'radius' => 'required|integer',
+ 'jumlah_jemaah' => 'nullable|integer',
+ 'pengurus' => 'nullable|string',
+ 'telepon' => 'nullable|string',
+ 'keterangan' => 'nullable|string',
]);
$ibadah->update($validated);
@@ -44,6 +60,11 @@ class IbadahController extends Controller
public function destroy($id)
{
$ibadah = RumahIbadah::findOrFail($id);
+
+ if (!auth()->user()->hasRole('administrator') && $ibadah->user_id !== auth()->id()) {
+ return response()->json(['message' => 'Tidak diizinkan menghapus data ini.'], 403);
+ }
+
$ibadah->delete();
return response()->json(['success' => true]);
}
diff --git a/app/Models/RumahIbadah.php b/app/Models/RumahIbadah.php
index 8510613..b913788 100644
--- a/app/Models/RumahIbadah.php
+++ b/app/Models/RumahIbadah.php
@@ -11,5 +11,10 @@ class RumahIbadah extends Model
use HasFactory;
protected $table = 'rumah_ibadah';
- protected $fillable = ['nama', 'alamat', 'latitude', 'longitude', 'radius'];
+ protected $fillable = ['user_id', 'nama', 'jenis', 'alamat', 'latitude', 'longitude', 'radius', 'jumlah_jemaah', 'pengurus', 'telepon', 'keterangan'];
+
+ public function user()
+ {
+ return $this->belongsTo(\App\Models\User::class);
+ }
}
diff --git a/app/Models/User.php b/app/Models/User.php
index 680037c..94a9432 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -2,13 +2,14 @@
namespace App\Models;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
- use HasRoles, Notifiable;
+ use HasFactory, HasRoles, Notifiable;
protected $fillable = ['name', 'email', 'password'];
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index c4ceb07..675af45 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -27,7 +27,6 @@ class UserFactory extends Factory
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
- 'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
];
@@ -38,8 +37,6 @@ class UserFactory extends Factory
*/
public function unverified(): static
{
- return $this->state(fn (array $attributes) => [
- 'email_verified_at' => null,
- ]);
+ return $this->state(fn (array $attributes) => []);
}
}
diff --git a/database/migrations/2026_06_02_add_user_id_to_rumah_ibadah_table.php b/database/migrations/2026_06_02_add_user_id_to_rumah_ibadah_table.php
new file mode 100644
index 0000000..e932bc3
--- /dev/null
+++ b/database/migrations/2026_06_02_add_user_id_to_rumah_ibadah_table.php
@@ -0,0 +1,22 @@
+foreignId('user_id')->nullable()->constrained('users')->nullOnDelete()->after('id');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('rumah_ibadah', function (Blueprint $table) {
+ $table->dropForeignIfExists(['user_id']);
+ $table->dropColumn('user_id');
+ });
+ }
+};
diff --git a/missing_features.md b/missing_features.md
index 73e5662..6260c7e 100644
--- a/missing_features.md
+++ b/missing_features.md
@@ -2,7 +2,7 @@
> Berdasarkan perbandingan dokumen SKPL (`D1041231009_RadityaIndraPutranto_SKPL_SIG.docx`) dengan implementasi aktual project.
>
-> **Terakhir diperbarui:** 2026-06-02 — setelah implementasi Auth & RBAC (Plan 1).
+> **Terakhir diperbarui:** 2026-06-02 — setelah implementasi Form Edit & Ownership (Plan 2).
---
@@ -28,7 +28,7 @@
### 1.3 Gap ownership yang ditemukan saat implementasi:
-- [ ] **Ownership Rumah Ibadah** — `pengurus_ibadah` seharusnya hanya bisa edit/hapus data ibadah miliknya sendiri. Saat ini bisa edit/hapus **semua** ibadah. Butuh kolom `user_id` di tabel `rumah_ibadah` + policy/gate untuk enforce ownership.
+- [x] **Ownership Rumah Ibadah** — `pengurus_ibadah` seharusnya hanya bisa edit/hapus data ibadah miliknya sendiri. Saat ini bisa edit/hapus **semua** ibadah. Butuh kolom `user_id` di tabel `rumah_ibadah` + policy/gate untuk enforce ownership.
---
@@ -53,8 +53,8 @@ Data bisa ditambah dan dihapus. Untuk lokasi: drag marker (ibadah & miskin) dan
| Fitur | Role terkait | Status |
|---|---|---|
-| **Form Edit Rumah Ibadah** — Edit nama, jenis, pengurus, telepon, jemaah, keterangan | I-06, A-02 | ❌ Belum ada |
-| **Form Edit Keluarga Miskin** — Edit nama KK, jumlah jiwa, pekerjaan, pendapatan, kondisi | P-02, A-02 | ❌ Belum ada |
+| **Form Edit Rumah Ibadah** — Edit nama, jenis, pengurus, telepon, jemaah, keterangan | I-06, A-02 | ✅ Selesai |
+| **Form Edit Keluarga Miskin** — Edit nama KK, jumlah jiwa, pekerjaan, pendapatan, kondisi | P-02, A-02 | ✅ Selesai |
---
@@ -84,12 +84,12 @@ Data bisa ditambah dan dihapus. Untuk lokasi: drag marker (ibadah & miskin) dan
|---|---|---|
| Autentikasi & RBAC | ✅ 6/6 komponen | — |
| Role Pengguna | ✅ 4/4 role | — |
-| Ownership pengurus_ibadah | — | ❌ 1 item baru |
+| Ownership pengurus_ibadah | ✅ 1/1 | — |
| Fitur Admin | — | ❌ 8 fitur |
-| Fitur Edit Data | — | ❌ 2 fitur |
+| Fitur Edit Data | ✅ 2/2 | — |
| Fitur Analisis/Dashboard | — | ❌ 3 fitur |
| Fitur Cetak/Ekspor | — | ❌ 3 fitur |
-| **Total sisa** | | **~17 item** |
+| **Total sisa** | | **~14 item** |
---
@@ -98,7 +98,7 @@ Data bisa ditambah dan dihapus. Untuk lokasi: drag marker (ibadah & miskin) dan
| Plan | Isi | Prioritas |
|---|---|---|
| ~~Plan 1~~ | ~~Auth & RBAC~~ | ✅ Selesai |
-| Plan 2 | Form Edit Rumah Ibadah & Keluarga Miskin + Ownership | Tinggi |
+| ~~Plan 2~~ | ~~Form Edit Rumah Ibadah & Keluarga Miskin + Ownership~~ | ✅ Selesai |
| Plan 3 | Manajemen Pengguna (Admin: CRUD user, assign role) | Tinggi |
| Plan 4 | Dashboard Statistik + Gap Analysis (Pemangku Kebijakan) | Sedang |
| Plan 5 | Ekspor PDF + Ekspor per Radius + Cetak Laporan | Sedang |
diff --git a/resources/views/data.blade.php b/resources/views/data.blade.php
index 516c8c9..9018fe4 100644
--- a/resources/views/data.blade.php
+++ b/resources/views/data.blade.php
@@ -157,6 +157,120 @@
+
+
+
+
+
+