Files
mylesen/docs/audit-mylesen.md
2026-05-14 16:27:38 +08:00

27 KiB

Audit Teknikal: Sistem myLesen

Tarikh Audit: 18 Mac 2026 Juruaudit: Claude Code (berdasarkan pembacaan kod semasa) Skop: Keseluruhan projek mylesen


A. Ringkasan Sistem Semasa

A1. Maklumat Projek

Butiran Nilai
Nama Sistem myLesen — Sistem Pengurusan Lesen Penjaja
Organisasi MBIP (Majlis Bandaraya Iskandar Puteri)
Framework Laravel 11.9 / PHP 8.2
Database Utama MySQL (mylesen)
Database Kedua MySQL (sistemutama) via second_mysql connection — sistem EPBT
Frontend Blade + Tailwind CSS + Alpine.js + jQuery
Penjanaan Dokumen PHPOffice/PHPWord (output .docx, bukan PDF)
Authentication Laravel Breeze (session-based)
API Luar http://epbt.mbip.gov.my/... (jana bil pelbagai)
API Chrome Extension Tiada — belum dibina

A2. Statistik Kod

Komponen Bilangan Catatan
Controllers (aktif) 15 termasuk auth controllers
Controllers (dalam asal/) 4 fail backup lama — tidak digunakan
Models 38 11 EPBT (second_mysql), 4 PbtPay (stub kosong)
Views (blade) ~104 termasuk asal/, -ori.blade.php, fail ujian
Migrations 39 1 ada typo nama fail
Routes (web) ~71 + auth routes tiada routes/api.php
Middleware custom 2 AdminMiddleware, KakitanganMiddleware
Policies 2 kebanyakan method masih empty stub
FormRequest classes 2 ProfileUpdateRequest, LoginRequest sahaja
Tema Admin dipasang 4 AdminLTE, KaiAdmin, Corporate UI, Kapella — hanya 1 digunakan

A3. Seni Bina Semasa

[Browser]
    |
    ↓ HTTP (web.php routes)
[Laravel Controllers]
    |                    |
    ↓                    ↓
[MySQL: mylesen]     [MySQL: sistemutama/EPBT]   [HTTP: epbt.mbip.gov.my]
(data permohonan)    (bil, resit, akaun lesen)   (jana bil API)

Autentikasi & Kebenaran:

  • role column dalam jadual users — string (bukan enum)
  • 2 middleware: admin (super sahaja), kakitangan (semua staf)
  • 6 Gate definitions dalam AppServiceProvider
  • 2 Policy classes (mostly stubs)
  • Tiada konsistensi antara penggunaan Gate vs Policy

Document Streaming:

  • Semua dokumen uploaded dilindungi — streaming melalui controller, bukan URL terus

A4. Aliran Status Semasa (dari pembacaan kod)

Status permohonan disimpan dalam status_progress (string) dan status_mesyuarat (string) dalam jadual lesen_penjajas.

[PEMOHON HANTAR BORANG]
         |
         ↓ hantar_permohonan()
   ┌─────────────┐
   │    BARU     │ ← Queue PT (penjaja-baru)
   └─────────────┘
         |
         ↓ simpanWangProses() — PT masukkan No. Bil EPBT
   ┌────────────────────────────┐
   │ MENUNGGU BAYARAN PROSES    │ ← Queue PT (penjaja-proses)
   └────────────────────────────┘
         |
         ↓ Auto: bila resit ditemui dalam EPBT (EpbtEcasResit)
   ┌────────────────────────────┐
   │ SEMAKAN BAYARAN PROSES     │ ← Queue PT (penjaja-bukafail)
   └────────────────────────────┘
         |
         ↓ hantarPPK() — PT hantar ke IK
   ┌─────────────────┐
   │  LAWATAN TAPAK  │ ← Queue IK (penjaja-pemeriksaan)
   └─────────────────┘
         |
         ↓ simpanUlasan() — IK lengkap borang ulasan
   ┌─────────────────────┐
   │  ULASAN PEGAWAI     │ ← Queue PP (penjaja-cadangan)
   └─────────────────────┘
         |
         ↓ simpan_cadangan() — PP tulis cadangan
   ┌─────────────────────┐
   │  ULASAN PENGARAH    │ ← Queue Pengarah (penjaja-ulasan-cadangan)
   └─────────────────────┘
         |
         ↓ simpan_ulasan_cadangan() — Pengarah setuju bawa ke mesyuarat
   ┌──────────────────────────────────┐
   │  SOKONG DIBAWA KE MESYUARAT      │
   └──────────────────────────────────┘
         |
         ↓ sahkanSenarai() — PT masukkan dalam agenda mesyuarat
   ┌────────────────────────────────────────┐
   │  MENUNGGU KEPUTUSAN MESYUARAT          │
   └────────────────────────────────────────┘
         |
         ↓ simpanKeputusanMesyuarat()
   ┌──────────────────────┐
   │  KEPUTUSAN DITERIMA  │
   └──────────────────────┘
         |
         ├── status_mesyuarat = 'diluluskan' → PT daftar lesen
         ├── status_mesyuarat = 'ditolak'    → Tamat
         └── status_mesyuarat = 'ditangguhkan' → Tunggu mesyuarat berikutnya

