Files
prn2026/docs/progress-log.md
2026-06-03 08:51:22 +08:00

52 KiB
Raw Permalink Blame History

Progress Log

2026-05-28 - Phase 0: Project Inspection and Planning

Status: Completed

Completed:

  • Inspected workspace.
  • Confirmed workspace is currently empty.
  • Confirmed no git repository is initialized.
  • Confirmed no existing Laravel application is present.
  • Confirmed no AGENTS.md project instruction file is present.
  • Checked local tooling:
    • PHP 8.5.1 available.
    • Composer 2.9.4 available.
    • Node 25.1.0 available.
    • npm.cmd 11.14.1 available.
    • npm PowerShell shim blocked by execution policy.
    • MySQL CLI not available in PATH.
  • Created Phase 0 planning documentation.

Changed files:

  • docs/00-project-brief.md
  • docs/01-development-plan.md
  • docs/02-architecture.md
  • docs/03-database-design.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/06-ui-ux-plan.md
  • docs/07-testing-plan.md
  • docs/08-deployment-notes.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Pending items:

  • Initialize or create Laravel project in Phase 1.
  • Confirm exact Laravel version during install.
  • Confirm MySQL server credentials and connectivity.
  • Verify package compatibility during Composer/npm installation.
  • Initialize git repository if desired.

Next step:

  • Proceed to Phase 1 only after approval: Laravel setup, authentication scaffolding, Bootstrap 5 base layout, roles, permissions, and base dashboards.

Manual testing for this phase:

  • Review documentation files for completeness.
  • Confirm assumptions in docs/decision-log.md.

2026-05-28 - Phase 0 Review Before Implementation

Status: Completed

Completed:

  • Reviewed all Phase 0 documentation files against the original requirement.
  • Confirmed the required documentation set is present.
  • Clarified Phase 1 package baseline in the development plan.
  • Clarified election_settings.is_registration_open in database and workflow design.
  • Recorded optional Telescope and DOMPDF decisions.

Changed files:

  • docs/01-development-plan.md
  • docs/03-database-design.md
  • docs/05-workflow-design.md
  • docs/decision-log.md
  • docs/progress-log.md

Pending items:

  • Proceed with Phase 1 implementation.

Next step:

  • Scaffold Laravel, install packages, configure authentication, Bootstrap layout, roles/permissions, and base dashboards.

2026-05-28 - Phase 1: Laravel Setup and Authentication

Status: Completed

Completed:

  • Scaffolded Laravel application.
  • Installed Laravel framework 13.12.0.
  • Installed Laravel Breeze authentication scaffolding.
  • Disabled generic public account registration route.
  • Installed and configured Bootstrap 5 layout through Vite.
  • Installed Bootstrap Icons, jQuery, SweetAlert2, Tom Select, Flatpickr, and DataTables Bootstrap packages.
  • Installed spatie/laravel-permission and published migrations/config.
  • Installed spatie/laravel-activitylog and published migrations/config.
  • Installed simplesoftwareio/simple-qrcode.
  • Attempted maatwebsite/excel; Composer rejected it for PHP 8.5.1/Laravel 13 compatibility.
  • Installed openspout/openspout as compatible spreadsheet export foundation.
  • Installed Larastan/PHPStan.
  • Added role middleware aliases.
  • Added User HasRoles support.
  • Added role and permission seeder.
  • Added default Admin seeding through config/prn.php.
  • Added role-based dashboard routes and base dashboard UI.
  • Updated auth/profile/welcome views to Bootstrap.
  • Updated .env.example for MySQL.
  • Set application timezone to Asia/Kuala_Lumpur.
  • Kept local .env on SQLite because MySQL server credentials are not yet available.
  • Added tests for disabled registration and dashboard role protection.

