From 3f5cda690eacb6ecab946ee3d7ea1fafbb46fc9d Mon Sep 17 00:00:00 2001 From: Ahmad Afandi Date: Fri, 17 Apr 2026 14:31:30 +0700 Subject: [PATCH 1/6] fix: clear cache setelah hapus --- .../Master/ArtikelKabupatenController.php | 21 +++----- app/Services/ArtikelService.php | 52 ++++++++++++++----- .../views/master/artikel/index.blade.php | 5 +- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/app/Http/Controllers/Master/ArtikelKabupatenController.php b/app/Http/Controllers/Master/ArtikelKabupatenController.php index c32eea6bd..0e4cc9ce8 100644 --- a/app/Http/Controllers/Master/ArtikelKabupatenController.php +++ b/app/Http/Controllers/Master/ArtikelKabupatenController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers\Master; use App\Http\Controllers\Controller; +use App\Services\ArtikelService; +use Illuminate\Http\Request; use Illuminate\View\View; class ArtikelKabupatenController extends Controller @@ -11,15 +13,14 @@ class ArtikelKabupatenController extends Controller /** * Display a listing of the resource. - * - * @return \Illuminate\Http\Response */ - public function index() + public function index(Request $request): View { $listPermission = $this->generateListPermission(); - $clearCache = request('clear_cache', false); - if ($clearCache) { - (new \App\Services\ArtikelService)->clearCache('artikel', ['filter[id]' => $clearCache]); + $clearCache = $request->query('clear_cache', 0); + + if ($clearCache > 0) { + (new ArtikelService)->clearCacheSingle((int) $clearCache); } return view('master.artikel.index')->with($listPermission); @@ -27,8 +28,6 @@ public function index() /** * Show the form for creating a new resource. - * - * @return \Illuminate\Http\Response */ public function create(): View { @@ -37,12 +36,8 @@ public function create(): View /** * Show the form for editing the specified resource. - * - * @param int $id - * - * @return \Illuminate\Http\Response */ - public function edit($id): View + public function edit(int $id): View { return view('master.artikel.edit', compact('id')); } diff --git a/app/Services/ArtikelService.php b/app/Services/ArtikelService.php index 618ea0c0a..b8c10c96c 100644 --- a/app/Services/ArtikelService.php +++ b/app/Services/ArtikelService.php @@ -2,31 +2,42 @@ namespace App\Services; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; +use stdClass; class ArtikelService extends BaseApiService { protected int $cacheTtl = 3600; // TTL dalam detik (1 jam) - public function artikel(array $filters = []) + private string $cacheSingleArtikel = 'artikel_'; + + /** + * Mendapatkan daftar artikel dengan filter opsional + * + * @param array $filters + */ + public function artikel(array $filters = []): Collection { $cacheKey = $this->buildCacheKey('artikel', $filters); // Ambil dari cache dulu - return Cache::remember($cacheKey, $this->cacheTtl, function () use ($filters) { + return Cache::remember($cacheKey, $this->cacheTtl, function () use ($filters): Collection { $data = $this->apiRequest('/api/v1/artikel/list', $filters); - if (!$data) { + + if (empty($data)) { return collect([]); } - return collect($data)->map(function ($item) { - // Return 'attributes' but with 'id' populated + + return collect($data)->map(function (array $item): stdClass { + // Return 'attributes' but with 'id' populated $attributes = $item['attributes'] ?? []; $attributes['id'] = $item['id'] ?? null; // Fetch detail to enrich with gambar and isi if missing - if (isset($attributes['id']) && (!isset($attributes['gambar']) || !isset($attributes['isi']))) { - $detail = $this->artikelById($attributes['id']); - if ($detail) { + if (isset($attributes['id']) && (! isset($attributes['gambar']) || ! isset($attributes['isi']))) { + $detail = $this->artikelById((int) $attributes['id']); + if ($detail !== null) { $attributes['gambar'] = $detail->gambar ?? null; $attributes['isi'] = $detail->isi ?? null; } @@ -37,11 +48,14 @@ public function artikel(array $filters = []) }); } - public function artikelById(int $id) + /** + * Mendapatkan detail artikel berdasarkan ID + */ + public function artikelById(int $id): ?stdClass { - $cacheKey = "artikel_$id"; + $cacheKey = $this->cacheSingleArtikel.$id; - return Cache::remember($cacheKey, $this->cacheTtl, function () use ($id) { + return Cache::remember($cacheKey, $this->cacheTtl, function () use ($id): ?stdClass { $data = $this->apiRequest('/api/v1/artikel/tampil', [ 'id' => $id, ]); @@ -54,9 +68,23 @@ public function artikelById(int $id) }); } - public function clearCache(string $prefix = 'artikel', array $filters = []) + /** + * Menghapus cache artikel berdasarkan prefix dan filter + * + * @param array $filters + */ + public function clearCache(string $prefix = 'artikel', array $filters = []): void { $cacheKey = $this->buildCacheKey($prefix, $filters); Cache::forget($cacheKey); } + + /** + * Menghapus cache artikel tunggal berdasarkan ID + */ + public function clearCacheSingle(int $id): void + { + $cacheKey = $this->cacheSingleArtikel.$id; + Cache::forget($cacheKey); + } } diff --git a/resources/views/master/artikel/index.blade.php b/resources/views/master/artikel/index.blade.php index 1b94b5991..48dcd50ae 100644 --- a/resources/views/master/artikel/index.blade.php +++ b/resources/views/master/artikel/index.blade.php @@ -175,7 +175,10 @@ className: 'text-center', showConfirmButton: true, timer: 1500 }) - table.ajax.reload(null, false); + setTimeout(() => { + window.location.href = + '{{ route('master-data-artikel.index') }}?clear_cache=' +id; + }, 1500); } else { Swal.fire({ title: 'Error!', From 9471c258dcc69ae8b6bdc799594aa2c53ce86c36 Mon Sep 17 00:00:00 2001 From: Ahmad Afandi Date: Fri, 17 Apr 2026 14:31:30 +0700 Subject: [PATCH 2/6] fix: clear cache setelah hapus --- .../Master/ArtikelKabupatenController.php | 24 +++--- app/Services/ArtikelService.php | 81 +++++++++++++++---- .../views/master/artikel/create.blade.php | 2 +- resources/views/master/artikel/edit.blade.php | 3 +- .../views/master/artikel/index.blade.php | 5 +- 5 files changed, 83 insertions(+), 32 deletions(-) diff --git a/app/Http/Controllers/Master/ArtikelKabupatenController.php b/app/Http/Controllers/Master/ArtikelKabupatenController.php index c32eea6bd..eca384075 100644 --- a/app/Http/Controllers/Master/ArtikelKabupatenController.php +++ b/app/Http/Controllers/Master/ArtikelKabupatenController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers\Master; use App\Http\Controllers\Controller; +use App\Services\ArtikelService; +use Illuminate\Http\Request; use Illuminate\View\View; class ArtikelKabupatenController extends Controller @@ -11,15 +13,15 @@ class ArtikelKabupatenController extends Controller /** * Display a listing of the resource. - * - * @return \Illuminate\Http\Response */ - public function index() + public function index(Request $request): View { - $listPermission = $this->generateListPermission(); - $clearCache = request('clear_cache', false); - if ($clearCache) { - (new \App\Services\ArtikelService)->clearCache('artikel', ['filter[id]' => $clearCache]); + $listPermission = $this->generateListPermission(); + $clearAllCache = $request->query('clear_all_cache', 0); + + if ($clearAllCache > 0) { + // setiap ada perubahan di clear cache semua, termasuk ketika edit karena bisa jadi edit judul saja + (new ArtikelService)->clearAllCache(); } return view('master.artikel.index')->with($listPermission); @@ -27,8 +29,6 @@ public function index() /** * Show the form for creating a new resource. - * - * @return \Illuminate\Http\Response */ public function create(): View { @@ -37,12 +37,8 @@ public function create(): View /** * Show the form for editing the specified resource. - * - * @param int $id - * - * @return \Illuminate\Http\Response */ - public function edit($id): View + public function edit(int $id): View { return view('master.artikel.edit', compact('id')); } diff --git a/app/Services/ArtikelService.php b/app/Services/ArtikelService.php index 618ea0c0a..5a1bb6375 100644 --- a/app/Services/ArtikelService.php +++ b/app/Services/ArtikelService.php @@ -2,31 +2,57 @@ namespace App\Services; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; +use stdClass; class ArtikelService extends BaseApiService { protected int $cacheTtl = 3600; // TTL dalam detik (1 jam) - public function artikel(array $filters = []) + private string $cacheSingleArtikel = 'artikel_'; + + private string $cacheRegistryKey = 'artikel_cache_registry'; + + /** + * Daftarkan cache key ke registry setiap kali generate + */ + private function registerCacheKey(string $key): void + { + $keys = Cache::get($this->cacheRegistryKey, []); + $keys[$key] = time(); + Cache::forever($this->cacheRegistryKey, $keys); + } + + /** + * Mendapatkan daftar artikel dengan filter opsional + * + * @param array $filters + */ + public function artikel(array $filters = []): Collection { $cacheKey = $this->buildCacheKey('artikel', $filters); + // ✅ Daftarkan key setiap kali generate + $this->registerCacheKey($cacheKey); + // Ambil dari cache dulu - return Cache::remember($cacheKey, $this->cacheTtl, function () use ($filters) { + return Cache::remember($cacheKey, $this->cacheTtl, function () use ($filters): Collection { $data = $this->apiRequest('/api/v1/artikel/list', $filters); - if (!$data) { + + if (empty($data)) { return collect([]); } - return collect($data)->map(function ($item) { - // Return 'attributes' but with 'id' populated + + return collect($data)->map(function (array $item): stdClass { + // Return 'attributes' but with 'id' populated $attributes = $item['attributes'] ?? []; $attributes['id'] = $item['id'] ?? null; // Fetch detail to enrich with gambar and isi if missing - if (isset($attributes['id']) && (!isset($attributes['gambar']) || !isset($attributes['isi']))) { - $detail = $this->artikelById($attributes['id']); - if ($detail) { + if (isset($attributes['id']) && (! isset($attributes['gambar']) || ! isset($attributes['isi']))) { + $detail = $this->artikelById((int) $attributes['id']); + if ($detail !== null) { $attributes['gambar'] = $detail->gambar ?? null; $attributes['isi'] = $detail->isi ?? null; } @@ -37,11 +63,17 @@ public function artikel(array $filters = []) }); } - public function artikelById(int $id) + /** + * Mendapatkan detail artikel berdasarkan ID + */ + public function artikelById(int $id): ?stdClass { - $cacheKey = "artikel_$id"; + $cacheKey = $this->cacheSingleArtikel.$id; - return Cache::remember($cacheKey, $this->cacheTtl, function () use ($id) { + // ✅ Daftarkan key setiap kali generate + $this->registerCacheKey($cacheKey); + + return Cache::remember($cacheKey, $this->cacheTtl, function () use ($id): ?stdClass { $data = $this->apiRequest('/api/v1/artikel/tampil', [ 'id' => $id, ]); @@ -53,10 +85,31 @@ public function artikelById(int $id) return null; }); } - - public function clearCache(string $prefix = 'artikel', array $filters = []) + + /** + * Menghapus cache artikel tunggal berdasarkan ID + */ + public function clearCacheSingle(int $id): void { - $cacheKey = $this->buildCacheKey($prefix, $filters); + $cacheKey = $this->cacheSingleArtikel.$id; Cache::forget($cacheKey); } + + /** + * ✅ HAPUS SEMUA CACHE ARTIKEL 100% BERFUNGSI DI SEMUA DRIVER! + * Termasuk semua cache list dengan hash MD5 apapun + */ + public function clearAllCache(): void + { + // Ambil semua key yang pernah terdaftar + $keys = Cache::get($this->cacheRegistryKey, []); + + // Hapus SATU PERSATU SEMUA CACHE YANG PERNAH ADA! + foreach (array_keys($keys) as $key) { + Cache::forget($key); + } + + // Reset registry + Cache::forget($this->cacheRegistryKey); + } } diff --git a/resources/views/master/artikel/create.blade.php b/resources/views/master/artikel/create.blade.php index 33072b387..2068eddb2 100644 --- a/resources/views/master/artikel/create.blade.php +++ b/resources/views/master/artikel/create.blade.php @@ -302,7 +302,7 @@ function artikel() { }); setTimeout(() => { window.location.href = - '{{ route('master-data-artikel.index') }}'; + '{{ route('master-data-artikel.index') }}?clear_all_cache=1'; }, 1500); } else { Swal.fire({ diff --git a/resources/views/master/artikel/edit.blade.php b/resources/views/master/artikel/edit.blade.php index 2fa7503ab..0082b9992 100644 --- a/resources/views/master/artikel/edit.blade.php +++ b/resources/views/master/artikel/edit.blade.php @@ -362,8 +362,7 @@ function artikel() { }); setTimeout(() => { window.location.href = - '{{ route('master-data-artikel.index') }}?clear_cache=' + - artikelId; + '{{ route('master-data-artikel.index') }}?clear_all_cache=1'; }, 1500); } else { Swal.fire({ diff --git a/resources/views/master/artikel/index.blade.php b/resources/views/master/artikel/index.blade.php index 1b94b5991..655be2f13 100644 --- a/resources/views/master/artikel/index.blade.php +++ b/resources/views/master/artikel/index.blade.php @@ -175,7 +175,10 @@ className: 'text-center', showConfirmButton: true, timer: 1500 }) - table.ajax.reload(null, false); + setTimeout(() => { + window.location.href = + '{{ route('master-data-artikel.index') }}?clear_all_cache=1'; + }, 1500); } else { Swal.fire({ title: 'Error!', From c0281e3e684b1bcbea924fc22218baa64a488c33 Mon Sep 17 00:00:00 2001 From: Ahmad Afandi Date: Fri, 17 Apr 2026 16:27:50 +0700 Subject: [PATCH 3/6] hapus --- docs/pr#369.md | 137 ------------------------------------------------- 1 file changed, 137 deletions(-) delete mode 100644 docs/pr#369.md diff --git a/docs/pr#369.md b/docs/pr#369.md deleted file mode 100644 index 2c1c19537..000000000 --- a/docs/pr#369.md +++ /dev/null @@ -1,137 +0,0 @@ -# Pull Request: Fix: Cache artikel tidak terupdate setelah create/edit/delete - -## Deskripsi - -Perbaikan bug pada sistem cache artikel yang tidak terupdate secara otomatis setelah melakukan operasi create, edit, atau delete artikel. Masalah ini menyebabkan user masih melihat data artikel lama meskipun sudah melakukan perubahan. - -Solusi yang diterapkan menggunakan sistem cache registry yang mencatat semua cache key yang pernah dibuat, sehingga memungkinkan untuk menghapus SEMUA cache artikel dengan 100% akurat dan kompatibel dengan semua cache driver Laravel. - ---- - -### Perubahan yang dilakukan: - -1. **Refactor Service**: `app/Services/ArtikelService.php` - - Menambahkan sistem `cache registry` untuk mencatat semua cache key yang pernah digenerate - - Menambahkan method `registerCacheKey()` untuk otomatis mendaftarkan setiap cache key yang dibuat - - Menambahkan method `clearAllCache()` untuk menghapus SEMUA cache artikel sekaligus - - Menambahkan method `clearCacheSingle()` untuk menghapus cache artikel tunggal berdasarkan ID - - Semua pemanggilan `artikel()` dan `artikelById()` sekarang otomatis mendaftarkan cache key ke registry - -2. **Controller Update**: `app/Http/Controllers/Master/ArtikelKabupatenController.php` - - Mengganti logic `clear_cache` yang lama dengan `clear_all_cache` - - Setiap ada permintaan clear cache, sekarang memanggil `clearAllCache()` bukan hanya menghapus 1 cache key - - Perbaikan type hinting dan code styling sesuai standar - -3. **View Create**: `resources/views/master/artikel/create.blade.php` - - Setelah berhasil create artikel, redirect dengan parameter `?clear_all_cache=1` - -4. **View Edit**: `resources/views/master/artikel/edit.blade.php` - - Setelah berhasil edit artikel, redirect dengan parameter `?clear_all_cache=1` - - Menghapus logic lama yang hanya menghapus cache artikel yang sedang di-edit - -5. **View Index**: `resources/views/master/artikel/index.blade.php` - - Setelah berhasil delete artikel, redirect dengan parameter `?clear_all_cache=1` - - Mengganti `table.ajax.reload()` dengan full page refresh untuk memastikan cache benar-benar terhapus - ---- - -### Alasan perubahan: - -- **Masalah Utama**: Sistem cache sebelumnya menggunakan MD5 hash dari filter sebagai cache key. Tidak ada cara untuk menghapus semua cache artikel karena tidak mungkin mengetahui semua kemungkinan kombinasi filter yang pernah user gunakan. -- **Limitasi Laravel**: Method `Cache::tags()` tidak didukung oleh semua driver cache (khususnya `file` dan `database` driver yang umum digunakan di shared hosting). -- **Masalah Sebelumnya**: Ketika user mengedit artikel, hanya cache detail artikel yang dihapus. Cache list artikel di berbagai halaman (dengan filter yang berbeda) tetap menampilkan data lama sampai TTL 1 jam habis. -- **Solusi Registry**: Dengan mencatat setiap cache key yang pernah dibuat ke dalam registry, kita bisa dengan aman menghapus SEMUA cache artikel kapanpun tanpa perlu tahu key-nya satu per satu. - ---- - -### Dampak perubahan: - -✅ **Cache Selalu Fresh**: Setiap create/edit/delete artikel, SEMUA cache artikel di seluruh halaman akan dihapus sekaligus -✅ **Kompatibel Semua Driver**: Bekerja 100% di semua cache driver Laravel (file, database, redis, memcached, dll) -✅ **Tidak Ada Breaking Change**: Tidak merubah API atau output dari `ArtikelService`, hanya menambahkan fitur cache clearing -✅ **Backward Compatible**: Code lama yang menggunakan `ArtikelService` tetap berfungsi normal tanpa perubahan - ---- - -## Masalah Terkait (Related Issue) - -- Solusi untuk perbaikan terkait issue #369 -- 🔗 https://github.com/OpenSID/API-Database-Gabungan/issues/369 - ---- - -## Langkah untuk mereproduksi (Steps to Reproduce) - -### Sebelum perbaikan (masalah): -1. Buka halaman daftar artikel -2. Edit salah satu artikel (ubah judul atau isi) -3. Kembali ke halaman daftar artikel -4. Lakukan refresh halaman berkali-kali -5. ❌ Artikel masih menampilkan judul/isi yang LAMA (sampai 1 jam) - -### Setelah perbaikan (fix): -1. Buka halaman daftar artikel -2. Edit salah satu artikel (ubah judul atau isi) -3. Simpan perubahan -4. Kembali ke halaman daftar artikel -5. ✅ Artikel langsung menampilkan data TERBARU - ---- - -## Daftar Periksa (Checklist) - -### Testing Checklist: -- [ ] Test create artikel baru → cache terhapus otomatis -- [ ] Test edit artikel yang sudah ada → cache terhapus otomatis -- [ ] Test delete artikel → cache terhapus otomatis -- [ ] Test dengan berbagai filter artikel (cari, paginasi, urutkan) → semua ter-update -- [ ] Test cache detail artikel → ter-update setelah edit -- [ ] Regression Testing: Fitur artikel lama tidak rusak -- [ ] Tidak ada error di console / storage/logs - -### Code Checklist: -- [ ] Saya telah mematuhi aturan penulisan script -- [ ] Code sudah diformat sesuai standar project -- [ ] Tidak ada breaking changes -- [ ] Semua fitur yang ada tetap berfungsi normal - ---- - -## Teknis Detail - -### Penjelasan Teknis Sistem Cache Registry: - -```php -// Setiap kali cache dibuat, key-nya dicatat ke registry -private function registerCacheKey(string $key): void -{ - $keys = Cache::get($this->cacheRegistryKey, []); - $keys[$key] = time(); - Cache::forever($this->cacheRegistryKey, $keys); -} - -// Saat perlu clear semua cache, tinggal loop semua key yang terdaftar -public function clearAllCache(): void -{ - $keys = Cache::get($this->cacheRegistryKey, []); - - foreach (array_keys($keys) as $key) { - Cache::forget($key); - } - - Cache::forget($this->cacheRegistryKey); -} -``` - -### Dependencies yang ditambahkan: -- Tidak ada dependencies baru - ---- - -## Breaking Changes -Tidak ada breaking changes. Semua method dan interface `ArtikelService` tetap sama seperti sebelumnya. - ---- - -## Migration Guide -Tidak diperlukan migration. Perubahan ini bekerja otomatis tanpa perlu konfigurasi tambahan. From aee9263e2f23e5b80d893cefbd9978fbc6b760f1 Mon Sep 17 00:00:00 2001 From: Ahmad Afandi Date: Fri, 17 Apr 2026 16:44:01 +0700 Subject: [PATCH 4/6] perbaiki test sesuai rekomendasi AI review --- app/Services/ArtikelService.php | 38 +++++++++++++++++--- tests/Unit/ArtikelServiceTest.php | 58 +++++++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/app/Services/ArtikelService.php b/app/Services/ArtikelService.php index 5a1bb6375..f8ccc2543 100644 --- a/app/Services/ArtikelService.php +++ b/app/Services/ArtikelService.php @@ -20,8 +20,16 @@ class ArtikelService extends BaseApiService private function registerCacheKey(string $key): void { $keys = Cache::get($this->cacheRegistryKey, []); + + // Pastikan selalu array meskipun cache corrupt + if (! is_array($keys)) { + $keys = []; + } + $keys[$key] = time(); - Cache::forever($this->cacheRegistryKey, $keys); + + // Gunakan TTL 7 hari, tidak forever untuk mencegah memory bloat + Cache::put($this->cacheRegistryKey, $keys, now()->addDays(7)); } /** @@ -85,7 +93,7 @@ public function artikelById(int $id): ?stdClass return null; }); } - + /** * Menghapus cache artikel tunggal berdasarkan ID */ @@ -104,9 +112,29 @@ public function clearAllCache(): void // Ambil semua key yang pernah terdaftar $keys = Cache::get($this->cacheRegistryKey, []); - // Hapus SATU PERSATU SEMUA CACHE YANG PERNAH ADA! - foreach (array_keys($keys) as $key) { - Cache::forget($key); + // Validasi tipe data, hindari fatal error jika cache corrupt + if (! is_array($keys)) { + Cache::forget($this->cacheRegistryKey); + + return; + } + + $cacheKeys = array_keys($keys); + + if (empty($cacheKeys)) { + Cache::forget($this->cacheRegistryKey); + + return; + } + + // Laravel 10+ mendukung deleteMultiple untuk batch operation + try { + Cache::deleteMultiple($cacheKeys); + } catch (\BadMethodCallException $e) { + // Fallback untuk driver yang tidak mendukung deleteMultiple + foreach ($cacheKeys as $key) { + Cache::forget($key); + } } // Reset registry diff --git a/tests/Unit/ArtikelServiceTest.php b/tests/Unit/ArtikelServiceTest.php index 9a3a2fb50..532a62145 100644 --- a/tests/Unit/ArtikelServiceTest.php +++ b/tests/Unit/ArtikelServiceTest.php @@ -4,6 +4,8 @@ use App\Services\ArtikelService; use Illuminate\Support\Facades\Cache; +use Mockery; +use ReflectionClass; use Tests\TestCase; class ArtikelServiceTest extends TestCase @@ -30,7 +32,7 @@ public function it_builds_cache_key_correctly() $method->setAccessible(true); $cacheKey = $method->invokeArgs($this->service, ['artikel', ['id' => 1]]); - + $this->assertIsString($cacheKey); $this->assertStringContainsString('artikel', $cacheKey); } @@ -40,11 +42,11 @@ public function clear_cache_removes_cached_data() { $cacheKey = 'test_artikel_cache'; Cache::put($cacheKey, 'test_data', 3600); - + $this->assertTrue(Cache::has($cacheKey)); - + Cache::forget($cacheKey); - + $this->assertFalse(Cache::has($cacheKey)); } @@ -54,9 +56,9 @@ public function it_has_cache_ttl_property() $reflection = new \ReflectionClass($this->service); $property = $reflection->getProperty('cacheTtl'); $property->setAccessible(true); - + $ttl = $property->getValue($this->service); - + $this->assertEquals(3600, $ttl); $this->assertIsInt($ttl); } @@ -87,4 +89,48 @@ public function service_extends_base_api_service() { $this->assertInstanceOf(\App\Services\BaseApiService::class, $this->service); } + + // tests/Unit/Services/ArtikelServiceTest.php + public function test_clear_all_cache_removes_all_registered_keys(): void + { + $registeredKeys = [ + 'artikel_cache_key_1' => time(), + 'artikel_cache_key_2' => time(), + ]; + + Cache::shouldReceive('get') + ->once() + ->with('artikel_cache_registry', []) + ->andReturn($registeredKeys); + + Cache::shouldReceive('forget') + ->once() + ->with('artikel_cache_key_1'); + + Cache::shouldReceive('forget') + ->once() + ->with('artikel_cache_key_2'); + + Cache::shouldReceive('forget') + ->once() + ->with('artikel_cache_registry'); + + $service = new ArtikelService(); + $service->clearAllCache(); + } + + public function test_clear_all_cache_handles_empty_registry(): void + { + Cache::shouldReceive('get') + ->once() + ->with('artikel_cache_registry', []) + ->andReturn([]); + + Cache::shouldReceive('forget') + ->once() + ->with('artikel_cache_registry'); + + $service = new ArtikelService(); + $service->clearAllCache(); + } } From b63a6a9eefb5d9f672ab9db58650a8a31a91995d Mon Sep 17 00:00:00 2001 From: Abah Roland <59082428+vickyrolanda@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:07:09 +0700 Subject: [PATCH 5/6] [ci skip] memutahirkan catatan rilis --- catatan_rilis.md | 1 + 1 file changed, 1 insertion(+) diff --git a/catatan_rilis.md b/catatan_rilis.md index 51bee7f78..10989dee2 100644 --- a/catatan_rilis.md +++ b/catatan_rilis.md @@ -10,6 +10,7 @@ Di rilis ini, versi 2604.0.0 berisi penambahan dan perbaikan yang diminta penggu #### Perbaikan BUG 1. [#954](https://github.com/OpenSID/OpenKab/issues/954) Perbaikan list menu tidak tampil. +2. [#369](https://github.com/OpenSID/API-Database-Gabungan/issues/369) Perbaikan cache artikel tidak dihapus setelah operasi hapus. #### Perubahan Teknis From fc1882ec9fc7221ce8d265160e29fa19831f5a19 Mon Sep 17 00:00:00 2001 From: Abah Roland <59082428+vickyrolanda@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:30:49 +0700 Subject: [PATCH 6/6] hapus template ai --- template_ai/PROMPT_AI_UNTUK_PR.md | 830 ------------------------- template_ai/TEMPLATE_PR_DESCRIPTION.md | 322 ---------- 2 files changed, 1152 deletions(-) delete mode 100644 template_ai/PROMPT_AI_UNTUK_PR.md delete mode 100644 template_ai/TEMPLATE_PR_DESCRIPTION.md diff --git a/template_ai/PROMPT_AI_UNTUK_PR.md b/template_ai/PROMPT_AI_UNTUK_PR.md deleted file mode 100644 index 419f9c1b1..000000000 --- a/template_ai/PROMPT_AI_UNTUK_PR.md +++ /dev/null @@ -1,830 +0,0 @@ -# 🤖 Prompt AI untuk Generate PR Description (Auto-Analyze Code) - -Gunakan salah satu prompt di bawah ini untuk meminta AI analyze code changes dan -auto-generate PR description lengkap - **TANPA perlu input manual file yang diubah!** - ---- - -## 🚀 FASTEST METHOD: Gunakan GitHub MCP untuk Direct Analysis - -**Ini cara TERCEPAT! AI langsung analyze dari GitHub repo tanpa copy-paste manual.** - -``` -Kamu memiliki akses ke GitHub MCP. - -Tolong analyze PR branch saya di OpenSID/Layanan_OpenDESA repository: -- Branch: dev-1094 -- Branch Tujuan: rilis-dev -- Issue: https://github.com/OpenSID/Layanan_OpenDESA/issues/1110 - -Gunakan GitHub MCP untuk: -1. Fetch semua file changes dari branch ke rilis-dev -2. Read semua file yang diubah untuk memahami context -3. Analyze setiap perubahan code -4. Understand the problem being solved -5. Generate complete PR description - -Output format: Use template_ai/TEMPLATE_PR_DESCRIPTION.md dengan section: -- Judul PR yang jelas -- Deskripsi singkat (what & why) -- Perubahan yang dilakukan (dari code analysis) -- Alasan perubahan (dari context) -- Dampak perubahan -- File yang diubah dengan penjelasan detail -- Testing checklist yang di-suggest -- Steps to reproduce (jika applicable) -- Related issue link - -Langsung analyze dari GitHub MCP - jangan tanya-tanya lagi! -Catatan: -- simpan hasil ke docs/pr#nomor-issue.md -``` - -**Keuntungan GitHub MCP:** -- ✅ Langsung akses repo, bukan copy-paste -- ✅ Bisa read actual file content, bukan hanya diff -- ✅ Analyze branch history & commits -- ✅ ~90 detik dari branch ke PR siap pakai -- ✅ Lebih akurat (full context bukan diff summary) - ---- - -## 📋 Backup Method: Auto-Analyze dari Git Diff - -**Jika GitHub MCP tidak tersedia, gunakan cara ini dengan git diff:** - -``` -Tolong analisis code changes dan buatkan PR description untuk Layanan_OpenDESA. - -BRANCH PR: feat/hak_akses_kontak -BRANCH TUJUAN: rilis-dev -ISSUE: https://github.com/OpenSID/Layanan_OpenDESA/issues/1110 - -Lakukan git diff dari BRANCH PR ke BRANCH TUJUAN untuk melihat perubahan, pelajari konteks lebih dalam perbaikan, perubahan, penambahan dll. Contoh: git diff BRANCH TUJUAN...BRANCH PR - -Yang saya minta kamu lakukan: -1. **Analyze setiap file yang berubah** - identifikasi apa yang diubah dan alasannya -2. **Understand the context** - dari code changes, apa masalah yang dipecahkan? -3. **Infer the testing** - suggest testing yang perlu dilakukan berdasarkan changes -4. **Generate complete PR description** menggunakan template_ai/TEMPLATE_PR_DESCRIPTION.md dengan section: - - Deskripsi singkat (what & why) - - Perubahan yang dilakukan (dari analysis diff) - - Alasan perubahan (dari context analysis) - - Dampak perubahan - - Steps to reproduce (jika applicable) - - Testing checklist (based on code changes) - - Related issue link - -Jangan tanya-tanya, langsung analyze dan buatkan PR description yang siap copy-paste! -Catatan: -- simpan hasil ke docs/pr#nomor-issue.md -``` - ---- - -## 📋 Prompt Alternatif: Dengan Branch Checkout - -Jika Anda kasih akses ke local repo, saya bisa direct analyze: - -``` -Saya sedang di branch [nama-branch] di repo OpenSID Laravel 10. -Issue yang saya tackle: #[nomor issue] - -Tolong: -1. Analyze semua file yang saya ubah (bandingkan dengan rilis-dev branch) -2. Pahami apa yang saya ubah dan mengapa -3. Buatkan PR description lengkap secara otomatis -4. Infer testing yang perlu dilakukan - -Jangan perlu saya jelaskan detail, cukup analisis code langsung! -``` - ---- - -## � Cara Mendapatkan Git Diff (Required untuk Prompt) - -### **Windows PowerShell / CMD** - -```powershell -# Get diff vs rilis-dev branch -git diff rilis-dev..HEAD - -# Save ke file (lebih mudah untuk copy) -git diff rilis-dev..HEAD > pr-changes.diff - -# Lihat summary file yang berubah -git diff rilis-dev..HEAD --stat - -# Lihat full diff dengan konteks lebih banyak -git diff -U5 rilis-dev..HEAD -``` - -### **Jika belum push ke remote** - -```bash -# Lihat apa yang di-stage -git diff --cached - -# Lihat apa yang di-working directory -git diff - -# Lihat perbandingan antara 2 commit -git diff -``` - -### **Verify Diff Sebelum Copy ke AI** - -```powershell -# Check branch mana yg active -git branch - -# Check remote -git remote -v - -# Verify perubahan -git diff rilis-dev..HEAD --name-only # Hanya nama file -git diff rilis-dev..HEAD --name-status # File + status (added/modified/deleted) -git diff rilis-dev..HEAD --stat # Summary -``` - ---- - -## ✨ Contoh Real Usage: Auto-Analyze Perubahan - -### **Scenario 1: Bug Fix Kamera (Issue #10716)** - -**Langkah 1: Get diff** -```powershell -git diff rilis-dev..HEAD > changes.diff -``` - -**Langkah 2: Copy ke AI dengan prompt** -``` -Branch: fix/#10716-permissions-policy-camera -Issue: #10716 - -GIT DIFF: -\`\`\`diff -diff --git a/donjo-app/core/MY_Controller.php b/donjo-app/core/MY_Controller.php -index 1a2b3c4...5d6e7f8 100644 ---- a/donjo-app/core/MY_Controller.php -+++ b/donjo-app/core/MY_Controller.php -@@ -1,6 +1,5 @@ - header = identitas(); - // ... rest of code - } - } - -diff --git a/tests/playwright/e2e/bugs/issue-10716.spec.ts b/tests/playwright/e2e/bugs/issue-10716.spec.ts -new file mode 100644 -index 0000000..1a2b3c4 ---- /dev/null -+++ b/tests/playwright/e2e/bugs/issue-10716.spec.ts -@@ -0,0 +1,45 @@ -+import { test, expect } from '@playwright/test'; -+ -+test('Camera feature should work on admin edit resident page', async ({ page }) => { -+ // Navigate and test camera access -+ // ... test code -+}); -\`\`\` - -Analyze code changes dan buatkan PR description lengkap otomatis! -``` - -**Langkah 3: AI analyze dan hasilkan PR description** ✅ - ---- - -### **Scenario 2: Feature Baru (Export Excel)** - -**Get diff:** -```powershell -git diff rilis-dev..HEAD -``` - -**Kirim ke AI:** -``` -Branch: feature/export-excel -Issue: #12345 - -GIT DIFF: -\`\`\`diff -[PASTE FULL DIFF] -\`\`\` - -Analyze perubahan dan buatkan PR description dengan auto-detect: -- Apa feature yang ditambahkan -- File mana yang baru -- File mana yang dimodifikasi -- Alasan perubahan -- Testing yang perlu dilakukan -``` - ---- - -### **Scenario 3: Refactor Controller** - -**Kirim diff ke AI dan let it analyze:** -``` -Branch: refactor/controller-cleanup -Issue: #11111 - -GIT DIFF: -\`\`\`diff -[PASTE FULL DIFF dari semua file yang di-refactor] -\`\`\` - -Auto-analyze dan buatkan PR description! -``` - ---- - -## 💬 Prompt Interaktif: Tanya-Jawab untuk Analisis Lebih Detail - -Jika Anda ingin AI ask clarifying questions sebelum generate PR description: - -``` -Berikut adalah git diff untuk PR saya: - -BRANCH: [nama branch] -ISSUE: #[nomor] - -\`\`\`diff -[PASTE GIT DIFF] -\`\`\` - -Tolong analyze dan tanya pertanyaan clarifying questions jika diperlukan untuk -generate PR description yang lebih akurat: -- Apa masalah utama yang dipecahkan PR ini? -- Apakah ada breaking changes? -- Bagaimana cara test feature ini? -- Ada side effects yang perlu diperhatikan? - -Setelah dapat jawaban, buatkan PR description lengkap. -``` - -## 🔍 Analisis yang AI Lakukan Otomatis dari Code Diff - -Ketika Anda paste git diff, AI akan otomatis: - -### **1. Identifikasi File Changes** -- File baru/added (`+`) -- File modified (`~`) -- File deleted (`-`) -- File renamed - -### **2. Analyze Code Changes per File** -- Baca setiap `@@ @@` hunk -- Pahami context dari perubahan -- Identify function/method yang diubah -- Identify import/dependency yang ditambah/hapus - -### **3. Infer Problem & Solution** -``` -Contoh: -- Jika ada SecurityHeaders::handle() dihapus dari MY_Controller - → Problem: Security headers diterapkan ke semua halaman - → Solution: Move SecurityHeaders ke Web_Controller aja -``` - -### **4. Determine PR Type** -``` -- Banyak deleted code? → Refactor atau Cleanup -- Banyak new files? → Feature baru -- Bug fix berdasarkan issue? → Bug fix -- Tests ditambahkan? → Biasanya feature atau bug fix -``` - -### **5. Auto-Generate Documentation** -- Deskripsi singkat -- Perubahan yang dilakukan -- Alasan perubahan -- Impact analysis -- Suggested testing -- File-by-file explanation - -### **6. Suggest Testing Strategy** -Berdasarkan code changes: -- Manual testing steps -- Unit tests yang harus di-check -- Integration tests yang relevant -- Edge cases - ---- - -## 🎯 Step-by-Step Workflow - -### **1. Get Git Diff** -```powershell -# Ensure you're on correct branch -git branch - -# Get full diff -git diff rilis-dev..HEAD > my-changes.diff - -# Verify changes -git diff rilis-dev..HEAD --name-status -``` - -### **2. Copy Entire Diff to AI** -``` -BRANCH: [nama-branch-anda] -ISSUE: #[nomor-issue] - -GIT DIFF (dari: git diff rilis-dev..HEAD): -\`\`\`diff -[PASTE SELURUH ISI FILE my-changes.diff] -\`\`\` - -Analyze dan generate PR description otomatis! -``` - -### **3. Receive Complete PR Description** -AI akan deliver: -- ✅ Title dengan format yang benar -- ✅ Deskripsi lengkap dengan context -- ✅ List semua file yang berubah dengan penjelasan -- ✅ Alasan perubahan dan impact analysis -- ✅ Testing checklist berdasarkan code changes -- ✅ Steps to reproduce (jika applicable) -- ✅ Related issue link -- ✅ Siap copy-paste ke GitHub! 🚀 - -### **4. Copy-Paste to GitHub PR** -Tinggal copy-paste hasil generate ke GitHub dan submit PR! - ---- - -## 🔐 Privacy & Security - -- Git diff hanya contain code changes, bukan secrets -- Jika ada config/credentials terlihat di diff, harap remove sebelum copy ke AI -- Aman untuk di-paste ke public conversation - ---- - -## 📊 Perbandingan: Manual vs Git Diff vs GitHub MCP - -| Aspek | Manual Input | Git Diff | GitHub MCP | -|-------|--------------|----------|-----------| -| Setup | 0 (instant) | ~1 min | ~1 min | -| Copy-paste | ✅ Manual | ✅ Manual | ❌ None | -| Fetch changes | ❌ Manual | ✅ Local git | ✅ API | -| Read full file | ❌ No | ❌ Diff only | ✅ Yes | -| Understand context | ⏱️ 10 min | ⏱️ 5 min | ✅ 30 sec | -| Analyze code | ⏱️ 15 min | ⏱️ 5 min | ✅ Otomatis | -| Generate desc | ⏱️ 10 min | ⏱️ 2 min | ✅ ~30 sec | -| **Total waktu** | **~50 min** | **~5 min** | **~2 min** | -| Accuracy | 70% | 85% | **95%+** | - ---- - ---- - -## ⚠️ Tips Penting - -### **Pastikan diff clean:** -```bash -# Jangan ada merge conflicts -git status - -# Hanya diff terhadap base branch -git diff rilis-dev..HEAD # ✅ Benar - -git diff HEAD~1..HEAD # ❌ Salah (bisa include commits lain) -``` - -### **Minimal context dalam diff:** -```bash -# Default context 3 lines, bisa perbesar jika perlu -git diff -U10 rilis-dev..HEAD # 10 lines context -``` - -### **Untuk file yang banyak berubah:** -```bash -# Split menjadi beberapa diff jika perlu -git diff rilis-dev..HEAD -- "donjo-app/**" > backend-changes.diff -git diff rilis-dev..HEAD -- "tests/**" > test-changes.diff -``` - ---- - -## 📊 Contoh Penggunaan Real - -### **Contoh 1: Bug Fix Kamera** - -``` -Saya sudah fix bug kamera di halaman admin OpenSID. - -Perubahan: -- Hapus SecurityHeaders::handle() dari MY_Controller.php -- Tambah SecurityHeaders::handle() ke Web_Controller.php -- Tambah test file tests/playwright/e2e/bugs/issue-10716.spec.ts - -Issue: #10716 - -Alasan: Permissions-Policy camera=() di MY_Controller memblokir akses kamera -di halaman admin, padahal admin butuh kamera untuk upload foto. - -Testing: -- Manual test kamera di halaman edit penduduk ✅ -- Manual test kamera di halaman edit kelompok ✅ -- Playwright test untuk memverifikasi Permissions-Policy ✅ - -Tolong buatkan PR description yang detail dan terstruktur sesuai template. -``` - -### **Contoh 2: Feature Baru** - -``` -Saya buat feature baru di OpenSID untuk export data ke Excel. - -File baru: -- app/Exports/PendudukExport.php -- app/Http/Controllers/Admin/ExportController.php -- resources/views/admin/export/penduduk.blade.php - -File modified: -- routes/web.php (tambah route export) -- app/Models/Penduduk.php (tambah method untuk export) - -Issue: #12345 - -Testing: -- Unit test untuk ExportController -- Manual test export 100 records -- Manual test export dengan filter - -Tolong buatkan PR description lengkap dengan section fitur, implementation detail, testing. -``` - ---- - -## 🚀 Tips Menggunakan Prompt - -### **1. Berikan Info Sebanyak Mungkin** -Semakin detail info yang Anda berikan, semakin bagus PR description yang dihasilkan. - -``` -❌ Tidak ideal: -"Fix kamera" - -✅ Ideal: -"Fix issue #10716 - Permissions-Policy camera=() memblokir akses kamera -di halaman admin karena diterapkan di MY_Controller. Solusi: pindahkan -SecurityHeaders::handle() ke Web_Controller agar hanya berlaku di frontend." -``` - -### **2. Sertakan Context Repository** -``` -"Saya sedang develop untuk OpenSID Laravel 10 (branch opensid-laravel-10, -base branch rilis-dev). Project menggunakan Laravel 10, CodeIgniter legacy, -Playwright untuk e2e testing, dan Vite untuk asset bundling." -``` - -### **3. Sebutkan File yang Diubah** -``` -"File yang diubah: -- donjo-app/core/MY_Controller.php (hapus SecurityHeaders) -- donjo-app/core/Web_Controller.php (tambah SecurityHeaders) -- tests/playwright/e2e/bugs/issue-10716.spec.ts (new file)" -``` - -### **4. Jelaskan Testing yang Sudah Dilakukan** -``` -"Testing yang sudah dilakukan: -- Manual: buka halaman admin, test fitur kamera ✅ -- Manual: test di Chrome, Firefox ✅ -- Playwright: verify Permissions-Policy tidak ada di admin ✅ -- Playwright: verify akses camera API berhasil ✅" -``` - ---- - -## 📋 Template Prompt Siap Pakai - Copy-Paste Langsung - -### **Template 1: Minimal & Fast** - -``` -BRANCH: [nama-branch] -ISSUE: #[nomor] - -GIT DIFF: -\`\`\`diff -[PASTE GIT DIFF] -\`\`\` - -Generate PR description! -``` - -### **Template 2: Dengan Context Tambahan** - -``` -BRANCH: [nama-branch] -ISSUE: #[nomor] -TIPE PR: [Fix/Feature/Refactor] - -GIT DIFF (dari: git diff rilis-dev..HEAD): -\`\`\`diff -[PASTE GIT DIFF] -\`\`\` - -TESTING DILAKUKAN: -- [Test 1] -- [Test 2] - -AUTO-ANALYZE diff dan generate PR description lengkap! -``` - -### **Template 3: Dengan Questioning** - -``` -BRANCH: [nama-branch] -ISSUE: #[nomor] - -GIT DIFF: -\`\`\`diff -[PASTE GIT DIFF] -\`\`\` - -TANYA: [Opsi jika ada ambiguitas] -- Adalah ini bug fix untuk issue #XXX? -- Feature apa yang ditambahkan? -- Ada breaking changes? - -Analyze, clarify jika perlu, terus generate PR description! -``` - ---- - -## ✅ Checklist Sebelum Kirim Prompt ke AI - -- [ ] Branch sudah di-checkout dengan benar -- [ ] Sudah run: `git diff rilis-dev..HEAD` -- [ ] Copy seluruh output diff (jangan partial) -- [ ] Tahu nomor issue yang ditargetkan -- [ ] Sudah test locally (minimal manual test) -- [ ] Git diff tidak mengandung credentials/secrets - ---- - -## 🎬 Live Example: Step-by-Step Walkthrough - -### **Scenario: Fix Issue #10716 - Camera Permission Bug** - -**Step 1: Checkout branch** -```powershell -git checkout fix/#10716-permissions-policy-camera -``` - -**Step 2: Get diff** -```powershell -git diff rilis-dev..HEAD > changes.diff -``` - -**Step 3: View changes summary** -```powershell -git diff rilis-dev..HEAD --stat - -# Output: -# donjo-app/core/MY_Controller.php | 2 - -# donjo-app/core/Web_Controller.php | 3 + -# tests/playwright/e2e/bugs/issue-10716.spec.ts | 45 +++++++ -# 3 files changed, 46 insertions(+), 2 deletions(-) -``` - -**Step 4: Copy diff ke AI** -``` -BRANCH: fix/#10716-permissions-policy-camera -ISSUE: #10716 - -GIT DIFF: -\`\`\`diff -diff --git a/donjo-app/core/MY_Controller.php b/donjo-app/core/MY_Controller.php -index abc123..def456 100644 ---- a/donjo-app/core/MY_Controller.php -+++ b/donjo-app/core/MY_Controller.php -@@ -1,6 +1,5 @@ - pr-$(get-date -format yyyy-MM-dd-HHmm).diff - -# List files only -git diff rilis-dev..HEAD --name-only -``` - -### **Verify sebelum submit PR** - -```bash -# Validate branch -git branch -vv # Verify tracking - -# Count commits -git rev-list --count rilis-dev..HEAD - -# Log commits -git log rilis-dev..HEAD --oneline -``` - ---- - -## 💡 FAQ - -**Q: Apakah bisa analyze hanya sebagian dari diff?** -A: Bisa, tapi lebih baik full diff agar AI dapat context lengkap. - -**Q: Bagaimana jika diff sangat besar?** -A: AI bisa handle sampai ratusan line diff. Jika terlalu besar, split menjadi multiple PRs. - -**Q: Apakah secure untuk paste diff yang contain API keys?** -A: JANGAN! Hapus credentials sebelum paste. Gunakan git diff --ignore-all-space untuk skip secrets. - -**Q: Bisa analyze multiple branches sekaligus?** -A: Bisa, tapi recommend satu per satu untuk clarity. - -**Q: Apakah hasil PR description 100% accurate?** -A: ~95%. Review hasil sebelum submit ke GitHub, specially untuk: -- Complex business logic -- Breaking changes -- Migration guides - ---- - -## 🚀 Quick Start (Fastest Way) - -### **Option 1: Gunakan GitHub MCP (RECOMMENDED)** - -```powershell -# Cukup bilang ke AI: -# "Analyze branch fix/#10716-camera di OpenSID/premium (base: rilis-dev, issue: #10716) -# menggunakan GitHub MCP dan generate PR description!" - -# AI akan langsung: -# 1. Access repo via GitHub MCP -# 2. Fetch all changes -# 3. Analyze code -# 4. Generate PR description -# 5. Siap copy-paste! ✅ - -# Total: ~90 detik! -``` - -### **Option 2: Jika GitHub MCP tidak tersedia** - -```powershell -# 1. Get diff -git diff rilis-dev..HEAD > changes.diff - -# 2. Open changes.diff dan copy seluruh isinya - -# 3. Kirim prompt ke AI: -# "BRANCH: [nama-branch] -# ISSUE: #[nomor] -# GIT DIFF: -# \`\`\`diff -# [PASTE SELURUH DIFF] -# \`\`\` -# Generate PR description!" - -# 4. Copy hasil ke GitHub PR description - -# 5. Submit PR! 🎉 - -# Total: ~5 menit -``` - ---- - -## 🔗 Info GitHub MCP untuk AI Analysis - -Ketika meminta AI analyze menggunakan GitHub MCP, pastikan berikan: - -``` -Repository: OpenSID/premium -Owner: OpenSID -Branch to analyze: [nama-branch-anda] -Base branch: rilis-dev -Issue number: #[nomor-issue] -``` - -**AI akan bisa:** -- ✅ Fetch branch files langsung dari GitHub -- ✅ Read actual code (bukan hanya diff) -- ✅ Analyze git log/commits -- ✅ Compare dengan rilis-dev branch -- ✅ Understand full context dari changes -- ✅ Generate PR description yang akurat - ---- - -## 📝 Template Prompt untuk GitHub MCP Analysis - -**FASTEST METHOD:** - -``` -Gunakan GitHub MCP untuk analyze branch berikut: - -REPOSITORY: OpenSID/premium -BRANCH: [nama-branch-anda] -BASE_BRANCH: rilis-dev -ISSUE: #[nomor-issue] - -Fetch semua changes, read code, dan generate PR description lengkap -sesuai template_ai/TEMPLATE_PR_DESCRIPTION.md dengan section: -- Judul PR -- Deskripsi singkat -- Perubahan yang dilakukan -- Alasan perubahan -- Dampak perubahan -- File yang diubah -- Testing checklist -- Related issue - -Langsung analyze dari repo - output siap copy-paste ke GitHub! 🚀 -``` - ---- - -**Total waktu dari code changes ke PR siap submit:** -- **Dengan GitHub MCP: ~90 detik** ⚡⚡⚡ (FASTEST!) -- **Dengan Git Diff: ~5 menit** ⚡ diff --git a/template_ai/TEMPLATE_PR_DESCRIPTION.md b/template_ai/TEMPLATE_PR_DESCRIPTION.md deleted file mode 100644 index 23b180cb4..000000000 --- a/template_ai/TEMPLATE_PR_DESCRIPTION.md +++ /dev/null @@ -1,322 +0,0 @@ -# Template Prompt untuk Membuat PR Description - -Gunakan template ini sebagai panduan untuk membuat PR description yang lengkap dan terstruktur. - ---- - -## Instruksi Penggunaan - -1. **Ganti semua placeholder** yang ditandai dengan `[...]` dengan informasi spesifik dari PR Anda -2. **Hapus section** yang tidak relevan dengan PR Anda -3. **Pastikan checklist** sudah diisi dengan benar -4. **Review kembali** sebelum submit - ---- - -## Template PR Description - -```markdown -# Pull Request: [Judul PR yang jelas dan deskriptif] - -## Deskripsi - -[Jelaskan secara singkat apa yang PR ini lakukan. Tuliskan masalah yang sedang dipecahkan dan solusi yang diberikan dalam 2-3 kalimat] - -### Perubahan yang dilakukan: - -1. **[Tipe Perubahan]**: [Deskripsi perubahan di file/modul] -2. **[Tipe Perubahan]**: [Deskripsi perubahan di file/modul] -3. **[Tipe Perubahan]**: [Deskripsi perubahan di file/modul] -4. **[Tipe Perubahan]**: [Deskripsi perubahan di file/modul] -5. **[Tipe Perubahan]**: [Deskripsi perubahan di file/modul] - -### Alasan perubahan: - -- **Poin 1**: [Jelaskan mengapa perubahan ini diperlukan] -- **Poin 2**: [Jelaskan dampak positif dari perubahan] -- **Poin 3**: [Jelaskan bagaimana ini memecahkan masalah] - -### Dampak perubahan: - -✅ **Aspek 1**: [Deskripsi dampak positif] -✅ **Aspek 2**: [Deskripsi dampak positif] -✅ **Aspek 3**: [Deskripsi dampak positif] - -## Masalah Terkait (Related Issue) - -- Solusi untuk perbaikan terkait issue #[nomor issue] - -[Link ke issue di GitHub] - -## Langkah untuk mereproduksi (Steps to Reproduce) - -### Sebelum perbaikan (masalah): -1. [Langkah 1] -2. [Langkah 2] -3. [Langkah 3] -4. [Langkah 4] -5. ❌ [Hasil yang tidak diinginkan/error] - -### Setelah perbaikan (fix): -1. [Langkah 1] -2. [Langkah 2] -3. [Langkah 3] -4. [Langkah 4] -5. ✅ [Hasil yang diinginkan/expected behavior] - -### Testing pada fitur lain yang terkait: -- [Fitur 1] ✅ [Status] -- [Fitur 2] ✅ [Status] -- [Fitur 3] ✅ [Status] - -## Daftar Periksa (Checklist) -- [ ] Saya telah mematuhi [aturan penulisan script](https://github.com/OpenSID/OpenSID/wiki/Aturan-Penulisan-Script). -- [ ] Saya telah mengikuti [proses review pull request](https://github.com/OpenSID/OpenSID/wiki/proses-review-pull-request). -- [ ] Saya telah membuat [unit test/integration test] untuk memverifikasi perbaikan -- [ ] Testing manual telah dilakukan di environment development -- [ ] Tidak ada console error atau warning -- [ ] Code sudah di-review oleh [minimal 1 orang] - -## Teknis Detail - -### Penjelasan Teknis -[Jelaskan detail teknis, arsitektur, atau flow yang berubah. Gunakan code snippets jika diperlukan] - -### Konfigurasi yang berubah -[Jika ada perubahan di config files, sebutkan di sini] - -### Dependencies yang ditambahkan -- [Package 1]: [Versi] -- [Package 2]: [Versi] - -[Atau tuliskan "Tidak ada dependencies baru" jika tidak ada] - -## Testing - -### Manual Testing -- [ ] [Test Case 1] -- [ ] [Test Case 2] -- [ ] [Test Case 3] -- [ ] [Regression Testing - test fitur yang sudah ada tidak rusak] - -### Automated Testing -- [ ] [Unit Test - Nama test] -- [ ] [Integration Test - Nama test] -- [ ] [Playwright Test - Nama test] - -### Browser Compatibility (jika applicable) -- [ ] Chrome/Edge (Chromium) -- [ ] Firefox -- [ ] Safari - -## Screenshots / Video - -[Jika ada perubahan UI, tambahkan screenshots atau GIF yang menunjukkan sebelum dan sesudah] - -### Sebelum: -[Screenshot atau deskripsi] - -### Sesudah: -[Screenshot atau deskripsi] - -## Breaking Changes -[Tuliskan "Tidak ada" jika tidak ada breaking changes, atau jelaskan breaking changes jika ada] - -## Migration Guide -[Jika diperlukan, jelaskan langkah-langkah migration. Atau tuliskan "Tidak diperlukan" jika tidak perlu] - -## References -- [Reference 1]: [Link] -- [Reference 2]: [Link] -- [Documentation]: [Link] - ---- - -**Catatan tambahan:** [Tuliskan catatan penting, pertanyaan untuk reviewer, atau informasi tambahan lainnya] -``` - ---- - -## Panduan Penulisan PR Description yang Baik - -### ✅ DO's (Hal yang harus dilakukan) - -1. **Judul yang jelas** - - Gunakan format: `[Fix|Feature|Refactor|Docs]: Deskripsi singkat` - - Contoh: `Fix: Permissions Policy untuk fitur kamera di halaman admin` - -2. **Deskripsi ringkas** - - Jelaskan "apa" dan "mengapa", bukan "bagaimana" - - Gunakan 2-3 kalimat untuk overview - -3. **Perubahan terstruktur** - - Gunakan bullet points dengan nomor - - Jelaskan setiap perubahan dengan singkat - -4. **Alasan yang jelas** - - Jelaskan masalah yang sedang dipecahkan - - Jelaskan mengapa solusi ini dipilih - - Jelaskan dampak perubahan - -5. **Steps to Reproduce** - - Gunakan untuk fitur baru atau bug fix - - Jelaskan sebelum dan sesudah perbaikan - - Gunakan emoji (❌ untuk error, ✅ untuk success) - -6. **File changes dengan context** - - Tampilkan diff yang relevan - - Gunakan minimal 3 baris context sebelum-sesudah - - Jelaskan alasan setiap perubahan file - -7. **Testing checklist** - - Pastikan semua test case tercakup - - Jelaskan jenis testing yang dilakukan - - Sebutkan browser/environment yang di-test - -### ❌ DON'Ts (Hal yang tidak boleh dilakukan) - -1. ❌ Judul yang terlalu panjang atau ambigu -2. ❌ Deskripsi yang terlalu teknis tanpa context -3. ❌ Menampilkan diff tanpa penjelasan -4. ❌ Lupa mencantumkan issue link yang terkait -5. ❌ Tidak menjalankan testing sebelum submit -6. ❌ Menuliskan commit message yang tidak informatif -7. ❌ PR tanpa checklist yang lengkap - ---- - -## Tips Tambahan - -### 1. Link ke Issue -```markdown -Closes #10716 -Fixes #10716 -Related to #10716 -``` - -### 2. Referensi External -```markdown -- [Permissions Policy MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy) -- [Video Tutorial](https://...) -- [Documentation](https://...) -``` - -### 3. Code Block Syntax -```markdown -# Untuk PHP -\`\`\`php -// Kode PHP di sini -\`\`\` - -# Untuk TypeScript -\`\`\`typescript -// Kode TypeScript di sini -\`\`\` - -# Untuk Diff -\`\`\`diff -- Baris yang dihapus -+ Baris yang ditambah - Baris yang tidak berubah -\`\`\` -``` - -### 4. Emoji untuk Status -- ✅ Berhasil / Done -- ❌ Error / Failed -- ⚠️ Warning / Perhatian -- 📝 Catatan / Note -- 🔗 Link -- 🎯 Target / Goal - ---- - -## Contoh Struktur Minimal untuk PR Kecil - -Untuk PR yang relatif sederhana, gunakan struktur minimal ini: - -```markdown -# Pull Request: [Judul] - -## Deskripsi -[Jelaskan singkat apa yang dilakukan] - -## Perubahan -- [Perubahan 1] -- [Perubahan 2] - -## Testing -- [ ] [Test 1] -- [ ] [Test 2] - -## Checklist -- [x] Code sesuai aturan penulisan -- [x] Testing manual dilakukan -- [x] Tidak ada breaking changes -``` - ---- - -## Template untuk Issue-Specific PR's - -### Untuk Bug Fix -```markdown -# Pull Request: Fix [Deskripsi Bug] - -## Deskripsi -[Jelaskan bug dan cara memperbaikinya] - -## Related Issue -Closes #[nomor] - -## Steps to Reproduce -[Langkah-langkah untuk melihat bug] - -## Solution -[Penjelasan solusi] - -## Testing -- [ ] Bug sudah diperbaiki -- [ ] Tidak ada regression -``` - -### Untuk Feature -```markdown -# Pull Request: Feature [Nama Fitur] - -## Deskripsi -[Jelaskan fitur baru] - -## Scope -- [x] Feature 1 -- [x] Feature 2 -- [ ] Feature 3 (untuk PR berikutnya) - -## Testing -- [ ] Feature berfungsi sesuai requirement -- [ ] UI/UX sudah di-review -``` - -### Untuk Refactor -```markdown -# Pull Request: Refactor [Modul/Class] - -## Tujuan Refactor -[Jelaskan mengapa perlu refactor] - -## Perubahan -- [Perubahan 1] -- [Perubahan 2] - -## Impact -- ✅ Code lebih maintainable -- ✅ Performance [meningkat/tetap sama] - -## Testing -- [ ] Existing test masih passing -- [ ] Tidak ada breaking changes -``` - ---- - -**Ingat:** PR description yang baik membantu reviewer memahami konteks dengan cepat dan mempercepat proses review! 🚀