# Bug Log — LPK Laravel (Sprint 0–9)

Daftar isu yang ditemukan & ditangani selama refactor.

| # | Sprint | Modul | Isu | Solusi |
|---|---|---|---|---|
| 1 | 0 | Laravel | Port 8000 bentrok proses lama | Kill proses, restart `artisan serve` |
| 2 | 0 | Laravel | Tabel `sessions` hilang (migration users bawaan dihapus karena bentrok tabel V2) | Migration terpisah `create_sessions_table` |
| 3 | 0 | Models | Nama model jamak hasil generator | Rename ke singular (61 model) |
| 4 | 0 | Dashboard | `whereColumn('min_stock','>',0)` memperlakukan `0` sebagai kolom | Ganti `where('min_stock','>',0)` |
| 5 | 0 | Livewire | Layout path Livewire 4 (`components.layouts`) | Pindah ke `resources/views/layouts/` |
| 6 | 0 | Menu | Model `Menu` kurang relasi `children` | Ditambahkan |
| 7 | 1 | Auth | **Rekursi tak terbatas**: `LegacyCompatibleHasher::make()` memanggil `Hash::make()` (resolve ke hasher sendiri) → memory habis | Pakai `password_hash()` langsung |
| 8 | 1 | RBAC | `user_authorizations` tanpa `updated_at` → insert error | `UPDATED_AT = null` |
| 9 | 2 | Migration | Parse error `??` di string interpolation PHP | Ekstrak variabel dulu |
| 10 | 2 | Migration | Kolom `email` tidak ada di legacy `employee` → migrasi employees gagal total | Hapus dari mapping |
| 11 | 2 | Livewire | Closure di property default PHP invalid | Ganti `options_method` |
| 12 | 2 | Payroll-adj | `graduation_year` empty string → kolom YEAR | Konversi '' → null |
| 13 | 2 | Models | Mass-assignment (fillable) 47 model generator | `$guarded = []` |
| 14 | 2 | Data | Cleanup test menghapus pegawai asli "Test123" (`name LIKE '%Test%'`) | Dipulihkan via re-run migrasi |
| 15 | 3 | Material | Relasi `brand/type/group/size/unit` belum ada di `InventoryItem` | Ditambahkan |
| 16 | 3 | Upload | Properti `$errors` bentrok variabel global Laravel | Rename `rowErrors` |
| 17 | 3 | Test | `UploadedFile` test Livewire | `fake()->createWithContent()` |
| 18 | 4 | Migration | FK legacy hilang (PR project, GR gudang/supplier 0) — fallback null gagal utk kolom NOT NULL | Fallback VALUES id 1000 |
| 19 | 4 | Migration | notrans duplikat legacy (271 GR) | Suffix `-id` |
| 20 | 4 | Models | `$fillable = ['*']` tidak valid di Laravel | `$guarded = []` |
| 21 | 4 | Stok | `rebuildStock` tidak idempotent (stok dobel saat re-run) | Reset + bangun ulang transaksional |
| 22 | 4 | Test | Cleanup test hapus data migrasi PR | Cleanup hanya id yang dibuat test |
| 23 | 5 | Migration | `usage_type_id` NOT NULL tapi matusedtypeid 0 | Fallback jenis "Tidak Diketahui" id 1000 |
| 24 | 5 | Migration | Helper insert me-null-kan kolom NOT NULL saat fallback | Hapus dari daftar nullable FK |
| 25 | 5 | Stok | Rebuild crash saat warehouse NULL | COALESCE gudang 1000 |
| 26 | 6 | Migration | `from/to_warehouse_id` NOT NULL tapi warefrom 0/gudang invalid | Validasi daftar gudang + fallback 1000 |
| 27 | 6 | Performa | Memory 128MB habis render SPB (dropdown 5113 material dimuat walau form tertutup) | Load dropdown hanya saat `showForm` |
| 28 | 6 | Test | Cleanup test hapus SPB migrasi (8308) | Track id test + re-run |
| 29 | 7 | Migration | `supplier_id` NOT NULL di solar_receipts | Fallback VALUES 1000 |
| 30 | 7 | Test | Cleanup by id range gagal (id test kecil) | Delete by supplier uji |
| 31 | 8 | Migration | Memory 128MB (458k baris absensi) | `chunk(2000)` + batch insert |
| 32 | 8 | Migration | "Prepared statement too many placeholders" (MySQL 65.535) | Chunk 2000 × 20 kolom |
| 33 | 8 | Migration | `absencelabor` tidak punya kolom `dayjob`/`nik` → Undefined property | Akses null-safe (`??`) |
| 34 | 8 | Migration | FK attendances/payroll invalid (employee/period hilang) | Pre-validasi id (lookup set) |
| 35 | 8 | Payroll | `$loop` (Blade) dipakai di PHP murni | Counter manual |
| 36 | 8 | Data | Migrasi re-run dobel attendances (1,4 juta) | TRUNCATE + jalankan ulang sekali |
| 37 | 8 | Payroll | **THP staff legacy dihitung skema upah lama** (basic_salary 0 tapi THP besar) | Dicatat — kalibrasi nilai upah staff saat UAT (H13) |
| 38 | 9 | Users | **Tabel `users` legacy (24 user) tidak pernah dimigrasi** — hanya admin seed | Command baru `lpk:migrate:users` (users + otorisasi menu/proyek); password legacy dipertahankan → login + auto-rehash |
| 39 | 9 | Users | `active` legacy bernilai 5/0 (bukan 0/1); user sampah test (legacy_ft_/rbac_) menempati id & menghalangi migrasi | is_active = active > 0; bersihkan user sampah; id legacy dimigrasi |

## Isu terbuka / rekomendasi
1. **Formula THP staff** perlu kalibrasi nilai `basic_salary`/tunjangan di data pegawai agar generate sesuai ekspektasi (lihat UAT H13).
2. Saldo stok negatif historis (3.744 item) — hasil data legacy; koreksi via modul Koreksi Stok bila perlu.
3. Notifikasi realtime (Laravel Reverb/Pusher) — saat ini polling 30 detik (opsional, Sprint 9 p2).

---

## [FIXED] 2026-08-13 — Pagination 404 page 2 (MasterCrud) & audit komponen lain
- **Bug:** `MasterCrud::$routeName` properti **private** → tidak diserialisasi Livewire antar request → saat klik pagination/search, `key()` baca route name kosong → `abort(404)` di `/payroll/periode?page=2`.
- **Fix:** `$routeName` dijadikan `public` + `key()` di-derive dari `indexRoute` (public, dipertahankan).
- **Audit tabel lain:**
  - `TransactionIndex` — `routeName` sudah public ✅
  - `TransactionCreate`/`TransactionShow` — `$key` public ✅
  - `SimpleCrud` (Gudang, Pemasok, Posisi, dst) — `protected $model/$fields` punya nilai default di deklarasi subclass → terisi ulang saat Livewire instantiate → **aman** ✅
  - `MaterialEdit`/`CashPaymentShow`/`TransferRequestShow` — dynamic props / `public $record/$item` ✅
- **Verifikasi:** `PaginationLivewireTest` (3 test) — pagination/search/save Livewire utk SimpleCrud + render ganda TransactionIndex. Total **65 test lulus**.