Changed files:

  • Laravel application scaffold files.
  • app/Http/Controllers/DashboardController.php
  • app/Models/User.php
  • bootstrap/app.php
  • config/activitylog.php
  • config/permission.php
  • config/prn.php
  • config/app.php
  • database/migrations/*permission*
  • database/migrations/*activity_log*
  • database/seeders/DatabaseSeeder.php
  • database/seeders/RolePermissionSeeder.php
  • resources/css/app.css
  • resources/js/app.js
  • resources/views/auth/*.blade.php
  • resources/views/dashboards/index.blade.php
  • resources/views/layouts/*.blade.php
  • resources/views/profile/edit.blade.php
  • resources/views/welcome.blade.php
  • routes/auth.php
  • routes/web.php
  • tests/Feature/Auth/RegistrationTest.php
  • tests/Feature/DashboardAccessTest.php
  • .env.example
  • .gitignore
  • composer.json
  • composer.lock
  • package.json
  • package-lock.json
  • phpstan.neon
  • docs/*

Verification:

  • php artisan migrate --seed completed after seeder correction.
  • php artisan db:seed completed.
  • npm.cmd run build passed.
  • php artisan route:list passed.
  • php artisan test passed: 27 tests, 64 assertions.
  • vendor\bin\pint.bat --test passed.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.

Pending items:

  • Confirm MySQL database credentials and switch local .env to MySQL when available.
  • Implement Phase 2 core domain migrations/models/seeders.
  • Replace OpenSpout with maatwebsite/excel only if a compatible release becomes available or runtime PHP target changes.

Manual testing:

  • Visit /.
  • Log in as seeded Admin:
    • email: admin@prn.local
    • password: password
  • Confirm /dashboard redirects Admin to /admin/dashboard.
  • Confirm /register is not available.
  • Resize browser to confirm mobile navbar behavior.

Next step:

  • Phase 2: Core database and seeders for election hierarchy, positions, quotas, applications, assignments, and operational records.

2026-05-28 - Phase 2: Core Database and Seeders

Status: Completed

Completed:

  • Added core election-domain migration.
  • Added user_profiles, election hierarchy, position/quota, application/document/history, assignment/history, representative, wheelchair, attendance, finance, export, and note tables.
  • Added domain models and Eloquent relationships.
  • Added baseline factories for election hierarchy, positions, applications, and assignments.
  • Added PositionSeeder.
  • Added SampleElectionSeeder.
  • Updated DatabaseSeeder to seed roles, positions, Admin user, and sample election data.
  • Seeded sample election PRN2026.
  • Seeded one Bahagian Pilihanraya, one Daerah Mengundi, one Pusat Mengundi, and three Saluran Mengundi.
  • Seeded 9 default positions and 17 sample quotas.
  • Seeded sample Admin Kewangan, PPM, and KTM users.
  • Seeded sample dual-role assignment where one user is both PPM and KTM.
  • Seeded sample wheelchair allocation.
  • Added feature test for core domain seeder output and dual-role assignment.
  • Confirmed MySQL connection through Laravel/PDO.
  • Shortened long composite index names for MySQL compatibility.

Changed files:

  • database/migrations/2026_05_28_030000_create_phase2_core_domain_tables.php
  • app/Models/*.php
  • database/factories/*.php
  • database/seeders/DatabaseSeeder.php
  • database/seeders/PositionSeeder.php
  • database/seeders/SampleElectionSeeder.php
  • tests/Feature/CoreDomainSeederTest.php
  • docs/00-project-brief.md
  • docs/01-development-plan.md
  • docs/03-database-design.md
  • docs/07-testing-plan.md
  • docs/08-deployment-notes.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan migrate:fresh --seed passed on MySQL database prn2026.
  • php artisan test passed: 28 tests, 80 assertions.
  • vendor\bin\pint.bat --test passed.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.

Manual testing:

  • Log in as admin@prn.local / password.
  • Confirm base dashboard loads after fresh seed.
  • Optional sample accounts:
    • kewangan@prn.local / password
    • ppm@prn.local / password
    • ktm@prn.local / password
  • Confirm /dashboard redirects based on each user's role.

Pending items:

  • Phase 3 Admin setup module UI and CRUD.
  • Implement policy-level ownership checks when domain UI routes are added.
  • Add business-rule services for vacancy and registration period calculations in later phases.

Next step:

  • Phase 3: Admin setup module for CRUD Bahagian, Daerah, Pusat, Saluran, Jawatan/quota setup, PPM assignment, and QR generation.

2026-05-29 - Phase 3: Admin Setup Module

Status: Completed

Completed:

  • Added Admin setup routes under /admin/setup.
  • Added setup overview page.
  • Added CRUD controllers, Form Requests, and Blade views for Bahagian Pilihanraya, Daerah Mengundi, Pusat Mengundi, Saluran Mengundi, Jawatan, and Kekosongan Jawatan.
  • Added Pusat Mengundi detail page with saluran list, QR registration link, QR preview, and PPM assignment form.
  • Added QR generation service using public UUID registration URLs.
  • Added Admin-protected QR SVG serving route.
  • Added public QR placeholder route /pohon/{pusatMengundi:public_uuid}.
  • Added PPM assignment service using staff_assignments, assignment history, RBAC role assignment, and activity logging.
  • Added quota validation to prevent assigning a Saluran Mengundi from a different Pusat Mengundi.
  • Added public Blade layout for QR-facing pages.
  • Linked Admin dashboard action to Election setup.
  • Added feature tests for Admin setup module behavior.

Changed files:

  • app/Http/Controllers/Admin/Setup/AdminSetupController.php
  • app/Http/Controllers/Admin/Setup/BahagianPilihanrayaController.php
  • app/Http/Controllers/Admin/Setup/DaerahMengundiController.php
  • app/Http/Controllers/Admin/Setup/PositionController.php
  • app/Http/Controllers/Admin/Setup/PositionQuotaController.php
  • app/Http/Controllers/Admin/Setup/PusatMengundiController.php
  • app/Http/Controllers/Admin/Setup/SaluranMengundiController.php
  • app/Http/Controllers/DashboardController.php
  • app/Http/Controllers/PublicApplicationPlaceholderController.php
  • app/Http/Requests/Admin/Setup/*.php
  • app/Services/Admin/PpmAssignmentService.php
  • app/Services/Admin/PusatQrCodeService.php
  • resources/views/admin/setup/**/*.blade.php
  • resources/views/dashboards/index.blade.php
  • resources/views/layouts/public.blade.php
  • resources/views/public/application-placeholder.blade.php
  • routes/web.php
  • tests/Feature/AdminSetupTest.php
  • docs/01-development-plan.md
  • docs/05-workflow-design.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 65 routes.
  • php artisan test --filter=AdminSetupTest passed: 4 tests, 24 assertions.
  • php artisan test passed: 32 tests, 104 assertions.
  • vendor\bin\pint.bat --test passed.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as admin@prn.local / password.
  • Open /admin/setup.
  • Create or edit Bahagian, Daerah, Pusat, Saluran, Jawatan, and Kuota records.
  • Open a Pusat Mengundi detail page, generate QR, and assign PPM.
  • Open the generated /pohon/{uuid} public link and confirm it shows the intended Pusat Mengundi.
  • Log in as ktm@prn.local / password and confirm /admin/setup is forbidden.

Pending items:

  • Full public application form and document upload in Phase 4.
  • Registration-period enforcement for public and KTM-created applications in Phase 4 and Phase 6.
  • Representative management for Police, KKM, and JKM in the later Admin management phase.
  • Rich filters for very large setup lists if operational data volume requires them.

Next step:

  • Phase 4: Public application module using QR link, registration-period rules, document uploads, KTM selection for KP/KPDP, and duplicate IC blocking.

2026-05-29 - Phase 4: Public Application Module

Status: Completed

Completed:

  • Replaced QR placeholder flow with public application form on /pohon/{pusatMengundi:public_uuid}.
  • Added public success page using application public UUID.
  • Added RegistrationPeriodService for registration open/closed checks.
  • Added KtmVacancyService for KP/KPDP KTM selection and vacancy calculation.
  • Added PublicApplicationSubmissionService for transactional application creation, private document storage, status history, bank verification initialization, and activity logging.
  • Added StorePublicApplicationRequest with validation for applicant fields, IC normalization, required documents, public roles, duplicate IC, KTM-created blocking rule, and KTM vacancy recheck.
  • Added responsive public Blade form for applicant details, role selection, KTM selection, bank data, and document upload.
  • Added closed-registration page.
  • Stored IC document and bank statement metadata in application_documents.
  • Created pending bank_verifications row for public submissions.
  • Added Phase 4 feature tests and unit tests.

