# Changelog All notable user-facing changes to this project will be documented in this file. ## 2026-05-28 - Phase 0 Planning Records Added: - Initial project planning documentation. - Proposed architecture. - Proposed database design. - RBAC matrix. - Workflow design. - UI/UX plan. - Testing plan. - Deployment notes. - Decision and progress logs. Notes: - No application features have been implemented yet. - No user-facing web interface exists yet. ## 2026-05-28 - Phase 0 Documentation Review Changed: - Clarified registration-open setting in database and workflow planning. - Clarified Phase 1 package baseline. - Recorded local-only Telescope and later-only DOMPDF decisions. ## 2026-05-28 - Phase 1 Laravel Base Application Added: - Laravel 13 application base. - Login, logout, password reset, email verification, and profile routes from Breeze. - Bootstrap 5 authenticated and guest layouts. - Role-based dashboards for Admin, Admin Kewangan, PPM, KTM, and Pemohon. - RBAC roles and permissions seeder. - Default local Admin seed account. - Spatie permission and activity log foundations. - QR code package foundation. - Spreadsheet export foundation using OpenSpout. Changed: - Disabled generic public account registration. - Replaced generated Tailwind views with Bootstrap views. Notes: - `maatwebsite/excel` was not installed because Composer rejected it for the current PHP 8.5.1/Laravel 13 environment. ## 2026-05-28 - Phase 2 Core Database Added: - Core election-domain database schema. - Domain models and relationships. - Default position seeder. - Sample election hierarchy seed data. - Position quota seed data. - Sample role users for Admin Kewangan, PPM, and KTM. - Sample dual-role PPM plus KTM assignment. - Sample wheelchair allocation. - Core domain seeder test. Changed: - Confirmed local MySQL usage for migrations and seeders. - Shortened long database index names for MySQL compatibility. ## 2026-05-29 - Phase 3 Admin Setup Module Added: - Admin setup overview page. - CRUD screens for Bahagian Pilihanraya, Daerah Mengundi, Pusat Mengundi, Saluran Mengundi, and Jawatan. - Position quota setup for pusat-level and saluran-level vacancies. - PPM assignment from Pusat Mengundi detail screen. - QR generation and refresh for each Pusat Mengundi. - Public QR placeholder page at `/pohon/{pusat_mengundi_uuid}`. - Admin dashboard link to Election setup. - Feature tests for Admin setup access, hierarchy creation, QR generation, quota setup, PPM assignment, and public UUID QR route. Changed: - QR links now resolve using public UUID values instead of internal database IDs. - Public QR pages use a public layout without authenticated navigation. Notes: - The full public applicant form remains scheduled for Phase 4. - KKM, JKM, and Police operational management remains scheduled for the later Admin management phase. ## 2026-05-29 - Phase 4 Public Application Module Added: - Public application form at `/pohon/{pusat_mengundi_uuid}`. - Application roles KTM, KP, KPDP, and PAPM. - Dynamic KTM selection for KP/KPDP based on remaining vacancy. - Required IC document and bank statement uploads. - Private document storage for uploaded public application files. - Registration period open/closed enforcement. - Duplicate IC blocking for current election. - Specific blocking message for active KTM-created records with the same IC. - Application success page with public UUID reference. - Pending bank verification creation for submitted applications. - Feature and unit tests for public application rules, registration period, and vacancy calculation. Changed: - QR links now open the real public application flow instead of the Phase 3 placeholder. Notes: - PPM review and approval of submitted applications remains scheduled for Phase 5. ## 2026-05-29 - Phase 5 PPM Review and Assignment Added: - PPM application list scoped to assigned Pusat Mengundi. - PPM application detail page with applicant, bank, document, selected KTM, agency representative, and status history sections. - PPM approval flow with role change before approval. - KTM assignment to available Saluran Mengundi. - KP/KPDP assignment to active KTM with remaining vacancy. - PAPM assignment at Pusat Mengundi level. - PPM rejection flow with required reason. - Private document download for PPM-owned applications. - Record-level authorization policy for PPM application access. - PPM dashboard metrics and link to review queue. - Feature tests for PPM scoping, missing-document block, approval/assignment, role change, and rejection. Changed: - Application approval in PPM flow now creates active staff assignment and moves the application to `assigned`. - Base controller now includes Laravel authorization support for policies. Notes: - Polling-day attendance remains scheduled for Phase 10. ## 2026-05-29 - Phase 6 KTM Flow Added: - KTM team page showing assigned Saluran, KP team members, and KP vacancy. - KTM KP registration form. - KTM-created KP records with `source = created_by_ktm`. - Queued Markdown email notification for KTM-created applicants. - KTM approval flow for KP applications under own team. - KTM deletion flow for own unassigned KTM-created applicant records. - Registration-period enforcement for KTM registration and approval. - KTM dashboard metrics and links to team/KP registration pages. - Feature tests for KTM team scope, KP-only registration, email notification, registration closing, approval, non-KP block, other-team block, and deletion. Changed: - KTM dashboard now shows assigned Saluran, active KP count, and KP vacancy from live data. Notes: - KTM cannot upload documents for applicants in this phase; document collection remains with public/admin flows. ## 2026-05-29 - Phase 7 Admin Management and Manual Entry Added: - Admin management dashboard at `/admin/management`. - Global Admin application list with filters. - Manual application entry by Admin. - Admin application edit screen with direct assignment panel. - Global staff assignment list and edit screen. - Police, KKM, and JKM representative entry screen. - Required post-registration `catatan` validation for Admin changes after registration closes. - System note creation for post-closing Admin changes. - Activity and history logging for Admin application and assignment changes. - Feature tests for manual entry, post-closing notes, direct assignment, representative creation, and Admin Kewangan route blocking. Changed: - Admin dashboard now shows live counts for Pusat Mengundi, Saluran, applications, and pending review. - Admin dashboard links to the new management module. Notes: - Admin manual records do not send applicant email requests. ## 2026-05-29 - Phase 8 Admin Kewangan Added: - Admin Kewangan bank verification module at `/kewangan/bank`. - Finance list for approved/assigned staff. - Filters for Pusat Mengundi, role, verification status, missing bank statement, missing account number, and keyword. - Bank verification detail page. - Status update for pending, verified, rejected, and requires correction. - Finance note capture. - Finance XLSX export with export log recording. - Sensitive data masking for IC, phone, and bank account display. - Feature tests for finance list, verification update, filters, export logs, and assignment access blocking. Changed: - Admin Kewangan dashboard now shows live finance counts and links to the finance module. Notes: - Finance export uses OpenSpout due to the documented `maatwebsite/excel` compatibility exception. ## 2026-05-29 - Phase 9 Wheelchair Management Added: - Admin wheelchair management module at `/admin/management/wheelchairs`. - Wheelchair allocation setup per Pusat Mengundi. - Taken transaction recording with quantity, time, person taking, and notes. - Returned transaction recording with quantity, time, condition, and notes. - Summary counts for allocated, taken, returned, outstanding, and available quantities. - Transaction history table. - Audit logging for allocation changes and wheelchair transactions. - Feature tests for allocation, taken/returned transactions, quantity validation, and role access blocking. Changed: - Admin management dashboard and navigation now include Kerusi Roda. Notes: - Transaction rows are retained as movement history; current balance is calculated from transaction totals. ## 2026-05-29 - Phase 10 Attendance Added: - PPM attendance module at `/ppm/attendance`. - PPM-scoped Pusat Mengundi attendance list. - Bulk attendance recording for active staff assignments. - Attendance statuses: present, absent, and not recorded. - Check-in time, recorded by, and note fields. - Attendance activation guard using `election_settings.is_attendance_active`. - Admin attendance dashboard at `/admin/attendance`. - Admin attendance detail view by Pusat Mengundi. - Role-level attendance summary. - Attendance detail XLSX export with export log recording. - Feature and unit tests for PPM scoping, activation flag, Admin dashboard, export log, and summary calculation. Changed: - Admin dashboard now links to attendance. - PPM dashboard now links to attendance and shows present count. Notes: - Attendance export uses OpenSpout due to the documented `maatwebsite/excel` compatibility exception. ## 2026-05-29 - Phase 11 Polish and Hardening Added: - Authorized Admin document download route for private application documents. - Authorized Admin Kewangan bank statement download route. - Activity logging for Admin and finance document downloads. - Document access tests for Admin, Admin Kewangan, and unauthorized roles. - Sensitive data masking unit test. - Final deployment quality gate notes. Changed: - Admin application edit screen now shows uploaded documents with secure download links. - Admin Kewangan bank detail screen now links to bank statement download when available. Notes: - Admin Kewangan cannot download IC documents through the finance document route. ## 2026-05-31 ### Changed - Borang daftar Pusat Mengundi kini menerima bilangan Saluran, KTM, Polis Iring, KP, PPM, KPDP, PAPM, JKM, KKM dan Calon Tambahan. - Saluran dijana secara automatik mengikut nombor dan tidak lagi memerlukan nama. - Istilah Calon Simpanan telah ditukar kepada Calon Tambahan. ## 2026-06-02 - Fasa 15-A: Purge Automatik Fail Eksport Sensitif ### Added - Artisan command `exports:purge --days=30` — memadam fail XLSX eksport lama dari storage dan menandakan rekod `export_logs` dengan `purged_at`. - Scheduled task harian pada `00:00` dalam `routes/console.php` untuk jalankan purge secara automatik (retention default: 30 hari). - Kolum `purged_at` dan `purged_by_user_id` pada jadual `export_logs`. - Activity log `export_file_purged` untuk setiap fail yang dipadamkan. - 7 ujian baharu dalam `ExportPurgeCommandTest`. ### Changed - `ExportLog` model kini mempunyai cast `purged_at` dan relationship `purgedBy()`. ## 2026-06-02 - Fasa 14-A: Portal Status Permohonan Pemohon Awam ### Added - Halaman status permohonan di `/permohonan/{uuid}/status` — boleh dicapai tanpa log masuk menggunakan UUID awam sahaja. - Memaparkan: nama disamarkan (3 aksara pertama), jawatan, pusat mengundi, status dengan badge berwarna, sebab penolakan jika ditolak. - UUID tidak dikenali, rekod soft-deleted, dan rekod `deleted_by_ktm` mengembalikan 200 dengan mesej generik — tidak mendedahkan maklumat dalaman. - `SensitiveData::maskName()` — helper masking nama (3 aksara pertama + `***`). - Panel "Simpan pautan status" pada halaman kejayaan permohonan dengan butang salin URL. - 9 ujian baharu dalam `PublicApplicationStatusTest`. ## 2026-06-02 - Fasa 12-E: Konsistensikan Semakan Jenis Dokumen Download ### Added - `ApplicationDocument` model kini mempunyai type constants (`TYPE_IC_DOCUMENT`, `TYPE_BANK_STATEMENT`) dan per-role allowlists (`ALLOWED_FOR_ADMIN`, `ALLOWED_FOR_PPM`, `ALLOWED_FOR_FINANCE`) sebagai satu sumber kebenaran. - Activity log untuk PPM document downloads: `document_downloaded_by_ppm`. - 9 ujian baharu dalam `DocumentDownloadAuthorizationTest` meliputi semua tiga path dan kes sempadan. ### Fixed - PPM path kini mempunyai semakan jenis dokumen eksplisit menggunakan `ALLOWED_FOR_PPM`. - PPM path kini mengembalikan 403 (bukan 404) untuk ownership mismatch — tidak mendedahkan kewujudan ID dokumen. - Admin path kini menggunakan `ALLOWED_FOR_ADMIN` secara eksplisit — jenis dokumen baharu perlu didaftarkan untuk Admin dapat akses. - Finance path kini menggunakan `ALLOWED_FOR_FINANCE` constant (logik sama, kini konsisten). ## 2026-06-02 - Fasa 13-A: Composite Indexes Pangkalan Data ### Added - Migration `2026_06_02_000000_add_performance_indexes.php` menambah 3 index baharu: - `applications.(election_id, status)` — dashboard count dan senarai admin bertapis election - `applications.(selected_ktm_assignment_id, requested_position_id)` — `KtmVacancyService` reserved-application count (dipanggil setiap semak kekosongan KP/KPDP) - `staff_assignments.(reports_to_assignment_id, position_id, status)` — `KtmVacancyService` active-assignment count di bawah KTM - Dokumentasi lengkap semua index dalam `docs/03-database-design.md`. - Arahan verifikasi index (`SHOW INDEX`, `EXPLAIN`) dalam `docs/08-deployment-notes.md`. ### Notes - Dua index yang diancangkan dalam plan sudah wujud dalam migration Phase 2: `(election_id, ic_number)` dan `(election_id, pusat_mengundi_id, status)` pada `applications`. - `bank_verifications` tiada kolum `election_id` — index berkaitan tidak ditambah. ## 2026-06-02 - Fasa 12-C: Perkukuh Enforcement Nota Catatan Post-Pendaftaran ### Added - Middleware `RequireAdminPostCloseNote` — automatically enforces that a `note` field is present in all write operations (`POST`, `PATCH`, `PUT`, `DELETE`) on Admin management routes when election registration is closed. Middleware alias: `admin.post_close_note`. - 5 ujian baharu meliputi semua mutation routes yang sebelum ini tidak mempunyai catatan enforcement tests: application create, assignment update, representative create, representative delete, dan ujian bahawa middleware tidak menyekat apabila pendaftaran terbuka. ### Changed - Route group `admin/management` kini menggunakan middleware `['auth', 'role:Admin', 'admin.post_close_note']` — catatan dikuatkuasakan secara automatik pada semua write routes tanpa bergantung pada konvensyen pemanggilan service sahaja. ## 2026-06-02 - Fasa 12-B: Pembetulan Semakan IC Soft-Deleted ### Fixed - Audit dan pengesahan bahawa semua query semakan IC duplikasi (`StorePublicApplicationRequest`, `KtmApplicationService`) menggunakan perlindungan dua lapis yang betul: SoftDeletes scope (mengecualikan `deleted_at IS NOT NULL`) dan `whereNotIn` (mengecualikan `cancelled` dan `deleted_by_ktm`). - Tambah comment dalam kod untuk mendokumentasikan intent perlindungan ini secara eksplisit. ### Added (Tests) - Ujian baharu `test_public_registration_is_unblocked_after_ktm_deletes_applicant`: mengesahkan pemohon awam boleh mendaftar semula selepas KTM delete rekod yang dicipta. - Ujian baharu `test_cancelled_application_does_not_block_new_registration`: mengesahkan rekod `cancelled` tidak menyekat pendaftaran IC yang sama. ## 2026-06-02 - Fasa 12-A: Admin Settings UI ### Added - Halaman Admin Settings di `/admin/setup/settings/{election}` untuk mengawal mod kehadiran dan override tempoh pendaftaran tanpa edit database. - Toggle radio untuk `is_attendance_active`: Tidak aktif / Aktif. - Toggle radio tiga-keadaan untuk `is_registration_open_override`: Auto (ikut tarikh) / Buka Paksa / Tutup Paksa. - Pautan "Tetapan" dalam nav setup dan setup index actions. - Amaran badge apabila override sedang aktif. - Activity log untuk setiap perubahan tetapan (nilai sebelum dan selepas, siapa yang ubah). - 9 ujian baharu untuk akses, kemaskini, dan activity log. ### Fixed - `SampleElectionSeeder` kini query kod jawatan `CALON_TAMBAHAN` (bukan `CALON_SIMPANAN` lama) — `php artisan migrate:fresh --seed` kini berjalan tanpa ralat. - `AdminSetupTest` dikemaskini untuk menghantar medan operasi yang diperlukan semasa cipta Pusat, dan menggunakan nombor saluran '3' untuk elak konflik dengan saluran auto-jana. ## 2026-06-02 - Perancangan Fasa 12–15 ### Added - Dokumen pelan penambahbaikan `docs/09-improvement-plan.md` merangkumi lapan isu yang dikenal pasti daripada semakan kod menyeluruh selepas Phase 11. - Fasa 12–15 ditambah dalam `docs/01-development-plan.md` sebagai fasa penambahbaikan berprioritikan. ### Planned (belum dilaksanakan) - Fasa 12: Pembetulan kritikal — Admin Settings UI untuk toggle kehadiran dan pendaftaran, pembetulan semakan IC soft-deleted, perkukuhan enforcement nota catatan, pembetulan seeder, dan konsistensi semakan jenis dokumen download. - Fasa 13: Composite indexes pangkalan data untuk prestasi query berskala besar. - Fasa 14: Portal status permohonan pemohon awam yang boleh dicapai via UUID tanpa login. - Fasa 15: Purge automatik fail eksport sensitif dengan polisi simpanan boleh dikonfigurasi.