Gap dalam status flow (isu penting):

  1. Tiada status terminal "LESEN DIKELUARKAN" atau "SELESAI" — status_progress kekal 'keputusan diperolehi' walaupun lesen sudah dikeluarkan
  2. senarai_pt_daftarlesen (queue pendaftaran no lesen) menggunakan status ulasan pegawai/pengarah/sokong dengan whereNull('no_akaun_lesen') — ini adalah aliran berasingan tanpa status dedicated
  3. Bayaran lesen (hutang lesen) dikesan melalui whereNotNull('no_akaun_lesen')->whereNull('lesen_no_resit') — tiada status formal untuk ini
  4. Apabila Pengarah tangguhkan cadangan (bukan ke mesyuarat), status kembali ke 'lawatan tapak' tetapi borang IK baru tidak dicipta secara automatik

B. Modul yang Masih Relevan

B1. Permohonan Lesen Penjaja (Pemohon/Awam)

Controller App\Http\Controllers\PenjajaController
Routes Utama /mohon-penjaja, /simpan-mohon-penjaja, /mohon_edit/{id}, /mohon_hapus/{id}, /mohon_papar/{id}, /mohon_hantar
Views Utama penjaja/mohon.blade.php, penjaja/mohon_papar.blade.php
Dashboard Pemohon dashboard.blade.php (route: /dashboard) → PenjajaController@list
Status AKTIF

B2. Permohonan Lesen Penjaja (Admin — Mohon Atas Nama)

Controller App\Http\Controllers\Admin\PenjajaController
Routes Utama /mohon-penjaja-admin, /simpan-mohon-penjaja-admin
Views Utama admin/penjaja/mohon_baru.blade.php
Catatan Lompat terus ke status lawatan tapak — fast-track untuk admin
Status AKTIF

B3. PT Workflow (Pembantu Tadbir)

Controllers Admin\PenjajaController (senarai), Admin\PtPenjajaController (tindakan)
Queue Screens /penjaja-baru (baru), /penjaja-proses (tunggu bayar), /penjaja-bukafail (bayar disahkan), /penjaja-daftarlesen (daftar lesen)
Tindakan Simpan Wang Proses, Simpan No Fail, Hantar ke IK, Urus Mesyuarat, Cetak Lampiran B
Status AKTIF

B4. IK Workflow (Inspektor Kesihatan)

Controller Admin\IkPenjajaController
Routes /penjaja-pemeriksaan, /ik-simpan-lokasi, /ik-simpan-ulasan
Model Utama BorangUlasanIk (30+ fields, 3 foto lawatan tapak)
Status AKTIF

B5. PP & Pengarah Workflow

Controller Admin\PegawaiPenjajaController
Routes /penjaja-cadangan, /penjaja-ulasan-cadangan, /pegawai-simpan-cadangan, /pegawai-simpan-ulasan-cadangan
Model Utama UlasanPegawai (gabungkan cadangan PP dan ulasan Pengarah dalam satu model)
Status AKTIF

B6. Mesyuarat Pelesenan + Lampiran B