Changed files:

  • app/Http/Controllers/PublicApplicationController.php
  • app/Http/Requests/Public/StorePublicApplicationRequest.php
  • app/Services/RegistrationPeriodService.php
  • app/Services/Public/KtmVacancyService.php
  • app/Services/Public/PublicApplicationSubmissionService.php
  • resources/views/layouts/public.blade.php
  • resources/views/public/applications/create.blade.php
  • resources/views/public/applications/closed.blade.php
  • resources/views/public/applications/success.blade.php
  • routes/web.php
  • tests/Feature/PublicApplicationTest.php
  • tests/Unit/KtmVacancyServiceTest.php
  • tests/Unit/RegistrationPeriodServiceTest.php
  • docs/01-development-plan.md
  • docs/03-database-design.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 67 routes.
  • php artisan test --filter=PublicApplicationTest passed: 6 tests, 27 assertions.
  • php artisan test passed: 41 tests, 137 assertions.
  • vendor\bin\pint.bat --test passed.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • npm.cmd run build passed.

Manual testing:

  • Open a generated /pohon/{uuid} QR link.
  • Submit a KTM or PAPM application with IC document and bank statement.
  • Submit KP with an available KTM selection.
  • Try submitting without IC document or bank statement and confirm validation blocks it.
  • Set registration end date to a past date and confirm public form shows closed-registration message.
  • Create a created_by_ktm application for an IC and confirm public self-registration with the same IC is blocked.

Pending items:

  • Phase 5 PPM review, approval/rejection, role change, and assignment of submitted public applications.
  • Phase 6 KTM-created application deletion flow and email notification.
  • Authorized document viewing/downloading for PPM/Admin/Admin Kewangan.
  • Public application status portal if later required.

Next step:

  • Phase 5: PPM review and assignment module.

2026-05-29 - Phase 5: PPM Review and Assignment Module

Status: Completed

Completed:

  • Added PPM application review routes under /ppm/applications.
  • Added PPM-scoped application list and detail screens.
  • Added ApplicationPolicy and PpmScopeService for record-level PPM access control.
  • Added PpmApplicationReviewService for transactional approve/reject behavior.
  • Added AssignmentVacancyService for Pusat/Saluran quota checks.
  • Extended KtmVacancyService to ignore the current application during PPM approval vacancy checks.
  • Added PPM approval form allowing role change before approval.
  • Implemented KTM assignment to available Saluran Mengundi.
  • Implemented KP/KPDP assignment to active KTM with remaining vacancy.
  • Implemented PAPM assignment at Pusat Mengundi level.
  • Implemented rejection with required reason.
  • Added authorized private document download for PPM-owned applications.
  • Added PPM dashboard metrics and link to the review queue.
  • Added representative display sections for Police, KKM, and JKM records.
  • Added AuthorizesRequests to the base controller for policy authorization.
  • Added Phase 5 feature tests.

Changed files:

  • app/Http/Controllers/Controller.php
  • app/Http/Controllers/DashboardController.php
  • app/Http/Controllers/Ppm/ApplicationReviewController.php
  • app/Http/Requests/Ppm/ApproveApplicationRequest.php
  • app/Http/Requests/Ppm/RejectApplicationRequest.php
  • app/Models/PusatMengundi.php
  • app/Policies/ApplicationPolicy.php
  • app/Services/Ppm/AssignmentVacancyService.php
  • app/Services/Ppm/PpmApplicationReviewService.php
  • app/Services/Ppm/PpmScopeService.php
  • app/Services/Public/KtmVacancyService.php
  • resources/views/ppm/applications/index.blade.php
  • resources/views/ppm/applications/show.blade.php
  • routes/web.php
  • tests/Feature/PpmApplicationReviewTest.php
  • docs/01-development-plan.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 72 routes.
  • php artisan test --filter=PpmApplicationReviewTest passed: 6 tests, 24 assertions.
  • php artisan test passed: 47 tests, 161 assertions.
  • vendor\bin\pint.bat --test passed.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as ppm@prn.local / password.
  • Open /ppm/applications.
  • Submit a public application through QR first, then confirm it appears in the PPM queue.
  • Open the application detail page and download uploaded documents.
  • Approve a KTM application into an available Saluran.
  • Approve a KP/KPDP application under an active KTM.
  • Change an applicant role before approval and confirm assignment is created.
  • Reject an application with a reason.
  • Confirm a PPM cannot access an application outside their assigned Pusat Mengundi.

Pending items:

  • Phase 6 KTM flow for KP registration/approval, deletion of KTM-created records, and email notification.
  • Admin/Admin Kewangan document viewing routes.
  • Admin global management and post-registration notes in Phase 7.
  • Attendance module in Phase 10.

Next step:

  • Phase 6: KTM flow for assigned Saluran, KP registration, KP approval, KTM-created deletion, and email notification.

2026-05-29 - Phase 6: KTM Flow

Status: Completed

Completed:

  • Added KTM application routes under /ktm/applications.
  • Added KtmScopeService for active KTM assignment ownership checks.
  • Added KtmApplicationService for KTM KP registration, KP approval, and KTM-created deletion.
  • Added queued Markdown Mailable KtmCreatedApplicantMail.
  • Added KTM team list showing assigned Saluran, active KP team members, and KP vacancy.
  • Added KTM KP registration form.
  • Added KTM application detail page with approve/delete actions.
  • Enforced KTM registration period on KP registration and approval.
  • Enforced KP-only creation and approval for KTM.
  • Enforced own-team-only approval/deletion.
  • Implemented source = created_by_ktm for KTM-created records.
  • Implemented delete flow that sets deleted_by_ktm, records status history, and soft deletes the KTM-created application.
  • Updated KTM dashboard with live metrics and navigation links.
  • Added Phase 6 feature tests.

Changed files:

  • app/Http/Controllers/DashboardController.php
  • app/Http/Controllers/Ktm/TeamController.php
  • app/Http/Requests/Ktm/RegisterKpApplicantRequest.php
  • app/Mail/KtmCreatedApplicantMail.php
  • app/Services/Ktm/KtmApplicationService.php
  • app/Services/Ktm/KtmScopeService.php
  • app/Services/Public/KtmVacancyService.php
  • resources/views/emails/ktm/created-applicant.blade.php
  • resources/views/ktm/applications/create.blade.php
  • resources/views/ktm/applications/index.blade.php
  • resources/views/ktm/applications/show.blade.php
  • routes/web.php
  • tests/Feature/KtmFlowTest.php
  • docs/01-development-plan.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 78 routes.
  • php artisan test --filter=KtmFlowTest passed: 6 tests, 25 assertions.
  • php artisan test passed: 53 tests, 186 assertions.
  • vendor\bin\pint.bat --test passed.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as ktm@prn.local / password.
  • Open /ktm/applications.
  • Confirm assigned Saluran and KP vacancy are shown.
  • Register a KP and confirm email is queued/sent according to local mail configuration.
  • Approve a KP under own team and confirm active assignment is created.
  • Try approving KP from another KTM team and confirm it is blocked.
  • Try approving a non-KP application and confirm it is blocked.
  • Set registration end date to the past and confirm KTM registration/approval is blocked.
  • Delete an unassigned KTM-created applicant and confirm public self-registration with the same IC is no longer blocked.

