15 KiB
Improvement Plan
Dokumen ini mencatat pelan pembetulan dan penambahbaikan sistem PRN2026 selepas semakan kod menyeluruh selepas Phase 11 selesai. Setiap fasa mengikut susunan keutamaan: kritikal → prestasi → pengalaman pengguna → pengurusan data.
Setiap pembetulan dan perubahan wajib kemaskini:
docs/progress-log.mddocs/changelog.mddocs/decision-log.mdjika ada keputusan seni bina, pakej, pangkalan data atau keselamatan yang berubah
Fasa 12: Pembetulan Kritikal dan Keselamatan
Status: Belum dimulakan.
Skop fasa ini ialah menangani kelemahan yang boleh menyebabkan data tidak konsisten, kawalan akses bocor, atau keperluan edit database secara manual dalam persekitaran produksi.
12-A: Admin Settings UI — Toggle Kehadiran dan Override Pendaftaran
Masalah semasa:
election_settings.is_attendance_activehanya boleh diubah melalui edit database secara terus.election_settings.is_registration_open_overridejuga tiada UI khusus; bergantung pada pengaturan tarikh semata-mata.- Ini tidak selamat dan tidak praktikal dalam persekitaran produksi semasa hari mengundi.
Tugas:
- Tambah halaman Admin Settings di bawah
/admin/settingsatau/admin/setup/settings. - Paparkan toggle untuk
is_attendance_activedengan label jelas dan amaran impak. - Paparkan toggle atau dropdown untuk
is_registration_open_override(null / buka paksa / tutup paksa). - Paparkan tarikh buka dan tarikh tutup pendaftaran semasa sebagai konteks.
- Tambah
AdminSettingsControllerdanUpdateElectionSettingsRequest. - Tambah
ElectionSettingsServiceuntuk enkapsulasi logik kemaskini. - Rekod perubahan dalam activity log: siapa, nilai lama, nilai baru, masa.
- Tambah ujian ciri untuk kemaskini setiap toggle, halaman diakses Admin sahaja.
- Tambah pautan ke Admin Settings dari Admin dashboard.
Kriteria keluar:
- Admin boleh toggle kehadiran dan override pendaftaran dari UI tanpa sentuh database.
- Perubahan direkod dalam activity log.
- Admin Kewangan, PPM, KTM tidak boleh akses halaman settings.
Dokumentasi yang perlu dikemaskini:
docs/01-development-plan.md— tambah Fasa 12 dengan semua tugas dan kriteria keluar.docs/04-rbac-permission-matrix.md— tambah permissionmanage election settingsuntuk Admin.docs/05-workflow-design.md— tambah bahagian pengurusan tetapan pilihan raya.docs/progress-log.md— rekod selepas siap.docs/changelog.md— rekod selepas siap.docs/decision-log.md— rekod keputusan reka bentuk halaman settings.
12-B: Pembetulan Semakan IC Duplikasi untuk Rekod Soft-Deleted
Masalah semasa:
- Semakan IC duplikasi dalam
StorePublicApplicationRequestmenapis rekod aktif sahaja, tetapi soft-deleted KTM-created records masih wujud dalam pangkalan data. - Jika KTM delete rekod pemohon (
deleted_by_ktm), rekod tersebut soft-deleted tetapi IC dalamapplicationsmasih boleh menyebabkan konflik bergantung kepada cara query dikodkan. - Risiko: pemohon awam mungkin diblock padahal KTM sudah delete rekod mereka.
Tugas:
- Semak semula query semakan IC duplikasi dalam
StorePublicApplicationRequestdan mana-mana service yang menjalankan semakan serupa. - Pastikan rekod
deleted_at IS NOT NULL(soft-deleted) tidak diambil kira sebagai "aktif" dalam semakan duplikasi. - Pastikan
withTrashed()atau scoped query digunakan secara eksplisit dan konsisten. - Tambah kes ujian: KTM delete rekod → pemohon awam dengan IC sama boleh mohon semula.
- Semak
KtmVacancyServicedanAssignmentVacancyServicejuga untuk memastikan tiada pengiraan yang termasuk soft-deleted rows secara tidak sengaja.
Kriteria keluar:
- Ujian baru lulus: soft-deleted KTM record tidak menghalang permohonan awam baharu.
- Semua semakan IC dalam system menggunakan kaedah yang sama dan konsisten.
Dokumentasi yang perlu dikemaskini:
docs/05-workflow-design.md— perjelas bahawa soft-deleted records dikecualikan dari semakan IC aktif.docs/progress-log.mddandocs/changelog.md— rekod selepas siap.
12-C: Perkukuh Enforcement Nota Catatan Post-Pendaftaran
Masalah semasa:
AdminPostCloseNoteServicemenguatkuasakan keperluancatatanpada peringkat service layer.- Jika ada controller baru yang lupa panggil service ini, semakan tidak berlaku dan Admin boleh edit rekod tanpa nota selepas pendaftaran ditutup tanpa sebarang amaran.
- Enforcement bergantung sepenuhnya pada konvensyen pemanggilan, bukan pada mekanisme framework.
Tugas:
- Semak semua controller Admin yang boleh mengubah
Application,StaffAssignment,PoliceEscort,KkmRepresentative, atauJkmRepresentativeselepas pendaftaran ditutup. - Tambah senarai semak di
AdminPostCloseNoteServiceyang boleh dipanggil secara konsisten. - Pertimbangkan untuk tambah
middlewarekhusus pada route group Admin management yang secara automatik menjalankan semakan ini, dan reject request tanpacatatanapabila pendaftaran ditutup. - Jika middleware digunakan, dokumentasikan dalam
docs/decision-log.md. - Tambah ujian integrasi untuk setiap route Admin management yang sepatutnya enforce semakan ini.
Kriteria keluar:
- Semua route management Admin yang mengubah rekod domain enforce catatan secara konsisten apabila pendaftaran ditutup.
- Ujian baru mengesahkan enforcement pada setiap route yang berkenaan.
- Tiada jalan pintas yang boleh bypass semakan ini tanpa sengaja.
Dokumentasi yang perlu dikemaskini:
docs/05-workflow-design.md— dokumentasikan mekanisme enforcement yang dipilih.docs/decision-log.md— rekod keputusan sama ada guna middleware atau service pattern.docs/progress-log.mddandocs/changelog.md— rekod selepas siap.
12-D: Pembetulan SampleElectionSeeder dan Konsistensi Nama Jawatan
Masalah semasa:
- Selepas migrasi Phase 11 menukar
CALON_SIMPANANkepadaCALON_TAMBAHAN, ada kemungkinanSampleElectionSeeder.phpmasih mengandungi rujukan kepada nama atau slug lama. - Jika seeder dijalankan semula (fresh seed untuk UAT atau persekitaran baharu), data yang dijana mungkin tidak konsisten dengan
PositionSeeder.
Tugas:
- Buka dan audit
SampleElectionSeeder.phpsecara menyeluruh. - Cari semua rujukan kepada
CALON_SIMPANANatau string berkaitan dan gantikan denganCALON_TAMBAHAN. - Pastikan semua slug jawatan dalam seeder sepadan tepat dengan apa yang
PositionSeederjana. - Jalankan
php artisan migrate:fresh --seeddan pastikan tiada ralat. - Jalankan
php artisan testdan pastikan semua 80 ujian lulus.
Kriteria keluar:
php artisan migrate:fresh --seedselesai tanpa ralat.php artisan testlulus sepenuhnya.- Tiada rujukan kepada
CALON_SIMPANANdalam mana-mana seeder.
Dokumentasi yang perlu dikemaskini:
docs/progress-log.mddandocs/changelog.md— rekod selepas siap.
12-E: Konsistensikan Semakan Jenis Dokumen pada Semua Path Download
Masalah semasa:
- Admin Kewangan route download secara eksplisit mengehad kepada
bank_statementsahaja. - Route download PPM, Admin, dan Admin Kewangan masing-masing menggunakan implementasi yang berbeza.
- Jika ada ketidakkonsistenan dalam cara jenis dokumen disahkan, pengguna yang dibenarkan mungkin boleh download jenis dokumen yang sepatutnya terhad untuk mereka.
Tugas:
- Audit semua route download dokumen: PPM, Admin, dan Admin Kewangan.
- Cipta satu senarai jenis dokumen yang dibenarkan per peranan (
document_typeallowlist). - Refactor semakan jenis dokumen ke dalam satu tempat — boleh dalam
DocumentDownloadControlleratau policyApplicationPolicy. - Tambah ujian untuk setiap peranan mengesahkan mereka:
- Boleh download dokumen yang dibenarkan.
- Tidak boleh download dokumen di luar skop mereka walaupun ID dokumen diketahui.
- Pastikan 403 dikembalikan, bukan 404, untuk download yang diblock (supaya mesej ralat tidak mendedahkan kewujudan dokumen).
Kriteria keluar:
- Semua path download dokumen menggunakan semakan jenis yang konsisten.
- Ujian baru mengesahkan boundary setiap peranan.
- Tiada path yang boleh bypass semakan jenis dokumen.
Dokumentasi yang perlu dikemaskini:
docs/04-rbac-permission-matrix.md— tambah baris untuk akses dokumen per peranan.docs/decision-log.md— rekod keputusan centralize semakan jenis dokumen.docs/progress-log.mddandocs/changelog.md— rekod selepas siap.
Fasa 13: Indeks Pangkalan Data dan Prestasi
Status: Belum dimulakan.
Skop fasa ini ialah menambah composite indexes yang diperlukan sebelum sistem mula menerima data sebenar dalam kuantiti besar.
13-A: Tambah Composite Indexes untuk Query Kerap
Masalah semasa:
- Query senarai Admin global (
/admin/management/applications) menyaring mengikutelection_id,status, danpusat_mengundi_idtanpa composite index. - Query
AssignmentVacancyServicedanKtmVacancyServicemenyaringstaff_assignmentsmengikutelection_id,pusat_mengundi_id,position_id, danis_activetanpa composite index. - Untuk pilihan raya dengan 5,000–20,000 permohonan, query ini boleh menjadi lambat secara signifikan.
Tugas:
- Cipta migration baharu untuk menambah indexes (jangan ubah migration sedia ada).
- Tambah pada jadual
applications:(election_id, status)(election_id, pusat_mengundi_id, status)(election_id, ic_number)— untuk semakan IC duplikasi
- Tambah pada jadual
staff_assignments:(election_id, pusat_mengundi_id, position_id, is_active)(election_id, saluran_mengundi_id, position_id, is_active)(reports_to_assignment_id, is_active)— untuk KtmVacancyService
- Tambah pada jadual
bank_verifications:(election_id, status)
- Gunakan nama index yang pendek dan eksplisit (ikut konvensyen sedia ada dalam sistem).
- Jalankan
php artisan migratedan sahkan indexes wujud. - Jalankan
php artisan testdan pastikan semua ujian lulus.
Kriteria keluar:
- Migration berjaya tanpa ralat.
- Semua ujian lulus.
- Query utama pada senarai admin menggunakan indexes (boleh disahkan dengan
EXPLAINdalam MySQL Workbench).
Dokumentasi yang perlu dikemaskini:
docs/03-database-design.md— tambah bahagian indexes dan justifikasi.docs/decision-log.md— rekod keputusan indexes yang ditambah dan sebab.docs/08-deployment-notes.md— tambah arahan semak indexes semasa deployment.docs/progress-log.mddandocs/changelog.md— rekod selepas siap.
Fasa 14: Portal Status Permohonan Pemohon Awam
Status: Belum dimulakan.
Skop fasa ini ialah memberi pemohon awam cara untuk semak status permohonan mereka tanpa perlu login atau hubungi Admin.
14-A: Halaman Status Permohonan via UUID Awam
Masalah semasa:
- Pemohon awam hanya menerima redirect ke
/permohonan/{uuid}/berjayaselepas mohon. - Tiada cara untuk semak status kemudian (diluluskan? ditolak? kenapa ditolak?).
- Ini menyebabkan beban sokongan kepada Admin dan PPM.
Tugas:
- Tambah route
GET /permohonan/{application:public_uuid}/status. - Halaman ini tidak memerlukan login — cukup UUID awam permohonan sebagai pengecam.
- Paparkan maklumat terhad: nama pemohon (sebahagian), jawatan dipohon, pusat mengundi, status semasa, tarikh kemaskini terakhir.
- Jika status
rejected, paparkan sebab penolakan jika ada. - Jika status
assigned, paparkan pengesahan penempatan tanpa mendedahkan butiran dalaman (saluran ID, dsb.). - Jangan paparkan nombor IC penuh, nombor akaun bank, atau data sensitif lain.
- Gunakan
SensitiveDatahelper untuk mask nama sebahagian jika perlu. - Tambah ujian untuk: permohonan berstatus submitted, approved, assigned, rejected, dan UUID tidak wujud.
Kriteria keluar:
- Pemohon boleh semak status dengan hanya URL yang mengandungi UUID awam.
- Data sensitif tidak didedahkan.
- Halaman tidak mendedahkan sama ada UUID wujud atau tidak kepada orang lain (status 200 dengan mesej umum untuk UUID tidak dikenali, bukan 404).
Dokumentasi yang perlu dikemaskini:
docs/05-workflow-design.md— tambah bahagian portal status pemohon.docs/06-ui-ux-plan.md— tambah reka bentuk halaman status.docs/progress-log.mddandocs/changelog.md— rekod selepas siap.docs/decision-log.md— rekod keputusan reka bentuk privacy (status 200 vs 404 untuk UUID tidak dikenali).
Fasa 15: Pengurusan Eksport dan Data Sensitif
Status: Belum dimulakan.
Skop fasa ini ialah memastikan fail eksport yang mengandungi data sensitif tidak kekal dalam storage tanpa had masa.
15-A: Purge Automatik Fail Eksport Lama
Masalah semasa:
- Fail XLSX eksport kewangan (disimpan di
exports/finance) dan eksport kehadiran (disimpan diexports/attendance) disimpan dalam private storage tanpa had masa. - Fail-fail ini mengandungi data bank, nombor IC, dan maklumat peribadi lain.
- Tiada mekanisme untuk padam fail lama secara automatik.
Tugas:
- Tambah
ExportPurgeCommand(php artisan exports:purge) sebagai Artisan command. - Command menerima parameter
--days=(default: 30) untuk menentukan tempoh simpanan. - Command akan:
- Query
export_logsuntuk rekod lebih lama daripada tempoh yang ditetapkan. - Padam fail dari storage disk yang berkaitan.
- Kemaskini
export_logsdenganpurged_atdanpurged_by(system). - Log aktiviti purge.
- Query
- Daftarkan command dalam
bootstrap/app.phpatauroutes/console.phpsebagai scheduled task (contoh: harian pada tengah malam). - Tambah kolum
purged_atpada jadualexport_logsmelalui migration baharu. - Tambah ujian untuk: command berjaya padam fail lama, fail baru tidak terpadam,
export_logsdikemaskini.
Kriteria keluar:
- Command boleh dijalankan secara manual dan secara scheduled.
- Fail lebih lama dari tempoh yang ditetapkan dipadamkan dari storage.
export_logsmenunjukkan rekod purge.- Fail yang masih dalam tempoh simpanan tidak terpadam.
Dokumentasi yang perlu dikemaskini:
docs/03-database-design.md— tambah kolumpurged_atdalam jadualexport_logs.docs/08-deployment-notes.md— tambah arahan konfigurasi scheduler dan polisi simpanan eksport.docs/decision-log.md— rekod keputusan tempoh simpanan default dan strategi purge.docs/progress-log.mddandocs/changelog.md— rekod selepas siap.
Ringkasan Keutamaan
| Fasa | Tajuk | Keutamaan | Status |
|---|---|---|---|
| 12-A | Admin Settings UI (toggle kehadiran/pendaftaran) | Kritikal | Selesai 2026-06-02 |
| 12-B | Pembetulan semakan IC soft-deleted | Kritikal | Selesai 2026-06-02 |
| 12-C | Perkukuh enforcement nota catatan | Kritikal | Selesai 2026-06-02 |
| 12-D | Pembetulan SampleElectionSeeder | Kritikal | Selesai 2026-06-02 |
| 12-E | Konsistensikan semakan jenis dokumen download | Kritikal | Selesai 2026-06-02 |
| 13-A | Tambah composite indexes pangkalan data | Prestasi | Selesai 2026-06-02 |
| 14-A | Portal status permohonan pemohon awam | UX | Selesai 2026-06-02 |
| 15-A | Purge automatik fail eksport sensitif | Data | Selesai 2026-06-02 |
Nota Pelaksanaan
- Setiap item dalam Fasa 12 boleh dilaksanakan secara bebas dan tidak perlu tunggu item lain selesai.
- Fasa 13 patut dilaksanakan sebelum data sebenar mula dimasukkan ke dalam sistem.
- Fasa 14 dan 15 boleh dilaksanakan secara selari kerana tidak ada kebergantungan antara satu sama lain.
- Setiap pembetulan mesti menjalankan semula suite ujian penuh (
php artisan test) sebelum dianggap selesai. - Jalankan
vendor\bin\pint.bat --testdanvendor\bin\phpstan.bat analyse --memory-limit=1Gselepas setiap fasa.