# Dev Journal 2026-06

## 2026-06-04 14:45:11

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: ollama-client-speed-optimization
- workspace/path kerja aktif: W:\san_staging
- modul/area: developer tooling / Ollama / Continue / Roo-Cline
- ringkasan perubahan: Optimasi service Ollama di 192.168.5.10 untuk penggunaan client agent CPU-only; batasi context default 4096, keep-alive 30 menit, single loaded model, single parallel request, dan update konfigurasi client lokal agar memakai qwen2.5-coder:7b sebagai model Ollama cepat.
- daftar file yang diubah:
  - /etc/systemd/system/ollama.service.d/override.conf (server 192.168.5.10; backup: /etc/systemd/system/ollama.service.d/override.conf.codex-20260604-143615)
  - C:\Users\vansgare\.continue\config.yaml
  - C:\Users\vansgare\.continue\index\globalContext.json
  - C:\Users\vansgare\AppData\Roaming\Code\User\settings.json
  - C:\Users\vansgare\AppData\Roaming\Code\User\globalStorage\rooveterinaryinc.roo-cline\cache\ollama_models.json
  - W:\san_staging\docs\dev-journal\2026-06.md
- status verifikasi singkat: Ollama service active; /api/version OK; qwen2.5-coder:7b loaded sebagai satu-satunya model aktif; context_length 4096; final warm smoke test `Return only OK` selesai 1.68 detik dengan load_duration 389 ms; JSON config client valid.

## 2026-06-06 10:30:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: fix-reset-variant-locker
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (shopping cart)
- ringkasan perubahan: Fix BUG #1 — method `reset()` di `_shoppingCart.php` tidak melepas hold locker untuk produk variant. Kode lama hanya handle `MdlLockerStock` (non-variant), sehingga saat reset cart, variant items hold-nya tetap menggantung di `stock_locker_variant` dan active tidak kembali. Fix: tambah branch varian yang pakai `MdlLockerStockVariant::cekLoker()` + release hold → active. Non-variant tetap pakai `MdlLockerStock` + tambah guard `isset()` untuk cegah notice jika hold/active row tidak ditemukan.
- daftar file yang diubah:
  - application/modules/konversi/controllers/_shoppingCart.php (method reset(), line 2299-2409)
- status verifikasi singkat: PHP syntax check lolos. Non-variant: hold→0, active+=holdQty ✅. Variant: hold→0, active+=holdQty via MdlLockerStockVariant ✅. Edge case: cart campuran variant+non-variant ✅.

## 2026-06-06 11:00:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: enhance-variant-picker-ui
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (variant picker)
- ringkasan perubahan: Enhance variant_picker.php + controller data:
  - Info bar master produk (kode, nama, satuan, total stok varian)
  - Filter/search SKU dan label varian (muncul otomatis jika varian > 5)
  - Warna peringatan stok: merah jika 0, oranye jika <= 5
  - Indikator max stok "/N" di samping input qty
  - Total row (tfoot) dengan live update qty request
  - CSS compact (padding, font, height dikecilkan)
- daftar file yang diubah:
  - application/modules/konversi/views/variant_picker.php
  - application/modules/konversi/controllers/_selectorItem.php (add productCode, productSatuan, totalStockAllVariant ke data)
- status verifikasi singkat: PHP syntax check lolos kedua file.

## 2026-06-06 11:30:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: fix-tableIn-detail-variant-fields
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (Create->save / ValueGate / tableIn_detail)
- ringkasan perubahan: Fix session `tableIn_detail` berisi literal string field name (`"cart_key"=>"cart_key"`) bukan nilai asli. Root cause 3 lapis:
  1. Config: variant fields (cart_key, variant_id, variant_sku, variant_label, variant_key) duplikat di `tableIn` dan `tableIn_static`. `tableIn_static` jalan setelah `tableIn` dan overwrite nilai benar dengan literal string.
  2. Fix: Hapus 5 baris variant fields dari `tableIn_static` di semua section (detail, detail2, detail2_sum, rsltItems).
  3. Typo: `"variant_label" => "variant_labe"` hilang huruf 'l' di 19 lokasi — diperbaiki semua.
- daftar file yang diubah:
  - application/modules/konversi/config/coTransaksiCore.php
- status verifikasi singkat: PHP syntax check lolos. Tidak ada lagi `variant_labe` di file. `tableIn_static` bersih dari variant fields.