Controller Admin\PtPenjajaController
Routes /senaraimesyuarat, /senaraibawamesyuarat/{id}, /simpan_mesyuarat, /sahkan_senarai, /simpan_keputusan_mesyuarat, /cetak_lampiran_b
Model Utama MesyuaratPelesenan + pivot mesyuarat_pelesenan_lesen_penjajas
Output Export landscape .docx menggunakan PHPWord, dikelompok mengikut kawasan
Pivot Data by_law, kodlesen, kadar_lesen, kadar_sampah, kadar_sewa_petak, kadar_patil, keputusan_mesyuarat
Status AKTIF

B7. Bil Proses + EPBT Integration (Mode Manual)

Controller Admin\PtPenjajaController::simpanWangProses()
Cara Kerja PT masukkan No. Bil dari EPBT secara manual → sistem baca dari second_mysql untuk dapatkan butiran bil → semak EpbtEcasResit untuk resit bayaran
Model BilPelbagai, BilPelbagaiItem, EpbtBpBil, EpbtEcasResit
Status AKTIF (mode manual)

B8. Bil Auto-Jana (EPBT API — Mode Automatik)

Controller BilPelbagaiController::janaBil()
Cara Kerja HTTP POST ke EPBT API → dapat accountNo → simpan dalam BilPelbagaiApi
Status Sekarang KOD SIAP DITULIS tetapi ROUTE DITUKAR KE doNothing()
Catatan Logik API lengkap, tetapi dimatikan sengaja — mungkin belum disahkan untuk production

B9. Semak Bayaran Lesen (Hutang Lesen)

Controller Admin\DashboardController::senaraiLesenBelumBayar() + semakBayaranLesen()
Routes /penjaja-hutang-lesen, /penjaja-hutang-lesen-semak
Model GrabResitLesen (log batch semakan), EpbtEcasResit
Status AKTIF

B10. Dashboard Admin

Controller Admin\DashboardController::utama()
Route /dashmin/{ctahun?}
Kandungan Count per status, filter tahun, semakan bayaran inline
Isu N+1 query: semua rekod 'menunggu bayaran proses' di-query EPBT setiap page load
Status AKTIF (dengan isu prestasi)

B11. Cetakan (IK + Cadangan Pegawai)

Controller Admin\CetakanPenjajaController
Routes /penjaja-cetak-pemeriksaan/{id}/{ik_id}, /penjaja-cetak-cadangan-pegawai/{id}/{ik_id}
Output Download .docx menggunakan PHPWord
Status AKTIF

B12. Pengurusan Admin

Controller Admin\PengurusanAdminController
Routes /lantikan_admin, /cari_admin, /admin/users/{id}/update-role, /rem-admin/{nokp}
Status AKTIF
Controllers Admin\PengumumanController, Admin\GambarCarouselController
Akses Role super sahaja (middleware admin)
Status AKTIF

B14. Profile + Document Streaming

Controller ProfileController
Routes /profile, /profil/stream/{filename}, /dokumen/stream/{id}/{filename}, /ik/stream/{id}/{filename}
Status AKTIF

B15. Data AJAX (Cascading Dropdowns)

Controller DataController
Routes /get_kawasan, /get_taman, /get_jalan, /get_penempatan
Status AKTIF

B16. Semakan EPBT Pelanggan

Controller Admin\PtPenjajaController::searchPelanggan()
Route /get-bil
Model EpbtPelanggan
Status AKTIF

C. Modul/Fail yang Obsolete atau Mencurigakan

C1. Fail Keselamatan — TINDAKAN SEGERA DIPERLUKAN

Fail Isu Tindakan
public/test_curl.php Fail ujian dengan IP server terus (1.9.131.236), endpoint EPBT nyata, client_key = 'MPJBT' hardcoded, dan struktur data pelanggan nyata. Boleh diakses oleh sesiapa tanpa sebarang auth kerana berada dalam folder public/. PADAM SEGERA
mylesen(2).sql Backup database penuh dalam root projek. Mengandungi data sensitif. Boleh terdedah jika repo dikongsi. PINDAH KELUAR dari projek

C2. Fail Backup / Lama

