UPDATE v616: Gudang Klawas & Gudang Exbkpl ditambahkan
             (kumulatif: MEMUAT v615, v614, v607, v606, v602, v603)

>>> BACKEND WAJIB RESTART <<<
>>> FRONTEND WAJIB BUILD ULANG <<<
>>> DUA TABEL BARU DIBUAT OTOMATIS SAAT BACKEND NYALA <<<

BERKAS BERUBAH (9)
  backend/utils/gudang.js             BERKAS BARU — daftar gudang
  backend/utils/sohFactory.js         BERKAS BARU — pabrik route SOH
  backend/server.js                   daftarkan dua route baru
  backend/routes/barangkeluar.js      pemeta tabel dari daftar
  backend/routes/detailpart.js        idem
  backend/routes/jadwalservice.js     idem
  backend/routes/hakedit.js           dua hak akses baru
  frontend/src/views/SukuCadang.vue   empat tab + stok gudang aktif
  frontend/src/services/api.js        kunci hak akses per gudang

>>> DUA BERKAS BARU ADA DI backend/utils/, BUKAN backend/routes/ <<<
>>> api.js ada di frontend/src/services/ <<<


================================================================
1. DIBUAT SEPERTI MSF 1 DAN MSF 2 — SESUAI PERMINTAAN ANDA
================================================================
Keduanya gudang penuh: punya tab sendiri, Stok (SOH) sendiri, Barang
Masuk/Keluar, History, Pembatalan, dan hak akses sendiri.

Tabelnya:
    soh_gudang_klawas
    soh_gudang_exbkpl

Titik akhirnya:
    /api/soh-gudang-klawas
    /api/soh-gudang-exbkpl

Keduanya dibuat otomatis saat backend nyala. Periksa log:

    [gudang] Gudang Klawas siap di /api/soh-gudang-klawas (tabel soh_gudang_klawas)
    [gudang] Gudang Exbkpl siap di /api/soh-gudang-exbkpl (tabel soh_gudang_exbkpl)


================================================
2. SATU DAFTAR, BUKAN PERCABANGAN DI 282 TEMPAT
================================================
Saya tidak menyalin pola dua-gudang. Alasannya bukan kerapian —
melainkan ini:

    kode === 'MSF1' ? 'soh_gudang_msf_1' : 'soh_gudang_msf'

Bentuk itu ada di beberapa tempat, dan ia melempar SEMUA yang bukan
MSF1 ke MSF 2. Klawas dan Exbkpl akan jatuh ke sana: stoknya dipotong
dari gudang yang salah, TANPA galat apa pun yang menandainya.

Tiga tempat seperti itu ditemukan dan diarahkan ke daftar:
    barangkeluar.js   (potongan stok saat barang keluar)
    detailpart.js     (pendaftaran part ke gudang)
    jadwalservice.js  (potongan stok paket PM)

Menambah gudang kelima nanti cukup satu baris di utils/gudang.js.


================================================
3. MSF 1 & MSF 2 SENGAJA TIDAK DISENTUH
================================================
Gudang baru memakai "pabrik" route (utils/sohFactory.js) — satu berkas
yang dipakai berdua, dibedakan nama tabelnya.

MSF 1 dan MSF 2 tetap memakai berkas lamanya. Memindahkan keduanya ke
pabrik memang lebih rapi, tapi risikonya menimpa dua gudang yang
dipakai setiap hari demi menambah dua yang belum ada isinya. Itu bukan
pertukaran yang sepadan.


================================================
4. SATU PENINGGALAN YANG KETEMU SAMBIL LALU
================================================
sohgudangmsf.js dan sohgudangmsf1.js seharusnya kembar. Ternyata sudah
MENYIMPANG 18 baris.

MSF 2 punya perbaikan pencarian yang TIDAK pernah ikut ke MSF 1:
Part_Number dicocokkan dari awal kata ("P" → "P5" → "P552020TM"), dan
hasilnya mendahulukan yang cocok persis.

Pabriknya saya salin dari MSF 2 — yang lebih baik. Akibatnya: gudang
BARU akan terasa lebih enak dicari daripada MSF 1.

Itu bukan kesengajaan. Saya menyebutnya karena kalau nanti Anda merasa
"kok cari part di MSF 1 lebih susah", sebabnya ini — dan perbaikannya
sebaiknya dikerjakan tersendiri, bukan diselipkan di tengah pekerjaan
ini.


================================================
5. HAK AKSES
================================================
Dua baris baru muncul di Master Data › Hak Akses Menu:

    🏭 Gudang Klawas
    🏭 Gudang Exbkpl

HAK BAWAANNYA DISAMAKAN dengan MSF 1/MSF 2, supaya orang yang sudah
boleh membuka gudang lama tidak perlu diatur ulang satu per satu.