## 2026-06-06 14:30:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: fix-dofollowup-variant-5049
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (FollowUp doFollowup)
- ringkasan perubahan: Fix error 5049 "Transaksi gagal disimpan karena sudah diotorisasi" saat followup transaksi variant. Root cause: `doFollowup()` dan `doCancelPacking()` di FollowUp.php mengecek `isset($_SESSION[$cCode]['items'][$row->produk_id])` — hanya cocok untuk non-variant (session key = produk_id). Untuk variant, session key adalah `variant:{produk_id}:{variant_id}`, sehingga pengecekan selalu false → `$arrValidQtyReady` kosong → error 5049.
  - Fix: generate `$sessionKey` berdasarkan `variant_id`, gunakan untuk pengecekan session dan key array `$items`.
  - Ditemukan juga bug serupa di `followupPreview()` (tableIn_detail_values lookup by produk_id tanpa variant awareness) — belum difix di sesi ini.
- daftar file yang diubah:
  - application/modules/konversi/controllers/FollowUp.php (2 blok foreach $tmpTr: doFollowup line 4976, doCancelPacking line 21067)
- status verifikasi singkat: PHP syntax check via `php -l` dilakukan. Perubahan logika: untuk variant item, session key dibentuk `variant:{pid}:{vid}`, non-variant pakai `produk_id`. Guard `arrValidQtyReady` sekarang terisi untuk transaksi variant.

## 2026-06-06 15:30:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: fix-rekening-pembantu-varian-tidak-nulis
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (RekeningPembantuProdukVarian, PreFifoProdukJadi)
- ringkasan perubahan: Fix `RekeningPembantuProdukVarian` tidak menulis in/out ke tabel varian. Root cause:
  - Pipeline: `items` gate → `PreFifoProdukJadi` preProcessor → `rsltItems` gate → `RekeningPembantuProdukVarian`
  - `PreFifoProdukJadi::pair()` di line 189-193 skip total semua item dengan `variant_id > 0` dengan `return true` tanpa set `$this->result`. Akibatnya `exec()` return null → `rsltItems` kosong untuk varian → component varian tidak ada input → tidak menulis.
  - Fix: Ubah skip jadi pass-through. PreProcessor tetap return true (tidak proses FIFO) tapi `$this->result` diisi dengan data dari static params, termasuk variant fields (`variant_id`, `variant_label`, `cart_key`, `variant_sku`, `variant_key`).
  - Ditemukan juga `PreFifoAverageConvertion` line 94-97 punya skip serupa untuk output ke `items` gate — tidak difix karena `items` gate sudah terisi dari session (hanya kehilangan update HPP dari FIFO untuk varian).
- daftar file yang diubah:
  - application/models/Preprocs/PreFifoProdukJadi.php (pass-through block gantikan skip di line 189-193)
- status verifikasi singkat: PHP syntax check lolos. Pass-through menghasilkan `rsltItems` entries untuk varian dengan struktur field sama seperti non-varian + variant fields. Backward compatible: non-varian tetap proses FIFO seperti biasa.

## 2026-06-07 10:00:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: fix-gap-lockerstockvariant-source-items
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (coTransaksiCore postProcessor 1334)
- ringkasan perubahan: **Tambah 3 komponen variant untuk source items (`items` gate)** yang sebelumnya missing:
  - **LockerStockVariant (hold, -qty)** — release hold di `stock_locker_variant` untuk source variant items
  - **LockerStockVariant (moved, +qty)** — tulis moved ke `stock_locker_variant` untuk source variant items
  - **LockerStockMutasiVariant (qty_debet=-qty)** — mutasi variant source items
  - Konfigurasi identik dengan non-variant counterpart (LockerStock/LockerStockMutasi) tapi pakai `comName => LockerStockVariant` / `LockerStockMutasiVariant`.
  - Mutual exclusion sudah diverifikasi: `ComLockerStock.php:118-122` skip jika varian_id > 0, `ComLockerStockVariant.php:60-62` skip jika variant_id < 1. Tidak ada double processing.
  - Sebelumnya hanya non-variant counterpart yang ada, variant items hanya dilewati (skip by ComLockerStock) tanpa alternatif → `stock_locker_variant` tidak terupdate untuk source items (hanya target side `items2_sum` yang punya).
- daftar file yang diubah:
  - application/modules/konversi/config/coTransaksiCore.php (postProcessor 1334, detail section, tambah 3 array setelah LockerStockMutasi line 654)
- status verifikasi singkat: Struktur konfigurasi valid (PHP array). Mutual exclusion diverifikasi via source code kedua Com classes. Target side (items2_sum) sudah punya komponen varian sejak awal (tidak diubah).