Fail/Direktori Isu Tindakan
app/Http/Controllers/Admin/asal/ Mengandungi 4 controllers lama: DashboardController, PenjajaController, IkPenjajaController, PegawaiPenjajaController. Tiada routes menuju ke namespace ini. Versi utama sudah jauh lebih lengkap. Padam
routes/asal/web.php Route lama sebelum refactor. Tidak dimuatkan oleh Laravel. Padam
resources/views/admin/penjaja/asal/ Folder views lama dengan ~16 fail. Tiada routes aktif menggunakan views ini. Padam
resources/views/admin/penjaja/papar_permohonan-ori.blade.php Versi lama papar_permohonan.blade.php. Padam
resources/views/admin/penjaja/partials/dokumen-ori.blade.php Versi lama partial. Padam
resources/views/admin/penjaja/partials/ori_dokumen.blade.php Versi lama partial (nama berbeza). Padam
resources/views/admin/penjaja/partials/wangproses_nofail-ori.blade.php Versi lama partial. Padam
resources/views/layouts/appmin_lama.blade.php Layout admin lama. Padam
resources/views/fahmi.blade.php Test view. Route / mengembalikan ini bukan halaman utama sebenar. welcome.blade.php wujud tetapi tidak digunakan. Padam, tukar route / ke view yang betul

C3. Modul Stub / Tidak Lengkap

Modul Fail Isu Cadangan
PBTPay Payment Gateway PbtpayController.php, PbtpayBil.php, PbtpayCart.php, PbtpayCartItem.php, PbtpayTransaksi.php, pbtpay/callback.blade.php, pbtpay/indirect.blade.php Controller checkout() tidak siap, tiada return value. 4 models kosong (tiada $fillable, tiada relations). Callback view hanya mengandungi teks "test". Routes wujud tetapi tidak berfungsi. Keputusan diperlukan: implement atau padam semua
Bil Auto-Jana BilPelbagaiController.php janaBil() ditulis lengkap tetapi route (/pt/jana-bil-automatik) sengaja ditukar ke doNothing() — ini bukan bug, ini keputusan disengajakan. Aktifkan setelah disahkan dengan MBIP IT
Laporan Prestasi Admin\LaporanPrestasiController.php Ada syntax error dalam method utama()->where() tanpa parameter. Tiada route yang menuju ke controller ini. Betulkan atau tulis semula
LesenPenjajaHistory LesenPenjajaHistory.php Model kosong — tiada $fillable, tiada relations. Table wujud dalam migration tetapi model tidak digunakan dalam mana-mana controller. Implement sebagai audit trail atau padam
UserPolicies UserPolicies.php, LesenPenjajaPolicy.php Model UserPolicies dan table wujud. Policy class cuba guna model ini untuk semak akses tetapi kebanyakan method dalam Policy adalah empty stub. Implement sepenuhnya atau guna Gate sahaja
BilPelbagaiItemController BilPelbagaiItemController.php Class wujud tetapi tiada sebarang method. Implement atau padam

C4. Isu Penamaan dan Konsistensi

Isu Lokasi Penerangan
Bug: no_akaun_lesen vs no_fail_lesen PtPenjajaController::simpanNoLesen() baris 155 Method simpan ke no_akaun_lesen dan kod_lesen, tetapi success message menyebut $mohon->no_fail_lesen. Ini adalah bug sebenar — nama field dalam mesej tidak sepadan dengan field yang disimpan.
Ketidakjelasan dua field LesenPenjaja model no_akaun_lesen = akaun dalam sistem EPBT. no_fail_lesen = nombor fail fizikal MBIP. Kedua-dua digunakan dalam konteks berbeza tanpa dokumentasi jelas.
Typo nama migration 2025_06_19_084503_create_pengumumen_table.php Sepatutnya pengumuman, bukan pengumumen. Walaupun nama fail boleh kekal, jadual yang dicipta juga mungkin ada typo.
Nama route bercampur routes/web.php Campuran Melayu/Inggeris: pt.bawa-mesyuarat, admin.papar, get-bilpelbagai, penjaja-mohon. Tiada naming convention yang konsisten.
Dua class bernama PenjajaController Namespace berbeza App\Http\Controllers\PenjajaController (public) dan App\Http\Controllers\Admin\PenjajaController (admin). Dalam web.php, kedua-dua diimport dengan alias. Mengelirukan.
senaraibawamesyuarat.blade.php admin/penjaja/ Fail lama wujud tapi sistem menggunakan senaraibawamesyuaratbaru.blade.php yang lebih baru.
laporandashboard.blade.php admin/penjaja/ Nama mengelirukan — ia digunakan untuk paparan "semua permohonan" dalam senarai_all(), bukan laporan dashboard yang sebenar.
Boolean flags tidak digunakan users table is_admin_lesen_penjaja, is_admin_lesen_anjing, is_admin_lesen_perniagaan ada dalam $fillable User model tetapi tidak digunakan dalam mana-mana logic. Role-based auth menggunakan role column sahaja.
hantar_permohonan() guna session PenjajaController lesen_penjaja_id dibaca dari session — boleh gagal jika session expired atau tab dibuka berganda.