Pending items:

  • Phase 7 Admin global management/manual entry and post-registration notes.
  • Admin/Admin Kewangan document viewing routes.
  • Finance verification module in Phase 8.
  • Attendance module in Phase 10.

Next step:

  • Phase 7: Admin management and manual entry.

2026-05-29 - Phase 7: Admin Management and Manual Entry

Status: Completed

Completed:

  • Added Admin management routes under /admin/management.
  • Added Admin management overview dashboard.
  • Added global application list with filters.
  • Added Admin manual application entry with source = admin_manual.
  • Added Admin application edit screen.
  • Added direct assignment from Admin application edit screen.
  • Added global staff assignment list and assignment edit screen.
  • Added post-registration catatan enforcement through AdminPostCloseNoteService.
  • Added system_notes records for accepted post-closing Admin changes.
  • Added assignment/application history and activity log entries for Admin changes.
  • Added Police, KKM, and JKM representative entry/deletion screen.
  • Updated Admin dashboard with live counts and management module links.
  • Added Phase 7 feature tests.

Changed files:

  • app/Http/Controllers/Admin/Management/AdminManagementController.php
  • app/Http/Controllers/Admin/Management/ManagedApplicationController.php
  • app/Http/Controllers/Admin/Management/RepresentativeController.php
  • app/Http/Controllers/Admin/Management/StaffAssignmentController.php
  • app/Http/Controllers/DashboardController.php
  • app/Http/Requests/Admin/Management/*.php
  • app/Services/Admin/Management/*.php
  • resources/views/admin/management/**/*.blade.php
  • routes/web.php
  • tests/Feature/AdminManagementTest.php
  • docs/01-development-plan.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 91 routes.
  • php artisan test --filter=AdminManagementTest passed: 5 tests, 18 assertions.
  • php artisan test passed: 58 tests, 204 assertions.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • vendor\bin\pint.bat --test passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as admin@prn.local / password.
  • Open /admin/management.
  • Create a manual application.
  • Edit a manual or public application.
  • Direct assign an application to a Pusat, Saluran, or KTM team.
  • Edit an existing staff assignment.
  • Create Police, KKM, and JKM representative records.
  • Close the registration period for the election and confirm Admin changes require catatan.
  • Log in as kewangan@prn.local / password and confirm /admin/management/assignments is forbidden.

Pending items:

  • Admin document viewing route for IC/bank statement remains for the finance/document module.
  • Excel export implementation remains in later finance/export phases.
  • More granular representative edit forms can be added if operational users need inline correction instead of delete/recreate.

Next step:

  • Phase 8: Admin Kewangan module for bank verification, finance filters, and finance export.

2026-05-29 - Phase 8: Admin Kewangan

Status: Completed

Completed:

  • Added finance bank verification routes under /kewangan/bank.
  • Added Admin Kewangan list of approved/assigned staff bank records.
  • Added filters for status, Pusat Mengundi, role, missing bank statement, missing account number, and keyword.
  • Added bank verification detail screen.
  • Added finance status update with finance note, verified by, and verified at.
  • Added activity log for finance verification changes.
  • Added sensitive display masking helper.
  • Added finance XLSX export using OpenSpout.
  • Added export log creation for finance exports.
  • Updated Admin Kewangan dashboard with live counts and module links.
  • Added Phase 8 feature tests.

Changed files:

  • app/Exports/FinanceVerificationExport.php
  • app/Http/Controllers/DashboardController.php
  • app/Http/Controllers/Kewangan/BankVerificationController.php
  • app/Http/Requests/Kewangan/UpdateBankVerificationRequest.php
  • app/Services/Finance/BankVerificationService.php
  • app/Services/Finance/FinanceExportService.php
  • app/Services/Finance/FinanceVerificationQuery.php
  • app/Support/SensitiveData.php
  • resources/views/kewangan/bank/index.blade.php
  • resources/views/kewangan/bank/show.blade.php
  • routes/web.php
  • tests/Feature/FinanceModuleTest.php
  • docs/01-development-plan.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 95 routes.
  • php artisan test --filter=FinanceModuleTest passed: 5 tests, 18 assertions.
  • php artisan test passed: 63 tests, 222 assertions.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • vendor\bin\pint.bat --test passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as kewangan@prn.local / password.
  • Open /kewangan/bank.
  • Filter records by Pusat, role, status, missing bank statement, and missing account number.
  • Open a bank verification record.
  • Mark it verified, rejected, or requires correction with a finance note.
  • Export the finance list and confirm a file downloads.
  • Confirm /admin/management/assignments is forbidden for Admin Kewangan.

Pending items:

  • Admin/Admin Kewangan authorized document download for bank statement remains to be added when document review UX is finalized.
  • Additional finance export formats can be added if official template is provided.

Next step:

  • Phase 9: Wheelchair management.

2026-05-29 - Phase 9: Wheelchair Management

Status: Completed

Completed:

  • Added Admin wheelchair management routes under /admin/management/wheelchairs.
  • Added allocation upsert per election and Pusat Mengundi.
  • Added wheelchair management service for allocation and transaction rules.
  • Added taken transaction recording with quantity, time, person taking, and notes.
  • Added return transaction recording with quantity, time, condition, and notes.
  • Added quantity guards for allocation, available balance, and outstanding return balance.
  • Added activity logging for allocation and transaction changes.
  • Added wheelchair list and detail screens.
  • Updated Admin management dashboard and navigation.
  • Added Phase 9 feature tests.

