6.8 KiB
6.8 KiB
Initial Architecture
Technology Stack
- Backend: Laravel 13.12.0, installed through
laravel/laravel13.8.0. - Database: MySQL.
- Views: Blade.
- Styling: Bootstrap 5 with Bootstrap Icons.
- JavaScript: Vite-managed assets, jQuery where it improves progressive enhancement, plus selected UI helpers.
- Queue: Laravel queue system for email and heavier export-related tasks where useful.
- Mail: Laravel Mail and Notifications with Markdown mail templates.
- Authorization: Laravel policies, gates, middleware, and
spatie/laravel-permission. - Auditing:
spatie/laravel-activitylogplus domain-specific history tables where a structured audit timeline is needed. - Export: OpenSpout for current PHP 8.5 compatibility.
maatwebsite/excelremains the preferred package from the original requirement but was not installable in this environment during Phase 1.
Phase 1 Implemented Structure
Implemented:
- Breeze auth controllers and routes.
- Generic
/registerroutes disabled. - Bootstrap-based
layouts.app,layouts.guest, and navigation. - Role-aware dashboards:
/admin/dashboard/kewangan/dashboard/ppm/dashboard/ktm/dashboard/pemohon/dashboard
/dashboardrole redirect.- Spatie role middleware aliases:
rolepermissionrole_or_permission
RolePermissionSeeder.- Default Admin seed account from
config/prn.php.
Application Structure
Planned directories:
app/
Actions/
Exports/
Http/
Controllers/
Requests/
Middleware/
Models/
Notifications/
Policies/
Services/
Support/
Guidelines:
- Controllers orchestrate requests and responses only.
- Form Request classes validate input and authorize request-specific actions.
- Policies enforce model-level access.
- Services hold business rules and transactional workflows.
- Action classes may be used for high-value operations such as approving applications, changing assignments, registering KTM-created KP, and recording attendance.
- Export classes live in
app/Exports. - Report filters and query preparation live in services, not controllers.
Architectural Layers
Presentation Layer
- Blade templates with Bootstrap 5.
- Responsive layouts for desktop, tablet, and mobile.
- Shared layout components for navigation, cards, filters, badges, breadcrumbs, tables, empty states, and modals.
- Mobile-friendly table alternatives for high-density data.
HTTP Layer
- Named routes.
- Route groups by role and module.
- Middleware for authentication, role, registration period, and public QR validation.
- Route model binding using internal IDs for authenticated admin areas where safe.
- Public routes use UUID/ULID identifiers only.
Domain Layer
Core services:
RegistrationPeriodServiceVacancyServiceApplicationServiceAssignmentServiceKtmTeamServicePpmScopeServiceBankVerificationServiceAttendanceServiceWheelchairServiceExportLoggingServiceSensitiveDataMaskingService
Potential action classes:
SubmitPublicApplicationCreateKtmApplicantApproveApplicationRejectApplicationChangeApplicantRoleAssignStaffToSaluranRecordAttendanceVerifyBankDetailsRecordWheelchairTransaction
Data Layer
- Eloquent models and relationships.
- Foreign keys for domain integrity.
- Soft deletes for records that should remain auditable.
- Domain history tables for applications and assignments.
- Activity log for actor/value snapshots and operational traceability.
Role-Based Areas
Planned route groups:
/dashboard
/admin/...
/ppm/...
/ktm/...
/kewangan/...
/pohon/{pusat_mengundi_uuid}
Expected access:
Admin: full operational management.Admin Kewangan: finance verification and finance exports only.PPM: assigned Pusat Mengundi only.KTM: assigned Saluran/team only.Pemohon: public form and own submission flow only if login is later required.
Public Identifier Strategy
- Public QR links must use UUID or ULID stored on
pusat_mengundis.public_uuidor equivalent. - Internal auto-increment IDs must not appear in public application URLs.
- Uploaded documents are accessed only through authenticated authorization checks and signed/temporary download responses where needed.
Dual-Role Assignment Strategy
The system must support a PPM who is also KTM. This should not be modeled as a single role column on a user or application.
Planned approach:
- Use
usersfor login identity. - Use
applicationsor staff records for applicant/staff biographical and banking data. - Use
staff_assignmentsas the canonical placement table. - A person can have multiple active
staff_assignmentswithin the same election when business rules allow it. staff_assignmentsreferencesposition_id,pusat_mengundi_id, optionalsaluran_mengundi_id, and optional supervisor/team references.- Uniqueness constraints prevent invalid duplicate active assignments, while allowing explicitly permitted dual role such as PPM + KTM.
Audit Strategy
Use two audit levels:
- Structured domain histories for application status and assignment changes.
- General activity log for before/after data changes, actor, timestamp, source, and notes.
Audit targets:
- Application approval/rejection.
- Role changes.
- Assignment changes.
- Document upload/change.
- Bank verification.
- Admin edits after registration closes.
- Attendance updates.
- Wheelchair transactions.
- Excel exports.
File Storage Strategy
- IC documents and bank statements are stored on Laravel private storage disk.
- Public symlink storage must not expose sensitive uploads.
- File validation must restrict MIME type, size, and extension.
- Document access must pass policy checks.
- File records should be stored in
application_documentswith document type, disk, path, original name, MIME type, size, uploader, and timestamps.
Export Strategy
maatwebsite/excelwill generate XLSX exports.- Every export inserts a row into
export_logs. - Export logs include generated_by, generated_at, report_type, filter parameters, and file name.
- Export services prepare queries and filters.
- Export classes only shape spreadsheet data.
Queue and Mail Strategy
- KTM-created applicant email notification should use Laravel Notifications or Mailables.
- Queue should be enabled for mail in production.
- Local development can use log mailer or local mail catcher.
- Admin-keyed records do not trigger bank account email requests.
Security Principles
- Use CSRF protection for all form submissions.
- Use policies and middleware for every protected module.
- Validate uploads strictly.
- Store sensitive files privately.
- Mask IC, bank account, phone, and email where full values are unnecessary.
- Avoid raw SQL unless justified and documented.
- Use transactions for approval, assignment, finance verification, and attendance updates.