C5. Isu Seni Bina

Isu Butiran
Fat Controllers Admin\PenjajaController::store() melakukan dalam satu method: buat user, buat syarikat, buat user_syarikat, buat lesen_penjaja, upload dokumen, buat bil pelbagai, query EPBT, buat borang IK. Tiada DB transaction. Jika gagal di tengah, data tidak konsisten.
Status strings hardcoded Nilai seperti 'menunggu bayaran proses', 'lawatan tapak', 'ulasan pegawai' tersebar dalam PtPenjajaController, PenjajaController, Admin\PenjajaController, dan DashboardController. Typo dalam satu tempat menyebabkan permohonan "hilang" dari semua queue.
N+1 query dalam Dashboard DashboardController::utama() dan senarai_pt_proses() loop semua rekod 'menunggu bayaran proses' dan buat query ke EPBT (second_mysql) untuk setiap rekod. Semakin banyak permohonan, semakin lambat halaman loads.
Logik EPBT diduplikasi Logik query EpbtBpBil dan EpbtEcasResit muncul dalam 4 tempat berbeza: PtPenjajaController, Admin\PenjajaController, DashboardController, dan lain-lain. Jika EPBT berubah struktur, perlu kemaskini 4 tempat.
Tiada Enum Semua nilai status adalah string literals. PHP 8.1 menyokong Enum natively.
Tiada Service layer Semua business logic dalam controllers. Tidak ada Service, Action, atau Command classes.
Gates vs Policies bercampur AppServiceProvider mendefinisikan 6 Gates, ada juga Policy classes, penggunaan tidak konsisten antara keduanya.
Tiada DB transaction Method-method yang menulis ke banyak jadual sekaligus (seperti store()) tidak wrapped dalam DB::transaction().
Tiada event/job/observer Semua operasi synchronous. Tiada queue, tiada listeners, tiada observers.
Tiada FormRequest Validation berlaku secara inline dalam controllers. Hanya 2 FormRequest classes wujud untuk keseluruhan sistem.
Soft delete tidak digunakan hapus_permohonan() menggunakan ->delete() — data dipadam terus tanpa boleh dipulihkan.

C6. Jadual Lengkap Routes dengan Status