Changed files:

  • app/Http/Controllers/Admin/Management/AdminManagementController.php
  • app/Http/Controllers/Admin/Management/WheelchairController.php
  • app/Http/Requests/Admin/Management/StoreWheelchairTransactionRequest.php
  • app/Http/Requests/Admin/Management/UpsertWheelchairAllocationRequest.php
  • app/Services/Admin/Management/WheelchairManagementService.php
  • resources/views/admin/management/_nav.blade.php
  • resources/views/admin/management/index.blade.php
  • resources/views/admin/management/wheelchairs/index.blade.php
  • resources/views/admin/management/wheelchairs/show.blade.php
  • routes/web.php
  • tests/Feature/WheelchairManagementTest.php
  • docs/01-development-plan.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 100 routes.
  • php artisan test --filter=WheelchairManagementTest passed: 6 tests, 16 assertions.
  • php artisan test passed: 69 tests, 238 assertions.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • vendor\bin\pint.bat --test passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as admin@prn.local / password.
  • Open /admin/management/wheelchairs.
  • Create or update a wheelchair allocation for a Pusat Mengundi.
  • Open the allocation detail screen.
  • Record wheelchair taken transaction.
  • Record wheelchair returned transaction with condition baik or rosak.
  • Try taking more than available and confirm validation blocks it.
  • Try returning more than outstanding and confirm validation blocks it.
  • Try lowering allocation below outstanding and confirm validation blocks it.
  • Log in as kewangan@prn.local / password and confirm wheelchair management is forbidden.

Pending items:

  • Phase 10 attendance module.
  • Optional wheelchair export/report if later required.

Next step:

  • Phase 10: Attendance module.

2026-05-29 - Phase 10: Attendance Module

Status: Completed

Completed:

  • Added PPM attendance routes under /ppm/attendance.
  • Added PPM attendance list for assigned Pusat Mengundi.
  • Added PPM attendance recording screen for active staff under own Pusat Mengundi.
  • Added attendance activation guard using election_settings.is_attendance_active.
  • Added bulk attendance recording service.
  • Added activity log entries for attendance updates.
  • Added Admin attendance routes under /admin/attendance.
  • Added Admin attendance dashboard by Pusat Mengundi.
  • Added Admin attendance detail view with staff, role, Saluran, status, check-in time, notes, and recorded by.
  • Added attendance summary service with totals and role-level summary.
  • Added attendance detail XLSX export using OpenSpout.
  • Added export log creation for attendance exports.
  • Updated Admin and PPM dashboard links/metrics.
  • Added Phase 10 feature and unit tests.

Changed files:

  • app/Exports/AttendanceDetailExport.php
  • app/Http/Controllers/Admin/AttendanceController.php
  • app/Http/Controllers/DashboardController.php
  • app/Http/Controllers/Ppm/AttendanceController.php
  • app/Http/Requests/Ppm/RecordAttendanceRequest.php
  • app/Services/Attendance/AttendanceExportService.php
  • app/Services/Attendance/AttendanceRecordingService.php
  • app/Services/Attendance/AttendanceSummaryService.php
  • resources/views/admin/attendance/index.blade.php
  • resources/views/admin/attendance/show.blade.php
  • resources/views/ppm/attendance/index.blade.php
  • resources/views/ppm/attendance/show.blade.php
  • routes/web.php
  • tests/Feature/AttendanceModuleTest.php
  • tests/Unit/AttendanceSummaryServiceTest.php
  • docs/01-development-plan.md
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/07-testing-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan route:list --except-vendor passed and shows 106 routes.
  • php artisan test --filter=Attendance passed: 7 tests, 21 assertions.
  • php artisan test passed: 76 tests, 259 assertions.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • vendor\bin\pint.bat --test passed.
  • npm.cmd run build passed.

Manual testing:

  • Activate attendance for the election in database/settings.
  • Log in as ppm@prn.local / password.
  • Open /ppm/attendance.
  • Record present/absent/not recorded statuses for staff under own Pusat Mengundi.
  • Confirm PPM cannot access or record another Pusat Mengundi.
  • Log in as admin@prn.local / password.
  • Open /admin/attendance.
  • View Pusat Mengundi summary and detail.
  • Export attendance detail and confirm file downloads.
  • Log in as kewangan@prn.local / password and confirm Admin attendance dashboard is forbidden.

Pending items:

  • Admin settings UI to toggle is_attendance_active if operational users need UI control.
  • Official attendance report template can replace the current export layout when provided.

Next step:

  • Phase 11: Testing, polish, security review, performance review, and final hardening.

2026-05-29 - Phase 11: Testing, Polish, and Hardening

Status: Completed

Completed:

  • Reviewed authorization, private document access, sensitive data masking, exports, and quality gates.
  • Added Admin document download route for private application documents.
  • Added Admin Kewangan bank statement download route.
  • Restricted finance document downloads to bank_statement only.
  • Added activity logging for Admin and finance document downloads.
  • Added secure document links to Admin application edit and finance bank detail screens.
  • Added feature tests for Admin/Admin Kewangan/unauthorized document access.
  • Added unit test for sensitive data masking.
  • Updated deployment notes with final quality gate commands and document storage hardening notes.
  • Updated Phase 11 documentation and release notes.

Changed files:

  • app/Http/Controllers/DocumentDownloadController.php
  • app/Http/Controllers/Admin/Management/ManagedApplicationController.php
  • resources/views/admin/management/applications/edit.blade.php
  • resources/views/kewangan/bank/show.blade.php
  • routes/web.php
  • tests/Feature/DocumentDownloadAuthorizationTest.php
  • tests/Unit/SensitiveDataTest.php
  • docs/01-development-plan.md
  • docs/07-testing-plan.md
  • docs/08-deployment-notes.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Verification:

  • php artisan test --filter=DocumentDownloadAuthorizationTest passed: 3 tests, 4 assertions.
  • php artisan test --filter=SensitiveDataTest passed: 1 test, 4 assertions.
  • php artisan route:list --except-vendor passed and shows 108 routes.
  • php artisan test passed: 80 tests, 267 assertions.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G passed.
  • vendor\bin\pint.bat --test passed.
  • npm.cmd run build passed.

Manual testing:

  • Log in as admin@prn.local / password.
  • Open an application with uploaded documents and download IC/bank documents.
  • Log in as kewangan@prn.local / password.
  • Open bank verification detail and download bank statement.
  • Confirm Admin Kewangan cannot download IC document through finance document route.
  • Run end-to-end smoke test from QR application to attendance export.

Pending items:

  • Replace current exports with official report templates if/when provided.
  • Add Admin UI toggle for attendance activation if operational users need it outside database/settings maintenance.

Next step:

  • Production readiness review with real environment credentials, mail transport, queue worker, HTTPS, backup plan, and user acceptance testing.

2026-05-31 - Penambahbaikan daftar Pusat Mengundi