Kalau keduanya seharusnya hanya boleh dibuka sebagian orang, atur di
sana — barisnya sudah ada begitu backend nyala.

CATATAN PENTING: kunci hak akses kini dibaca dari daftar, bukan
percabangan if. Gudang yang namanya tidak ada di daftar mengembalikan
kunci KOSONG — dan kosong berarti "tanpa pembatasan". Jadi gudang yang
terlewat akan terbuka untuk semua orang tanpa ada yang menyadarinya.
Itu sebabnya daftarnya ditaruh di satu tempat.


================================================
6. YANG BELUM SAMA DENGAN MSF 1/MSF 2
================================================
>>> Ini perlu Anda ketahui sebelum memakainya. <<<

KOLOM "STOK MSF1" DAN "STOK MSF2" di form Barang Keluar TETAP hanya
menampilkan dua gudang itu. Untuk Klawas/Exbkpl keduanya "—".

Yang dipakai memutuskan cukup-tidaknya stok BUKAN kolom itu, melainkan
stok gudang yang sedang dibuka — dan itu sudah benar untuk keempat
gudang (kolom "Sisa" dan penjaga v607 memakainya).

Jadi Barang Keluar dari Klawas BEKERJA dengan benar; yang belum ada
hanya dua kolom pembanding di tabelnya.

Menambah dua kolom lagi akan membuat tabelnya delapan kolom stok dan
mengulang persoalan yang sama pada gudang berikutnya. Yang benar:
mengganti empat kolom itu dengan satu kolom "Stok gudang ini" plus satu
kolom "Ada di gudang lain". Itu pekerjaan tersendiri — sebutkan saja
kalau perlu.


================================================
7. CARA PASANG
================================================
1. Extract ke folder yang MEMUAT folder Digitalisasi_3_3, lalu timpa.
   Perhatikan letak berkas baru di backend/utils/.
2. RESTART BACKEND. Periksa dua baris [gudang] di log.
3. cd frontend && npm run build
4. Ctrl+Shift+R di peramban.

5. UJI:
   a. Suku Cadang — sekarang ada EMPAT tab gudang.
   b. Buka Gudang Klawas › Stok (SOH). Kosong, dan itu benar.
   c. Barang Masuk di Klawas: tambahkan satu part. Stoknya muncul di
      SOH Klawas, dan TIDAK muncul di SOH gudang lain.
   d. Barang Keluar dari Klawas: part tadi harus muncul di daftar
      saran, kolom Sisa terisi, dan stoknya berkurang setelah simpan.
   e. Periksa SOH MSF 1 dan MSF 2 — keduanya TIDAK boleh berubah sama
      sekali oleh langkah (c) dan (d).

>>> LANGKAH 5e YANG PALING PENTING. Kalau stok MSF 2 ikut berubah,
    berarti masih ada percabangan dua-arah yang saya lewatkan. <<<


================================================
YANG SUDAH DIPERIKSA
================================================
- Daftar gudang diuji terhadap 15 keadaan: empat gudang dengan tabel
  dan endpoint yang semuanya berbeda; pemetaan dari kode, dari nama,
  dari huruf kecil, dan dari nama berspasi.
- Dibuktikan cara lama memetakan KLAWAS dan EXBKPL ke soh_gudang_msf —
  sebab yang diperbaiki.
- Kolom Gudang kosong diuji tetap jatuh ke MSF 2, sama seperti
  sebelumnya, supaya riwayat lama tidak berpindah gudang.
- Kunci hak akses diuji: gudang baru punya kunci; nama tak dikenal
  mengembalikan '' (tanpa pembatasan).
- Tujuh berkas backend lolos `node --check`
- 41 berkas .vue lolos @vue/compiler-sfc — 0 bermasalah
- Pemeriksa impor (v579): 0 bermasalah
- `vite build` DIJALANKAN dan BERHASIL (14,3 detik)


================================================
YANG BELUM SAYA UJI
================================================
Tidak ada database di tempat saya bekerja. Kedua tabel baru belum
pernah dibuat sungguhan, dan pabrik route-nya belum pernah melayani
satu permintaan pun.

Pabrik itu hasil penyalinan otomatis dari berkas yang sudah berjalan,
dengan nama tabel dijadikan peubah. Saya memeriksa setiap tempat nama
tabelnya muncul (22 tempat) dan memastikan tidak ada yang tertinggal di
dalam string yang tidak diproses — tapi lolos `node --check` bukan
jaminan ia berjalan benar.

LANGKAH 5c ADALAH UJI SUNGGUHAN PERTAMANYA. Kalau menambah part di
Klawas gagal dengan pesan tabel tidak ditemukan, kirimkan pesannya —
berarti ada satu nama tabel yang tidak ikut menjadi peubah.