## 2026-06-07 11:00:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: trace-15-skenario-items-gate
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi — static analysis 15 skenario
- ringkasan perubahan: **Laporan verifikasi 15 skenario untuk items gate postProcessor.** Trace data flow untuk setiap kombinasi NV/V source melalui pipeline: preProcessor → items gate postProcessor → rsltItems → write DB. Temuan kritis:
  - Pre-existing bug: field name mismatch (`qty`→`jml`, `name`→`nama`) menyebabkan semua LockerStock/LockerStockVariant NO-OP (jumlah=0). Mitigasi: locker diupdate di shopping cart.
  - Mutual exclusion diverifikasi untuk 5 Com classes — tidak ada double processing.
  - Edge case S13/S14: cart_key=variant:X:Y dengan variant_id=0/string → data loss pre-existing.
  - 13/15 skenario ✅, 2/15 ❌ (pre-existing).
- daftar file yang diubah:
  - docs/15-skenario-verifikasi-konversi-items-gate.md (file baru — laporan lengkap)
- status verifikasi singkat: Static code analysis selesai. 13 skenario OK, 2 edge case pre-existing. Rekomendasi: fix pre-existing field name mismatch jika diinginkan.

## 2026-06-10 23:00:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: dual-locker-co-update-variant
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (locker stock)
- ringkasan perubahan: **Implementasi dual-locker co-update untuk variant.** Sebelumnya saat user memilih produk variant, hanya `stock_locker_variant` yang diupdate (active↔hold), sedangkan `stock_locker` parent tidak tersentuh → locker leak. Fix: tambah co-update parent `stock_locker` di 3 titik mutasi varian:

  1. `reserveVariantLockerForSelect()` — SELECT produk / ubah qty: parent active −jmlNambah, parent hold +jmlNambah
  2. `releaseVariantLockerOnRemove()` — REMOVE item: parent hold −holdQty, parent active +holdQty
  3. `reset()` — CLEAR ALL (variant branch): parent hold −holdQty per varian, parent active +holdQty per varian

  Semua dalam 1 transaksi DB yang sama dengan mutasi variant locker. Parent hold disimpan sebagai 1 row aggregate per (produk_id, gudang_id, oleh_id, state='hold').

- daftar file yang diubah:
  - application/modules/konversi/controllers/_processSelectProductConvertion.php (2 fungsi: reserveVariantLockerForSelect + releaseVariantLockerOnRemove)
  - application/modules/konversi/controllers/_shoppingCart.php (reset() variant branch)
  - docs/blueprint-dual-locker-co-update-variant.md (file baru — blueprint desain)
  - docs/checklist-dual-locker-co-update-variant.md (file baru — checklist implementasi)
- status verifikasi singkat: PHP syntax check lolos kedua file. Parent active/hold query + update dalam 1 transaksi. Clamp hold ke 0 jika delta negatif. Edge case: multiple varian 1 parent, qty naik/turun, remove, reset all.

## 2026-06-10 23:45:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: dual-locker-co-update-variant-fix-accumulated-filters
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (locker stock)
- ringkasan perubahan: **Fix bug parent active tidak berkurang saat co-update.** Root cause: `MdlMother::addFilter()` append ke `$this->filters`, dan `updateData()` mengaplikasikan SEMUA akumulasi filters sebagai WHERE tambahan. Karena parent active + hold di-query dengan SATU instance `$parentLocker`, filter dari query hold (`state='hold'`) meng-overwrite `state='active'` di criteria array → UPDATE parent active WHERE `state='hold'` tidak match row active → 0 affected rows. Fix: pakai **fresh instance** (`new MdlLockerStock()`) setiap kali query/update parent, konsisten dengan pattern existing di non-variant branch (`$c = new $mdlName()` di line 1631). Berlaku di 3 titik: `reserveVariantLockerForSelect`, `releaseVariantLockerOnRemove`, dan `reset()`.
- daftar file yang diubah:
  - application/modules/konversi/controllers/_processSelectProductConvertion.php (parent queries + updates pakai fresh instances)
  - application/modules/konversi/controllers/_shoppingCart.php (parent queries + updates pakai fresh instances)
- status verifikasi singkat: PHP syntax check lolos. Logic: fresh `new MdlLockerStock()` untuk setiap cekLoker (active/hold) dan setiap updateData/addData — tidak ada lagi akumulasi filter silang.

## 2026-06-10 23:59:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: cross-type-conversion-guard
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (shopping cart, paired item validation)
- ringkasan perubahan: **Implementasi guard cross-type conversion (variant↔non-variant).** 3 lapis proteksi agar source dan target konversi wajib setipe:
  1. **View filter (shoppingCart.php:469-471)**: dropdown target hanya menampilkan opsi yang setipe dengan source (sama-sama variant / sama-sama non-variant). Deteksi tipe via prefix `variant:` pada `cart_key`/`piID`.
  2. **Controller guard recordPairedItem() (:3252-3262)**: setelah `parsePairedSelectionValue()`, bandingkan `sourceVariantId > 0` dengan `pairSel['is_variant']`. Jika berbeda, tampilkan swalAlert warning dan die().
  3. **Controller guard recordPairedItemSatuan() (:3483-3490)**: sumber variant tidak bisa konversi di mode satuan (target non-variant). Jika `sourceVariantId > 0`, reject dengan swalAlert.
