UPDATE v549: Izin Bypass Pengecekan Awal per Unit (BD bisa ditutup meski Pengecekan Awal belum lengkap, tapi hanya untuk unit yang didaftarkan) >>> BACKEND BERUBAH — WAJIB RESTART <<< >>> FRONTEND WAJIB BUILD ULANG <<< >>> SATU TABEL BARU DIBUAT OTOMATIS SAAT BACKEND NYALA <<< BERKAS BERUBAH (10) backend/routes/masterdata.js tabel + 3 endpoint backend/routes/hakedit.js kunci hak baru backend/routes/maintenancerecord.js jejak di log server frontend/src/services/api.js ATURANNYA ADA DI SINI frontend/src/views/IzinBypassPengecekan.vue BERKAS BARU frontend/src/router/index.js route layar baru frontend/src/App.vue menu Master Data frontend/src/views/MonitoringUnit.vue Close BD + Edit Pelaporan frontend/src/views/TiketPerbaikan.vue Close Tiket frontend/src/views/TodoList.vue popup part di Outstanding TABEL_IZIN_BYPASS_PENGECEKAN.sql TIDAK WAJIB (lihat bag. 9) ================================================================ BACA INI DULU — SATU AKIBAT YANG LANGSUNG TERASA ================================================================ DAFTAR UNITNYA BERAWAL KOSONG. Sampai ada unit yang didaftarkan, TIDAK ADA SATU PUN BD yang bisa ditutup tanpa Pengecekan Awal lengkap — termasuk oleh akun berakses penuh (31196), yang sebelum update ini bisa menutup apa saja. Itu memang arti "izin per unit", bukan kelalaian. Tapi kalau Anda memasangnya tanpa tahu, gejalanya akan terlihat persis seperti fitur yang rusak: tombol Simpan & Close mati di layar yang kemarin masih bisa dipakai. Langkah pertama setelah memasang ada di bagian 8. ================================================ 1. YANG DIMINTA, DAN KENAPA BENTUKNYA JADI BEGINI ================================================ Permintaannya: Close BD bisa dilanjutkan walaupun laporan Pengecekan Awal belum ada, dengan izin per unit seperti Izin Bypass HM. Bagian "bisa dilanjutkan" sebenarnya SUDAH ADA sejak v406 — tapi hanya untuk satu akun, dan tanpa batas apa pun. Di tangkapan layar Anda kalimatnya berbunyi: "Akun ini berwenang menutup BD tanpa itu." Itulah persoalannya. Wewenangnya melekat pada ORANG, bukan pada keadaan. Sekali akun itu dipakai, syarat Pengecekan Awal praktis berhenti berlaku untuk SELURUH armada, selamanya, tanpa ada yang tercatat di mana pun. Padahal alasan melewatinya selalu melekat pada SATU unit tertentu: BD lama yang terlanjur berjalan sebelum aplikasi dipakai, unit yang kondisinya membuat LOTO tidak bisa dipasang, unit yang sedang di luar area. Itu keadaan pada unit, bukan sifat orangnya. Jadi yang ditambahkan bukan "kemampuan melewati" — itu sudah ada — melainkan BATASNYA. ================================================ 2. DUA SYARAT, BUKAN SATU ================================================ Persis pola Izin Bypass HM (v487): SIAPA hak 'aksi:bypass-pengecekan' di Master Data > Hak Akses Menu (NIK berakses penuh otomatis punya) UNIT MANA terdaftar dan masih berlaku di Master Data > Izin Bypass Pengecekan Awal DUA-DUANYA HARUS TERPENUHI. Salah satu saja tidak cukup. Kenapa hak saja tidak cukup: sudah dijelaskan di bagian 1. Kenapa daftar unit saja tidak cukup: unit yang didaftarkan bisa dikerjakan siapa pun yang membuka layarnya. Kalau haknya tidak ikut diperiksa, mendaftarkan satu unit berarti mengizinkan SEMUA orang menutup BD unit itu tanpa bukti keselamatan. ================================================ 3. DUA KEADAAN PENOLAKAN, DUA KALIMAT BERBEDA ================================================ Akun yang SUDAH berhak tapi unitnya belum didaftarkan akan melihat penolakan yang — kalau tidak dibedakan — sama persis dengan penolakan untuk akun yang memang tidak berwenang. Tidak ada cara menebak bahwa yang kurang justru pendaftaran unitnya. Orangnya akan mencari kesalahan di tempat yang salah: menyalahkan haknya, meminta hak baru, atau menyerah dan mengisi pengecekan seadanya. Jadi di bawah spanduk merah muncul baris kuning tersendiri: ℹ️ Akun Anda berhak melewati syarat Pengecekan Awal, tapi izinnya diberikan per unit — DT3010-63 belum terdaftar (atau izinnya sudah berakhir) di Master Data › Izin Bypass Pengecekan Awal. Warnanya sengaja dibedakan dari penolakan di atasnya: ini bukan larangan, melainkan petunjuk apa yang harus dikerjakan supaya bisa. KALIMAT INI TIDAK MUNCUL untuk akun yang tidak berhak. Menawarkan cara mendaftarkan unit kepada orang yang tetap tidak akan bisa memakainya hanya memindahkan kebingungan, dan menghasilkan permintaan pendaftaran unit yang sebenarnya tidak menyelesaikan apa-apa. ================================================ 4. EMPAT LAYAR, BUKAN DUA ================================================ Saya kira aturan ini dipakai dua layar. Ternyata empat: MonitoringUnit.vue Close BD (menutup BD) MonitoringUnit.vue Edit Pelaporan (menyimpan part BARU) TiketPerbaikan.vue Close Tiket (menutup BD yang sama) TodoList.vue Semua Outstanding (menyimpan part BARU) TodoList nyaris terlewat. Kalau terlewat, layar itu jadi jalan pintas yang membatalkan aturannya — dan orang akan memakai jalan pintas itu justru karena lebih cepat. SATU PERBEDAAN DI TODOLIST YANG PERLU DISEBUT Di tiga layar lain, daftar izin dimuat saat halaman dibuka dan disegarkan lagi saat modal dibuka — jadi saat tombol ditekan, daftarnya sudah ada. Popup di TodoList bisa jadi layar PERTAMA yang menyentuh aturan ini dalam satu sesi. Jadi di sana daftarnya DITUNGGU (await) sebelum keputusan diambil. Kalau tidak ditunggu: daftar yang belum termuat berarti TOLAK, sehingga akun yang sebenarnya berhak akan ditolak pada percobaan pertama lalu berhasil pada percobaan kedua. Itu jenis kegagalan yang paling sulit dipercaya orang lain, karena tidak bisa diulang. ================================================ 5. DAFTAR GAGAL DIMUAT = TOLAK, BUKAN IZINKAN SEMUA ================================================ Kalau permintaan daftar izin gagal — backend mati, jaringan putus, backend belum direstart sehingga endpoint-nya belum ada — jawabannya TIDAK ADA yang diizinkan. Untuk syarat keselamatan, ragu-ragu harus berarti tolak. Kebalikannya (anggap semua boleh saat daftarnya tidak terbaca) berarti satu gangguan jaringan sesaat membuka seluruh armada tanpa ada yang sadar. Dan kegagalannya TIDAK MENGUNCI: penanda "sudah termuat" sengaja tidak disetel saat gagal, jadi pembukaan modal berikutnya mencoba lagi — bukan terkunci kosong sampai halaman dimuat ulang. BENTUK JAWABAN DIPERIKSA, BUKAN DIANGGAP BENAR. Pola `r.data?.data || []` menelan segala jawaban tak terduga menjadi daftar kosong, dan di layar itu terbaca persis seperti "memang belum ada unit yang diizinkan". Backend yang belum direstart menghasilkan tepat keadaan itu — tanpa galat, tanpa 404. Jadi jawaban yang bentuknya salah diperlakukan sebagai KEGAGALAN dan disebutkan di console. ================================================ 6. SERVER MENCATAT, TIDAK MENOLAK — DAN INI DISENGAJA ================================================ Sampai v548 TIDAK ADA penjaga Pengecekan Awal di server sama sekali. Penjaganya murni di layar. Saya tidak menambahkannya di update ini. ALASANNYA Menambahkan penjaga di server berarti menegakkan syarat Pengecekan Awal pada SEMUA jalur yang menutup BD, bukan hanya yang lewat layar Close. Jalur lain yang selama ini sah akan ikut terblokir: - kartu shift yang menulis Stop_Perbaikan - impor Excel - Close Tiket dari TiketPerbaikan - jalur mana pun yang belum saya petakan Itu pembatasan BARU yang tidak Anda minta, dan akibatnya baru terasa di lapangan setelah dipasang. Kalau penjaga server memang diinginkan, itu perubahan tersendiri beserta pendataan jalur mana saja yang terdampak — bilang saja. YANG DITAMBAHKAN: JEJAKNYA Sebelumnya pelewatan hanya dicatat dengan console.warn di peramban. Console peramban hilang begitu tab ditutup — jadi pertanyaan "siapa yang menutup BD ini tanpa pengecekan, kapan, dan unit apa" tidak pernah bisa dijawab setelahnya. Sekarang layar mengirim penanda `bypass_pengecekan: true` beserta daftar apa yang kurang, dan server menuliskannya ke log: [bypass-pengecekan] NIK 31196 menutup BD #4821 (DT3010-63) tanpa Pengecekan Awal lengkap — kurang: Foto Loto, Foto Wheel Chock Ini pelonggaran aturan keselamatan — justru jenis kejadian yang paling perlu bisa ditelusuri. CATATAN: `bypass_pengecekan` dan `bypass_kurang` BUKAN kolom tabel. Handler PUT menyaring badan permintaan dengan `COLS.filter(c => c in req.body)`, jadi kunci di luar daftar kolom diabaikan dengan sendirinya. ================================================ 7. KENAPA TABELNYA TERPISAH DARI hm_bypass_unit ================================================ Kolomnya kembar persis. Menggabungkannya jadi satu tabel dengan kolom "jenis" memang lebih ringkas. Tapi itu berarti satu centang mengendalikan DUA pengaman yang tidak ada hubungannya. Mencabut izin HM untuk satu unit akan ikut mencabut izin pengecekannya — atau lebih buruk, memberi izin HM diam-diam memberi izin melewati LOTO. HM yang mundur adalah kesalahan DATA. Pengecekan Awal yang kosong adalah pekerjaan keselamatan yang belum dilakukan, atau sudah dilakukan tapi tidak terbukti. Dua hal itu tidak boleh dikendalikan satu saklar. TAPI LOGIKANYA SATU Endpoint keduanya sekarang dilayani fungsi yang SAMA (daftarIzin, daftarIzinAktif, simpanIzin di masterdata.js). Sampai v548 hanya ada satu daftar, jadi logikanya ditulis langsung di dalam endpoint-nya. Begitu ada yang kedua, menyalinnya berarti dua salinan aturan "izin sudah kedaluwarsa atau belum", "unit ini terdaftar atau tidak", dan "menyimpan itu menyamakan, bukan menambah". Salinan yang disalin akan berbeda cepat atau lambat, dan bedanya baru ketahuan saat satu layar mengizinkan apa yang dilarang layar lain. PERUBAHAN INI MENYENTUH JALUR BYPASS HM YANG SUDAH BEKERJA. Perilakunya tidak diubah sama sekali — hanya letak kodenya. Tapi karena ia jalur yang sudah berjalan, ada baiknya diuji sekali setelah memasang (bagian 10, langkah 6). ENDPOINT BARU: /aktif Layar admin memakai /daftar — seluruh unit beserta keadaan izinnya. Aplikasi sehari-hari memakai /aktif — hanya unit yang izinnya masih berlaku, tanpa tipe, model, dan satker. Bedanya penting: layar Close BD cuma perlu menjawab satu pertanyaan ya/tidak, dan mengirim 551 baris lengkap untuk itu adalah muatan yang tidak perlu ada di setiap pembukaan halaman. Yang kedaluwarsa DIBUANG di /aktif, bukan dikirim dengan penanda. Layar yang menerimanya tidak punya urusan lain dengan izin yang sudah berakhir, dan mengirimkannya hanya menambah satu cara untuk salah. ================================================ 8. LANGKAH PERTAMA SETELAH MEMASANG ================================================ A. BERI HAKNYA Master Data > Hak Akses Menu Cari baris: 🦺 Tutup BD tanpa Pengecekan Awal lengkap Bawaannya TERTUTUP untuk SEMUA jenis akun. Itu disengaja: yang dilewati bukan kesalahan pencatatan melainkan bukti keselamatan, dan sebuah update yang dipasang tidak boleh memberi siapa pun kemampuan itu. Harus ada yang memutuskannya. NIK 31196 tidak perlu saklar ini — sudah otomatis. >>> INI KEPUTUSAN ANDA: apakah Supervisor ikut diberi, atau cukup akun berakses penuh saja seperti perilaku sebelumnya. B. DAFTARKAN UNITNYA Master Data > Izin Bypass Pengecekan Awal Centang unitnya, isi Alasan dan Berlaku sampai, tekan Simpan Daftar. Untuk kasus di tangkapan layar Anda: centang DT3010-63. MENYIMPAN ITU MENYAMAKAN, BUKAN MENAMBAHKAN. Unit yang centangnya dilepas akan DICABUT izinnya. Konsekuensinya ditampilkan SEBELUM ditekan — ada baris "N akan DICABUT izinnya", dan jumlah centang yang sedang tersembunyi oleh saringan ikut disebutkan. ISI "BERLAKU SAMPAI" BILA MEMUNGKINKAN. Dikosongkan = tanpa batas waktu. Untuk izin keselamatan itu sebaiknya dihindari: izin yang dibuka untuk satu kejadian lalu lupa ditutup tidak akan ada yang menemukan — tidak ada layar yang menampilkan "izin yang masih terbuka sejak tiga bulan lalu". Kueri untuk mencarinya ada di TABEL_IZIN_BYPASS_PENGECEKAN.sql. PERUBAHAN LANGSUNG TERASA. Daftar izin disimpan di memori peramban dan dibaca layar Close BD tanpa bertanya lagi ke server. Menyimpan di layar admin membuang simpanan itu, dan setiap modal Close yang dibuka akan mengambil daftar terbaru. Jadi izin yang baru DICABUT langsung berhenti berlaku — tidak menunggu halaman dimuat ulang. ================================================ 9. BERKAS SQL TIDAK WAJIB DIJALANKAN ================================================ Tabel pengecekan_bypass_unit dibuat sendiri saat backend menyala, dan dipastikan lagi setiap kali endpoint izin dipanggil. TABEL_IZIN_BYPASS_PENGECEKAN.sql hanya diperlukan kalau backend tidak bisa direstart sekarang, atau Anda ingin mendaftarkan unit lewat SQL. Isinya juga memuat kueri untuk melihat izin yang masih terbuka. ================================================ 10. CARA PASANG ================================================ 1. Extract ke folder yang MEMUAT folder Digitalisasi_3_3, lalu timpa. >>> App.vue ada di frontend/src/, BUKAN frontend/src/views/ <<< >>> api.js WAJIB ikut ditimpa — aturannya ada di situ <<< 2. RESTART BACKEND. 3. cd frontend && npm run build 4. Ctrl+Shift+R di peramban. 5. UJI JALUR BARUNYA: a. Buka Close BD pada unit yang BELUM didaftarkan, dengan akun yang SUDAH diberi hak. Harus muncul spanduk merah + baris kuning yang menyebut unitnya belum terdaftar. b. Daftarkan unit itu di Master Data > Izin Bypass Pengecekan Awal. c. Buka lagi Close BD-nya TANPA memuat ulang halaman. Spanduknya harus berubah jadi kuning "dilewati", dan Simpan & Close hidup. d. Tutup BD-nya. Periksa log backend, harus ada baris [bypass-pengecekan]. 6. UJI JALUR LAMANYA (karena kodenya ikut dipindah): Master Data > Izin Bypass HM per Unit harus tetap memuat daftar unit dan tetap bisa menyimpan. Kalau layarnya kosong, itu tanda backend belum direstart. ================================================ YANG SUDAH DIPERIKSA ================================================ - Keputusan izin diuji terhadap 13 keadaan, semuanya benar: berhak + unit terdaftar LOLOS berhak + unit TIDAK terdaftar ditolak, sebab disebut berhak + ejaan beda huruf besar/spasi LOLOS (dinormalkan) TIDAK berhak + unit terdaftar ditolak TIDAK berhak + tidak terdaftar ditolak berhak + unit kosong / null ditolak — pemanggil yang lupa menyertakan unit TIDAK mendapat wewenang tanpa batas berhak + daftar izin kosong ditolak daftar GAGAL dimuat ditolak, bukan izinkan semua izin kedaluwarsa ditolak (disaring server, tidak terkirim) Dan kalimat sebab: muncul untuk yang berhak-tapi-belum-terdaftar, KOSONG untuk yang tidak berhak, KOSONG untuk yang memang boleh. - Penyimpanan daftar diuji terhadap database palsu, 7 keadaan: tambah pertama tersimpan tambah kedua yang lama tidak ganda lepas satu centang DICABUT (menyamakan) unit tidak dikenal ditolak & disebut namanya, tidak ikut tersimpan duplikat 'rt-032' / ' RT-032 ' / 'RT-032' lebur jadi SATU baris, bukan tiga yang bentrok dengan UNIQUE KEY daftar kosong seluruhnya dicabut - masterdata.js, hakedit.js, dan maintenancerecord.js lolos `node --check` - 40 berkas .vue lolos @vue/compiler-sfc: parse, compileScript, compileTemplate — 0 bermasalah - `vite build` DIJALANKAN dan BERHASIL (15,4 detik) - Seluruh pemanggilan bolehLewatiPengecekan() ditelusuri ulang setelah tanda tangannya berubah. Fungsi yang dulu dipanggil tanpa argumen sekarang WAJIB menyertakan unit; pemanggilan yang terlewat akan menjawab TOLAK, bukan diam-diam mengizinkan. Empat pemanggil ditemukan dan keempatnya sudah disesuaikan. - Urutan route diperiksa: /bypass-pengecekan/* berada DI ATAS route generik '/:type' dan '/:type/:id'. Kalau di bawah, ia akan tertangkap sebagai type='bypass-pengecekan', id='daftar' dan membalas daftar KOSONG tanpa galat — persis gejala v489. ================================================ YANG BELUM SAYA UJI ================================================ Tidak ada MySQL di tempat saya bekerja. CREATE TABLE dan seluruh query terhadap pengecekan_bypass_unit belum pernah dijalankan terhadap database sungguhan — yang dipastikan baru sintaks dan bentuk querynya. Langkah 5 dan 6 di bagian 10 ada persis untuk membuktikannya dalam dua menit. Satu hal lagi yang tidak bisa saya uji sendiri: apakah ada jalur lain di aplikasi ini yang menutup BD tanpa melewati keempat layar di bagian 4. Kalau ada, jalur itu tidak terkena aturan ini sama sekali — lihat bagian 6.