Route Method Controller@Method Status
/ GET view('fahmi') TEST VIEW — perlu tukar
/utama GET Auth\AuthenticatedSessionController@create aktif
/dashboard GET PenjajaController@list aktif
/mohon-penjaja GET PenjajaController@create aktif
/simpan-mohon-penjaja POST PenjajaController@store aktif
/mohon_hapus/{id} GET PenjajaController@hapus aktif
/mohon_edit/{id} GET PenjajaController@edit aktif
/mohon_papar/{id} GET PenjajaController@papar aktif
/mohon_hantar POST PenjajaController@hantar aktif
/pbtpay/checkout/{modul}/{id} POST PbtpayController@checkout STUB
/pbtpay/callback POST view('pbtpay.callback') STUB
/pbtpay/indirect POST view('pbtpay.indirect') STUB
/get-bil GET/POST PtPenjajaController@searchPelanggan aktif
/get_kawasan GET DataController@getKawasan aktif
/get_taman GET DataController@getTaman aktif
/get_jalan GET DataController@getJalan aktif
/get_penempatan GET DataController@getPenempatan aktif
/dashmin/{ctahun?} GET DashboardController@utama aktif
/penjaja-baru GET Admin\PenjajaController@senarai_pt aktif
/penjaja-proses GET Admin\PenjajaController@senarai_pt_proses aktif
/penjaja-bukafail GET Admin\PenjajaController@senarai_pt_bukafail aktif
/penjaja-daftarlesen GET Admin\PenjajaController@senarai_pt_daftarlesen aktif
/penjaja-pemeriksaan GET IkPenjajaController@senarai_ik aktif
/penjaja-cadangan GET PegawaiPenjajaController@senarai_cadangan aktif
/penjaja-ulasan-cadangan GET PegawaiPenjajaController@senarai_ulasan_cadangan aktif
/penjaja-mesyuarat GET Admin\PenjajaController@senarai_mesyuarat aktif
/penjaja-minitmesyuarat/{id} GET Admin\PenjajaController@senarai_bawa_mesyuarat aktif
/penjaja-keputusanmesyuarat GET Admin\PenjajaController@senarai_keputusan aktif
/penjaja-all GET Admin\PenjajaController@senarai_all aktif
/penjaja-hutang-lesen GET DashboardController@senaraiLesenBelumBayar aktif
/penjaja-hutang-lesen-semak GET DashboardController@semakBayaranLesen aktif
/simpan_wangproses POST PtPenjajaController@simpanWangProses aktif
/simpan_nofail POST PtPenjajaController@simpanNoFail aktif
/simpan_nolesen POST PtPenjajaController@simpanNoLesen aktif
/hantar_ppk POST PtPenjajaController@hantarPPK aktif
/simpan_mesyuarat POST PtPenjajaController@simpanMesyuarat aktif
/cetak_lampiran_b POST PtPenjajaController@exportWord aktif
/sahkan_senarai POST PtPenjajaController@sahkanSenarai aktif
/simpan_keputusan_mesyuarat POST PtPenjajaController@simpanKeputusanMesyuarat aktif
/ik-simpan-lokasi POST IkPenjajaController@simpanLokasi aktif
/ik-simpan-ulasan POST IkPenjajaController@simpanUlasan aktif
/pegawai-simpan-cadangan POST PegawaiPenjajaController@simpan_cadangan aktif
/pegawai-simpan-ulasan-cadangan POST PegawaiPenjajaController@simpan_ulasan_cadangan aktif
/pt/jana-bil-automatik POST BilPelbagaiController@doNothing DIMATIKAN (stub)
/mohon-penjaja-admin GET Admin\PenjajaController@create aktif
/simpan-mohon-penjaja-admin POST Admin\PenjajaController@store aktif
/lantikan_admin GET PengurusanAdminController@showList aktif (super)
/admin/users/{id}/update-role PATCH PengurusanAdminController@updateRole aktif (super)
/rem-admin/{nokp} GET PengurusanAdminController@removeAdmin aktif (super)
/admin/pengumuman/* CRUD PengumumanController aktif (super)
/carousel/* CRUD GambarCarouselController aktif (super)

D. Risiko Jika Terus Refactor Tanpa Pelan

D1. Risiko Keselamatan — Perlu Tindakan Segera

Risiko Punca Kesan
public/test_curl.php boleh diakses tanpa auth Fail ujian tertinggal dalam folder public Pihak luar boleh guna client_key = 'MPJBT' untuk jana bil palsu ke sistem EPBT. Data pelanggan ujian terdedah.
mylesen(2).sql dalam projek Developer simpan backup dalam folder projek Jika folder projek dikongsi atau di-commit ke git, seluruh database terdedah.
Tiada HTTPS enforcement dalam kod Tiada ForceScheme middleware BilPelbagaiController::janaBil() memanggil endpoint EPBT melalui http:// — komunikasi tidak selamat

D2. Risiko Integriti Data

Risiko Punca Kesan
Status "hilang" dari queue Status string typo dalam satu controller Permohonan tidak muncul dalam mana-mana queue — staf tidak dapat tindakan
Data tidak konsisten jika simpan gagal Tiada DB transaction dalam store() Permohonan dicipta tetapi dokumen tidak diupload, atau syarikat dicipta tetapi lesen tidak
Permohonan terlepas semak bayaran Semak bayaran manual atau bila dashboard diload Jika admin tidak reload dashboard, bayaran yang masuk tidak dikemaskini
no_fail_lesen vs no_akaun_lesen kekeliruan Dua field dengan nama serupa, peranan berbeza Laporan salah, carian gagal, integration dengan EPBT gagal

D3. Risiko Prestasi

Risiko Punca Kesan
Dashboard lambat bila permohonan banyak N+1 query ke EPBT second_mysql dalam loop Setiap rekod 'menunggu bayaran proses' buat satu query. 50 rekod = 50 queries setiap kali dashboard dibuka
Fail cetakan besar PHPWord tanpa compression .docx yang besar boleh timeout jika banyak permohonan dalam satu mesyuarat

D4. Risiko Kebolehselenggaraan

Risiko Punca Kesan
Developer baru keliru dengan asal/ directories Tiada dokumentasi tentang fail backup Developer mungkin edit fail lama dalam asal/ dan hairan kenapa tiada perubahan dalam sistem
Perubahan status flow memerlukan tukar 4 tempat Status strings tersebar Kesilapan dalam satu tempat tidak akan kelihatan dalam ujian manual biasa
LaporanPrestasiController tidak boleh diaktifkan Syntax error Jika developer cuba aktifkan, akan dapat 500 error
Integrasi EPBT sukar dimodifikasi Logic tersebar dalam 4 controllers Jika EPBT tukar endpoint atau struktur data, perlu cari dan tukar di banyak tempat

D5. Risiko Integrasi

Risiko Punca Kesan
PBTPay tidak berfungsi jika diaktifkan Semua stub, tiada implementasi sebenar Pengguna boleh click butang bayar tetapi proses tidak berlaku, tiada makluman ralat yang berguna
janaBil() client_key tidak disahkan 'MPJBT' hardcoded, tapi test_curl.php guna SHA-1 hash Ada kemungkinan format key yang berbeza untuk production

E. Cadangan Struktur Baru Secara Ringkas

E1. Pembersihan Segera (Lakukan Sebelum Sebarang Refactor)

Tindakan berikut tidak memerlukan perubahan kepada mana-mana business logic:

  1. PADAM public/test_curl.php — risiko keselamatan kritikal
  2. PINDAH mylesen(2).sql keluar dari folder projek ke lokasi selamat
  3. PADAM app/Http/Controllers/Admin/asal/ (4 controllers lama)
  4. PADAM routes/asal/web.php
  5. PADAM resources/views/admin/penjaja/asal/ (16 views lama)
  6. PADAM semua fail dengan nama -ori.blade.php, _lama.blade.php, -ori/
  7. TUKAR route / — dari view('fahmi') ke view('welcome') atau redirect ke /utama

Selepas setiap tindakan, jalankan semula semua routes untuk pastikan tiada broken link.

E2. Cadangan Struktur Direktori Baru

app/
  Enums/
    StatusPermohonan.php     ← gantikan string hardcoded
    StatusMesyuarat.php
    RolePengguna.php
  Services/
    ApplicationService.php   ← business logic permohonan
    EpbtService.php          ← semua EPBT API + DB calls
    BilService.php           ← bil proses + lesen
    MesyuaratService.php     ← mesyuarat + Lampiran B
  Http/
    Controllers/
      Pemohon/               ← public controllers
      Admin/
        PT/                  ← pembantu tadbir
        IK/                  ← inspektor kesihatan
        Pegawai/             ← pp + pengarah
        Pengurusan/          ← admin management
        Laporan/             ← reports
      Api/                   ← chrome extension API
    Requests/
      Permohonan/
      Bil/
      Mesyuarat/

Rujuk docs/rebuild-architecture.md untuk pelan rebuild penuh termasuk status flow, role matrix, dashboard plan, integration design, API design, dan implementation roadmap.


Dokumen ini adalah hasil audit statik berdasarkan pembacaan kod. Untuk maklumat terkini, sila semak kod semasa.