Selesai

  • Membuang keperluan nama Saluran daripada borang dan validasi setup Saluran.
  • Menambah sepuluh input bilangan operasi pada borang daftar Pusat Mengundi.
  • Menjana Saluran bernombor serta kuota Pusat dan Saluran secara automatik semasa daftar Pusat.
  • Menukar istilah Calon Simpanan kepada Calon Tambahan dengan migrasi data.
  • Menambah ujian ciri untuk penciptaan Pusat, Saluran tanpa nama dan kuota operasi.

Fail berubah

  • app/Services/Admin/PusatOperationalSetupService.php
  • app/Http/Controllers/Admin/Setup/PusatMengundiController.php
  • app/Http/Requests/Admin/Setup/UpsertPusatMengundiRequest.php
  • app/Http/Requests/Admin/Setup/UpsertSaluranMengundiRequest.php
  • resources/views/admin/setup/pusat/_form.blade.php
  • resources/views/admin/setup/saluran/_form.blade.php
  • database/migrations/2026_05_31_000000_rename_calon_simpanan_position_to_calon_tambahan.php
  • database/seeders/PositionSeeder.php
  • database/seeders/SampleElectionSeeder.php
  • tests/Feature/Admin/PusatOperationalSetupTest.php

Semakan manual

  • Buka /admin/setup/pusat/create, pastikan sepuluh medan bilangan operasi dipaparkan.
  • Daftar Pusat baharu dan pastikan Saluran bernombor dijana tanpa meminta nama Saluran.

Seterusnya

  • Jalankan migrasi, ujian automatik dan semakan statik selepas shell runner tersedia.

2026-06-02 - Perancangan Fasa 1215: Pembetulan dan Penambahbaikan

Status: Selesai (perancangan)

Selesai:

  • Menjalankan semakan kod menyeluruh ke atas keseluruhan sistem selepas Phase 11 dan penambahbaikan 2026-05-31.
  • Mengenal pasti lapan isu meliputi keselamatan, prestasi, pengalaman pengguna, dan pengurusan data.
  • Menyusun isu-isu tersebut kepada empat fasa penambahbaikan berprioritikan (Fasa 1215).
  • Mendokumentasikan plan penuh dalam docs/09-improvement-plan.md.
  • Mengemas kini docs/01-development-plan.md dengan ringkasan Fasa 1215.

Fail berubah:

  • docs/09-improvement-plan.md (baharu)
  • docs/01-development-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Isu yang dikenal pasti:

  • 12-A: Tiada UI toggle untuk is_attendance_active dan is_registration_open_override — memerlukan edit database terus dalam produksi.
  • 12-B: Semakan IC duplikasi mungkin tidak mengecualikan soft-deleted records secara eksplisit dan konsisten.
  • 12-C: AdminPostCloseNoteService boleh dipintas jika controller baharu lupa memanggilnya.
  • 12-D: SampleElectionSeeder mungkin masih mengandungi rujukan kepada CALON_SIMPANAN selepas migration rename Phase 11.
  • 12-E: Semakan jenis dokumen pada path download tidak sepenuhnya konsisten antara peranan.
  • 13-A: Composite indexes belum wujud pada applications, staff_assignments, bank_verifications — boleh perlahan apabila data besar.
  • 14-A: Tiada halaman status permohonan untuk pemohon awam — mereka perlu hubungi Admin untuk semak status.
  • 15-A: Fail XLSX eksport sensitif disimpan tanpa had masa — polisi purge automatik diperlukan.

Seterusnya:

  • Mulakan Fasa 12 dengan 12-A (Admin Settings UI) kerana ia paling mendesak untuk kebolehgunaan dalam persekitaran produksi.

2026-06-02 - Fasa 12-A: Admin Settings UI dan 12-D: Pembetulan Seeder

Status: Selesai

Selesai:

  • Tambah halaman Admin Settings di /admin/setup/settings/{election} untuk toggle is_attendance_active dan is_registration_open_override tanpa perlu edit database.
  • Tambah ElectionSettingsController, ElectionSettingsService, UpdateElectionSettingsRequest.
  • Tambah view admin/setup/settings/edit.blade.php dengan toggle radio untuk kedua-dua tetapan, badge status semasa, dan amaran override aktif.
  • Tambah pautan "Tetapan" (kuning) ke admin/setup/_nav.blade.php dan setup index actions.
  • Perubahan tetapan direkod dalam activity_log dengan nilai sebelum dan selepas.
  • Betulkan bug 12-D: SampleElectionSeeder::seedQuotas() masih query CALON_SIMPANAN — ditukar kepada CALON_TAMBAHAN.
  • Betulkan AdminSetupTest: tambah medan operasi yang diperlukan untuk pusat.store, dan tukar nombor saluran dari '1' ke '3' untuk elak konflik dengan saluran auto-jana.
  • Betulkan anotasi PHPDoc pada UpdateElectionSettingsRequest::prepareForValidation().
  • Tambah anotasi @var ElectionSetting pada ElectionSettingsService untuk PHPStan.
  • Jalankan pint (auto-fix 2 fail) dan phpstan (0 error).

