# Known Issues

Bug, keterbatasan teknis, dan inkonsistensi yang diketahui di codebase V0. Periksa daftar ini sebelum mendiagnosis masalah atau merancang fitur baru.

---

## Bug & inkonsistensi logika

### 1. ~~Dashboard `saldoKas` tidak per sumber kas~~ (selesai)

**Status:** Diperbaiki — dashboard menampilkan **Saldo BCA (global)** + **Saldo Kas Tunai cabang aktif** (neto Medis+OTC per `cabang_id`). Lihat `BRIEF_Kas_Tunai_BCA.md`.

---

### 2. `getRingkasanBulanIni()` menghitung neto global

**Lokasi:** `app/Services/KasService.php`

**Masalah:** `masuk - keluar` dihitung dari semua sumber kas digabung, bukan per rekening.

**Dampak:** Ringkasan bulan ini di dashboard tidak membedakan Kas Medis vs OTC vs BCA.

---

### 3. Rencana pembayaran tidak terhubung ke tagihan

**Masalah:** CRUD `rencana_pembayaran_pbf` tidak memiliki relasi atau aksi ke `tagihan_pbf`. Status `Dibayar` pada rencana tidak mencatat pembayaran aktual. Histori bayar aktual ada di `pembayaran_tagihan_pbf` / menu Histori Pembayaran.

**Dampak:** Admin bisa menandai rencana "Dibayar" tanpa efek ke hutang atau kas.

---

### 4. Tidak ada unique constraint nomor faktur

**Masalah:** `pembelian.nomor_faktur` dan `tagihan_pbf.nomor_faktur` tidak unique per PBF/cabang.

**Dampak:** Faktur duplikat bisa masuk dan menghasilkan tagihan ganda.

---

### 5. Race condition saldo kas (minor)

**Masalah:** `KasService::getSaldoTerakhir()` + insert tidak memakai `lockForUpdate()`.

**Dampak:** Pada konkurensi tinggi (tidak realistis di V0 single-user), saldo bisa salah. Stok sudah pakai `lockForUpdate()`, kas belum.

---

## Keterbatasan desain (bukan bug, tapi perlu diketahui)

### 6. Single user, tanpa otorisasi

Semua user authenticated punya akses penuh. Tidak ada audit `created_by` / `updated_by`.

### 7. Batas edit/hapus penjualan & DPB

Penjualan **boleh** diedit/dihapus lewat `PenjualanService` (rollback alokasi `detail_penjualan_batch` + kompensasi kas), kecuali batch stok terpakai sudah tidak ditemukan.

DPB boleh edit/hapus hanya jika tagihan belum dibayar dan stok batch dari DPB belum terpakai.

### 7b. Pelajaran merge conflict (Jul 2026)

Saat merge `feat/penjualan` ↔ `main`, resolusi conflict menghapus method role di `User` dan mempertahankan `penjualan/create.blade.php` lama.

| Gejala | Penyebab | Perbaikan |
|--------|----------|-----------|
| Login 500: `User::isAdminCabang()` undefined | Method `isOwner` / `isAdminCabang` / `bisaSwitchCabang` hilang | Kembalikan method di `app/Models/User.php` |
| Create penjualan: `$cabangList` undefined | View lama butuh `$cabangList`; controller/`_form` memakai cabang aktif | `create.blade.php` harus `@include('penjualan._form')` |

Commit perbaikan: `cc33bda`.

**Saat merge:** cek conflict di model bersama (`User`) dan view form transaksi (`penjualan/*`, `_form`) — jangan buang helper role atau shared form.

### 8. FEFO selalu otomatis

Tidak ada UI pilih batch manual. Batch dengan `tanggal_expired` NULL (jika ada) akan diurutkan tidak terduga — saat ini field wajib di form.

### 9. Jatuh tempo tagihan hardcoded +30 hari

**Lokasi:** `PembelianService::buatTagihan()`

```php
'tanggal_jatuh_tempo' => $pembelian->tanggal_faktur->copy()->addDays(30),
```

Tidak configurable per PBF atau faktur.

### 10. `pembelian.status_tagihan` redundan

Kolom ada di `pembelian` dan `tagihan_pbf` — bisa tidak sinkron karena pembayaran hanya update `tagihan_pbf`.

### 11. `mutasi_stok` jenis `Retur` tidak diimplementasi