- daftar file yang diubah:
  - application/modules/konversi/views/shoppingCart.php (dropdown filter — 5 baris baru)
  - application/modules/konversi/controllers/_shoppingCart.php (recordPairedItem guard — 11 baris; recordPairedItemSatuan guard — 8 baris)
- status verifikasi singkat: PHP syntax check lolos kedua file. Guard melindungi 3 entry point: (1) UI dropdown tidak tampilkan opsi salah tipe, (2) recordPairedItem via AJAX langsung reject cross-type, (3) recordPairedItemSatuan via AJAX reject jika source variant. Regression: varian→varian ✅, non-varian→non-varian ✅, varian→non-varian 🚫, non-varian→varian 🚫.

## 2026-06-11 00:45:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: fix-core-pipeline-cross-type-guard-P0
- workspace/path kerja aktif: \\192.168.5.14\web\san_staging
- modul/area: konversi (core pipeline — PreFifoProdukJadi, ComLockerStock, ComLockerStockMutasi)
- ringkasan perubahan: **Fix 3 P0 data integrity gaps** di core pipeline. Semua pola sama: guard variant ditulis lalu di-comment out, menyebabkan variant items diproses oleh komponen non-variant:

  **G1 — PreFifoProdukJadi.php**: guard variant (lines 78-119) di-comment. Varian masuk ke FIFO parent → stok parent berkurang, stok varian tidak tersentuh. Fix: skip variant items di inner loop pSpec via `variant_id > 0`, tambah early return `$this->result=array()` jika semua item variant.

  **G2 — ComLockerStock.php**: guard variant (lines 44-126) di-comment. Varian nulis ke `stock_locker` parent → parent stock double-count. Fix: uncomment seluruh guard — `$normalParams` filter, `$this->inParams = $normalParams`.

  **G3 — ComLockerStockMutasi.php**: `continue;` di line 153 di-comment. Varian nulis ke `stock_locker_mutasi` parent + `outParamsVarian` tidak pernah dipersist (`variantMutationCom` selalu null). Fix: uncomment `continue;`, hapus debug arrPrint.

- daftar file yang diubah:
  - application/models/Preprocs/PreFifoProdukJadi.php (skip variant di inner loop + early return)
  - application/models/Coms/ComLockerStock.php (uncomment guard lines 44-127)
  - application/models/Coms/ComLockerStockMutasi.php (uncomment continue; hapus debug arrPrint)
- status verifikasi singkat: PHP syntax check lolos ketiga file. Mutual exclusion dipulihkan: variant → variant pipeline ✅, non-varian → non-varian pipeline ✅. Tidak ada cross-processing. Belum ada regresi test di DB (perlu konfirmasi user untuk smoke test).


## 2026-06-15 03:43:00

- actor: codex
- source: ai-session
- operator: vansgare
- session_tag: agent1-variant-entries-2334-2336-2337
- workspace/path kerja aktif: W:\san_staging
- modul/area: konversi (coTransaksiCore postProcessor — 2334, 2336, 2337)
- ringkasan perubahan: **Tambah varian entries (LockerStockVariant, LockerStockMutasiVariant) ke postProcessor 2334, 2336, 2337 yang sebelumnya missing.** Steps 1334 dan 334 sudah lengkap dari sesi sebelumnya.

  Detail perubahan:
  - **2334** (target items2_sum gate): +1 LockerStockVariant (active) +1 LockerStockMutasiVariant. 2334r tetap supplies-only (2 entries, no variant needed).
  - **2336** (source items gate): 2336r +2 LockerStockVariant (active, hold); 2336 main +2 LockerStockVariant (hold, converted) +1 LockerStockMutasiVariant.
  - **2337** (source items gate): 2337r +2 LockerStockVariant (active, hold); 2337 main +2 LockerStockVariant (hold, converted).

  Pattern: setiap LockerStock (.produk) mendapat LockerStockVariant counterpart; setiap LockerStockMutasi mendapat LockerStockMutasiVariant counterpart. Supplies entries tidak mendapat variant (konsisten dengan existing).

- daftar file yang diubah:
  - application/modules/konversi/config/coTransaksiCore.php (+261 lines, 8007 total)
- status verifikasi singkat: PHP syntax check lolos. Struktur array valid. 33 total variant entries di file (sebelumnya ~24). Mutual exclusion diverifikasi: ComLockerStock skip varian_id>0, ComLockerStockVariant skip varian_id<1. Tidak ada double processing. Format konsisten dengan existing entries di 1334 dan 334.