Fail berubah:

  • app/Http/Controllers/Admin/Setup/ElectionSettingsController.php (baharu)
  • app/Http/Requests/Admin/Setup/UpdateElectionSettingsRequest.php (baharu)
  • app/Services/Admin/ElectionSettingsService.php (baharu)
  • resources/views/admin/setup/settings/edit.blade.php (baharu)
  • resources/views/admin/setup/_nav.blade.php
  • resources/views/admin/setup/index.blade.php
  • routes/web.php
  • database/seeders/SampleElectionSeeder.php
  • tests/Feature/Admin/ElectionSettingsTest.php (baharu)
  • tests/Feature/AdminSetupTest.php
  • docs/04-rbac-permission-matrix.md
  • docs/05-workflow-design.md
  • docs/09-improvement-plan.md
  • docs/decision-log.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan route:list --except-vendor — 110 routes (tambah 2).
  • php artisan test — 90 tests, 310 assertions (selesai, semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Seterusnya:

  • 12-B: Semak dan betulkan query IC duplikasi untuk pastikan soft-deleted records dikecualikan.
  • 12-C: Perkukuh enforcement nota catatan post-pendaftaran.
  • 12-E: Konsistensikan semakan jenis dokumen download.

2026-06-02 - Fasa 12-B: Pembetulan Semakan IC Soft-Deleted

Status: Selesai

Selesai:

  • Audit menyeluruh semua lokasi semakan IC duplikasi: StorePublicApplicationRequest::validateDuplicateIc(), KtmApplicationService::registerKp(), KtmVacancyService::remainingVacancy(), dan AssignmentVacancyService.
  • Disahkan bahawa kedua-dua query IC menggunakan SoftDeletes scope (mengecualikan deleted_at IS NOT NULL) DAN whereNotIn('status', ['cancelled', 'deleted_by_ktm']) — perlindungan dua lapis yang betul.
  • cancelled records: dikecualikan oleh whereNotIn sahaja (bukan soft-deleted).
  • deleted_by_ktm records: dikecualikan oleh kedua-dua SoftDeletes scope DAN whereNotIn (redundant safety layer).
  • Tambah comment eksplisit pada kedua-dua query IC untuk mendokumentasikan intent perlindungan dua lapis ini.
  • Tambah 2 ujian baharu dalam PublicApplicationTest:
    • test_public_registration_is_unblocked_after_ktm_deletes_applicant: KTM cipta rekod, KTM delete (soft-delete + status deleted_by_ktm), pemohon awam dengan IC yang sama boleh daftar semula.
    • test_cancelled_application_does_not_block_new_registration: Rekod cancelled (bukan soft-deleted) tidak menyekat pendaftaran IC yang sama.
  • KtmVacancyService dan AssignmentVacancyService disahkan betul — menggunakan whitelist status dan StaffAssignment queries tidak melibatkan soft-deleted Application records secara salah.

Fail berubah:

  • app/Http/Requests/Public/StorePublicApplicationRequest.php — tambah comment
  • app/Services/Ktm/KtmApplicationService.php — tambah comment
  • tests/Feature/PublicApplicationTest.php — tambah 2 ujian
  • docs/09-improvement-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan test — 92 tests, 316 assertions (semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Seterusnya:

  • 12-C: Perkukuh enforcement nota catatan post-pendaftaran.
  • 12-E: Konsistensikan semakan jenis dokumen download.

2026-06-02 - Fasa 12-C: Perkukuh Enforcement Nota Catatan Post-Pendaftaran

Status: Selesai

Selesai:

  • Audit semua 6 service methods yang mengubah rekod domain selepas pendaftaran tutup — kesemua sudah memanggil AdminPostCloseNoteService::requireIfClosed() dengan betul.
  • Masalah: enforcement bergantung pada konvensyen — controller baharu boleh lupa panggil service tersebut.
  • Tambah middleware RequireAdminPostCloseNote sebagai safety net automatik pada route group admin/management.
  • Middleware menyemak election_id dari request body (untuk create routes) atau active election (untuk edit/delete routes). Jika pendaftaran ditutup dan note kosong, redirect balik dengan ralat validasi.
  • Daftarkan alias admin.post_close_note dalam bootstrap/app.php.
  • Apply middleware ke ['auth', 'role:Admin', 'admin.post_close_note'] dalam routes/web.php.
  • Tambah 5 ujian baharu dalam AdminManagementTest:
    • test_admin_create_application_after_registration_closed_requires_catatan
    • test_admin_update_assignment_after_registration_closed_requires_catatan
    • test_admin_create_representative_after_registration_closed_requires_catatan
    • test_admin_delete_representative_after_registration_closed_requires_catatan
    • test_middleware_does_not_block_when_registration_is_open

Fail berubah:

  • app/Http/Middleware/RequireAdminPostCloseNote.php (baharu)
  • bootstrap/app.php — alias middleware baharu
  • routes/web.php — middleware pada route group management
  • tests/Feature/AdminManagementTest.php — tambah 5 ujian
  • docs/decision-log.md
  • docs/09-improvement-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan test — 97 tests, 337 assertions (semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Seterusnya:

  • 12-E: Konsistensikan semakan jenis dokumen download.

2026-06-02 - Fasa 13-A: Composite Indexes Pangkalan Data

Status: Selesai

Selesai:

  • Audit index sedia ada berbanding query kritikal dalam KtmVacancyService, AssignmentVacancyService, ManagedApplicationController, dan DashboardController.
  • Dapatan: dua index yang disenaraikan dalam plan sudah wujud — (election_id, ic_number) dan (election_id, pusat_mengundi_id, status) pada applications, serta dua index komposit pada staff_assignments.
  • bank_verifications tiada kolum election_id — index (election_id, status) yang diancangkan dalam plan tidak relevan dan tidak ditambah.
  • Tiga index baharu yang benar-benar diperlukan ditambah melalui migration 2026_06_02_000000_add_performance_indexes.php:
    • applications.app_election_status_idx(election_id, status) untuk dashboard count queries
    • applications.app_ktm_position_idx(selected_ktm_assignment_id, requested_position_id) untuk KtmVacancyService reserved count
    • staff_assignments.sa_reports_to_pos_status_idx(reports_to_assignment_id, position_id, status) untuk KtmVacancyService assigned count
  • Dokumentasi index lengkap ditambah dalam docs/03-database-design.md.
  • Arahan verifikasi index dengan SHOW INDEX dan EXPLAIN ditambah dalam docs/08-deployment-notes.md.

Fail berubah:

  • database/migrations/2026_06_02_000000_add_performance_indexes.php (baharu)
  • docs/03-database-design.md
  • docs/08-deployment-notes.md
  • docs/decision-log.md
  • docs/09-improvement-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan migrate — lulus, 2 migration dijalankan.
  • php artisan test — 97 tests, 337 assertions (semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Seterusnya:

  • 12-E: Konsistensikan semakan jenis dokumen download.
  • Fasa 14: Portal status permohonan pemohon awam.
  • Fasa 15: Purge automatik fail eksport sensitif.

2026-06-02 - Fasa 12-E: Konsistensikan Semakan Jenis Dokumen Download

Status: Selesai

Selesai:

  • Audit tiga path download dokumen — PPM, Admin, Finance (Admin Kewangan).
  • Dapatan:
    • PPM: tiada type check eksplisit, tiada activity log, ownership failure pakai 404 (patut 403).
    • Admin: tiada type check eksplisit (senyap allow semua jenis).
    • Finance: sudah betul — explicit bank_statement check, log activity, pakai 403.
  • Tambah ApplicationDocument::TYPE_IC_DOCUMENT, TYPE_BANK_STATEMENT, ALLOWED_FOR_ADMIN, ALLOWED_FOR_PPM, ALLOWED_FOR_FINANCE sebagai constants dalam model — satu tempat yang autoriti untuk semua rules.
  • Kemaskini DocumentDownloadController::admin() guna ALLOWED_FOR_ADMIN — jenis baharu perlu didaftarkan secara eksplisit untuk Admin dapat akses.
  • Kemaskini DocumentDownloadController::finance() guna ALLOWED_FOR_FINANCE — logik sama, kini guna constant.
  • Kemaskini ApplicationReviewController::downloadDocument():
    • Tambah ALLOWED_FOR_PPM type check → 403 jika jenis tidak dibenarkan.
    • Tukar ownership check dari 404 → 403 (tidak mendedahkan kewujudan ID dokumen).
    • Tambah activity log document_downloaded_by_ppm.
  • Tambah 9 ujian baharu dalam DocumentDownloadAuthorizationTest meliputi semua tiga path dan kes utama:
    • Admin: ic_document ✓, bank_statement ✓, peranan tidak dibenarkan ✗.
    • Finance: bank_statement ✓, ic_document ✗.
    • PPM: ic_document (pusat sendiri) ✓, bank_statement (pusat sendiri) ✓, dokumen pusat lain ✗, activity log disimpan.

Fail berubah:

  • app/Models/ApplicationDocument.php — tambah type constants dan allowlist
  • app/Http/Controllers/DocumentDownloadController.php — explicit type checks via constants
  • app/Http/Controllers/Ppm/ApplicationReviewController.php — type check, 403, activity log
  • tests/Feature/DocumentDownloadAuthorizationTest.php — tulis semula dengan 9 ujian komprehensif
  • docs/04-rbac-permission-matrix.md
  • docs/decision-log.md
  • docs/09-improvement-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan test — 103 tests, 342 assertions (semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Seterusnya:

  • Fasa 14: Portal status permohonan pemohon awam.
  • Fasa 15: Purge automatik fail eksport sensitif.

2026-06-02 - Fasa 14-A: Portal Status Permohonan Pemohon Awam

Status: Selesai

Selesai:

  • Tambah route GET /permohonan/{publicUuid}/status tanpa route model binding untuk elak 404 mendedahkan kewujudan UUID.
  • Tambah PublicApplicationController::status() yang mengendalikan semua kes dengan selamat:
    • UUID tidak wujud → 200 dengan mesej generik.
    • Rekod soft-deleted → 200 dengan mesej generik.
    • Status deleted_by_ktm → 200 dengan mesej generik (tidak dedahkan status dalaman).
    • Rekod aktif → 200 dengan data terhad.
  • Tambah SensitiveData::maskName() — tunjuk 3 aksara pertama sahaja.
  • Cipta view public/applications/status.blade.php memaparkan: nama disamarkan, jawatan dipohon, jawatan diluluskan (jika berbeza), pusat mengundi, badge status dengan warna, sebab penolakan (jika ditolak), nombor rujukan UUID.
  • Kemaskini success.blade.php dengan panel simpan pautan status dan butang salin URL ke clipboard.
  • Tambah 9 ujian baharu dalam PublicApplicationStatusTest:
    • submitted, assigned, rejected (dengan sebab), UUID tidak dikenali, deleted_by_ktm, soft-deleted — semuanya.
    • Nama penuh tidak dipaparkan, IC tidak dipaparkan.
    • Halaman boleh dicapai tanpa log masuk.
    • Success page paparkan pautan status.

Fail berubah:

  • app/Http/Controllers/PublicApplicationController.php — tambah status()
  • app/Support/SensitiveData.php — tambah maskName()
  • resources/views/public/applications/status.blade.php (baharu)
  • resources/views/public/applications/success.blade.php — tambah panel pautan status
  • routes/web.php — route baharu
  • tests/Feature/PublicApplicationStatusTest.php (baharu)
  • docs/05-workflow-design.md
  • docs/06-ui-ux-plan.md
  • docs/decision-log.md
  • docs/09-improvement-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan test — 112 tests, 364 assertions (semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Seterusnya:

  • Fasa 15: Purge automatik fail eksport sensitif.

2026-06-02 - Fasa 15-A: Purge Automatik Fail Eksport Sensitif

Status: Selesai

Selesai:

  • Tambah kolum purged_at (nullable timestamp) dan purged_by_user_id (nullable FK) pada export_logs melalui migration 2026_06_02_000001_add_purged_at_to_export_logs.php.
  • Kemaskini model ExportLog dengan cast purged_at dan relationship purgedBy().
  • Cipta Artisan command ExportPurgeCommand (php artisan exports:purge --days=30):
    • Query export_logs di mana created_at < now - days DAN purged_at IS NULL.
    • Padam fail dari storage disk yang berkaitan.
    • Rekod yang filenya sudah tiada di disk tetap ditandakan purged_at supaya tidak diproses semula.
    • Log aktiviti export_file_purged untuk setiap rekod.
    • Lapor bilangan fail dipadamkan dan rekod tiada fail.
  • Daftarkan command sebagai scheduled task harian pada 00:00 dalam routes/console.php (--days=30, withoutOverlapping, runInBackground).
  • Tambah 7 ujian baharu dalam ExportPurgeCommandTest:
    • Fail lama dipadamkan, purged_at ditetapkan.
    • Fail dalam tempoh simpanan tidak disentuh.
    • Rekod tanpa fail (missing) tetap ditandakan purged_at.
    • Rekod yang sudah purged_at tidak diproses semula.
    • --days custom berfungsi.
    • Activity log direkod.
    • --days=0 gagal dengan exit code bukan 0.

Fail berubah:

  • database/migrations/2026_06_02_000001_add_purged_at_to_export_logs.php (baharu)
  • app/Models/ExportLog.php — tambah cast + relationship
  • app/Console/Commands/ExportPurgeCommand.php (baharu)
  • routes/console.php — scheduled task
  • tests/Feature/ExportPurgeCommandTest.php (baharu)
  • docs/03-database-design.md
  • docs/08-deployment-notes.md
  • docs/decision-log.md
  • docs/09-improvement-plan.md
  • docs/progress-log.md
  • docs/changelog.md

Semakan:

  • php artisan migrate — lulus.
  • php artisan test — 119 tests, 388 assertions (semua lulus).
  • vendor\bin\pint.bat --test — lulus.
  • vendor\bin\phpstan.bat analyse --memory-limit=1G — lulus, 0 error.

Semua fasa selesai (12-A hingga 15-A). Sistem sedia untuk UAT.