Enum/value ada, tidak ada code path yang menulis jenis `Retur`.

### 12. Hapus master data tanpa cek referensi

Delete cabang/obat/PBF tidak dicegah jika masih dipakai di transaksi — bisa gagal di DB constraint atau orphan logic.

---

## UI / UX issues

### 13. Tombol "Lupa password?" non-fungsional

**Lokasi:** `resources/views/auth/login.blade.php`

Tombol dengan `cursor-default`, tidak ada route password reset.

### 14. Tombol "Masuk sebagai anggota" placeholder

`title="Fitur belum tersedia"` — tidak ada flow alternatif login.

### 15. Inkonsistensi styling form transaksi

Halaman `pembelian/create` dan `penjualan/create` memakai inline Tailwind, berbeda dari halaman master yang memakai `<x-card>`. Bukan bug fungsional.

### 16. Alpine.js via CDN

Bergantung jaringan eksternal untuk form dinamis. Jika CDN down, tambah/hapus baris transaksi rusak. Vite bundle tidak include Alpine.

### 17. Searchable select re-init

Pada baris dinamis Alpine, perlu manual `SiagaSearchableSelect.initWithin()` — jika lupa dipanggil setelah add row, dropdown tidak berfungsi.

---

## Data & migrasi

### 18. Migration rename untuk upgrade path

`2026_07_03_000003_rename_master_data_tables` menangani rename dari skema awal. Fresh install tidak terpengaruh, tetapi upgrade dari DB lama perlu hati-hati.

### 19. Dictionary obat hanya via seeder

Tidak ada UI CRUD untuk `master_golongan_obat`, dll. Perubahan hanya lewat DB/seeder.

### 20. Seeder password plain text

`DatabaseSeeder` set password `'password'` sebagai string — bergantung pada cast `hashed` di model `User` (Laravel 11+). Jika cast dihapus, password tidak ter-hash.

---

## Testing gaps

| Issue | Risiko |
|-------|--------|
| Tidak ada test penjualan/FEFO | Regresi stok tidak terdeteksi |
| Tidak ada test kas | **Sudah ada** `KasTunaiBcaTest` (posting CASH/TRANSFER, filter, PBF conditional cabang) |
| `Unit/ExampleTest` trivial | False sense of coverage |
| Hanya SQLite di CI | Perilaku MySQL enum bisa berbeda (jarang) |

---

## Keamanan (prototype)

| Issue | Severity | Catatan |
|-------|----------|---------|
| Tidak ada rate limiting login | Rendah | V0 internal |
| `APP_DEBUG=true` di .env.example | Medium | Jangan di produksi |
| Tidak ada 2FA | — | Out of scope |
| CSRF | OK | `@csrf` di form |
| SQL injection | OK | Eloquent + validation |
| XSS | OK | Blade `{{ }}` escaping default |

---

## Performance (belum dioptimasi)

- `getStokAgregat()` load semua batch lalu map di PHP — bisa lambat pada data besar.
- Laporan tanpa index khusus pada kolom tanggal (selain PK).
- Tidak ada caching query dashboard.

Tidak masalah untuk prototype dengan data kecil.

---

## Cara melaporkan issue baru

Saat menemukan issue baru sebagai agent:

1. Verifikasi dengan reproduce step konkret.
2. Tambahkan entry di dokumen ini dengan format: **Judul**, **Lokasi**, **Masalah**, **Dampak**, **Perbaikan disarankan**.
3. Jika memperbaiki, tambahkan test Feature yang mencegah regresi.

---

## Quick reference — file sering jadi sumber masalah

| Gejala | Periksa |
|--------|---------|
| Stok tidak berkurang/bertambah | `StokService`, `PembelianService`, `PenjualanService` |
| Saldo kas salah | `KasService`, `DashboardController` |
| Tagihan tidak update | `KasService::updateTagihanPembayaran` |
| Form transaksi error | Controller `store()`, validation rules |
| Dropdown obat kosong | `searchable-select.js`, Alpine init |
| Migration gagal | Urutan FK, nama tabel `master_*` |
| 404 route | `routes/web.php`, middleware auth |
| Login 500 role method | `app/Models/User.php` (`isOwner` / `isAdminCabang`) |
| Form penjualan `$cabangList` | Harus `penjualan._form` + cabang aktif, bukan dropdown lama |
