first
This commit is contained in:
209
docs/02-architecture.md
Normal file
209
docs/02-architecture.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# Initial Architecture
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- Backend: Laravel 13.12.0, installed through `laravel/laravel` 13.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-activitylog` plus domain-specific history tables where a structured audit timeline is needed.
|
||||
- Export: OpenSpout for current PHP 8.5 compatibility. `maatwebsite/excel` remains 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 `/register` routes disabled.
|
||||
- Bootstrap-based `layouts.app`, `layouts.guest`, and navigation.
|
||||
- Role-aware dashboards:
|
||||
- `/admin/dashboard`
|
||||
- `/kewangan/dashboard`
|
||||
- `/ppm/dashboard`
|
||||
- `/ktm/dashboard`
|
||||
- `/pemohon/dashboard`
|
||||
- `/dashboard` role redirect.
|
||||
- Spatie role middleware aliases:
|
||||
- `role`
|
||||
- `permission`
|
||||
- `role_or_permission`
|
||||
- `RolePermissionSeeder`.
|
||||
- Default Admin seed account from `config/prn.php`.
|
||||
|
||||
## Application Structure
|
||||
|
||||
Planned directories:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
- `RegistrationPeriodService`
|
||||
- `VacancyService`
|
||||
- `ApplicationService`
|
||||
- `AssignmentService`
|
||||
- `KtmTeamService`
|
||||
- `PpmScopeService`
|
||||
- `BankVerificationService`
|
||||
- `AttendanceService`
|
||||
- `WheelchairService`
|
||||
- `ExportLoggingService`
|
||||
- `SensitiveDataMaskingService`
|
||||
|
||||
Potential action classes:
|
||||
|
||||
- `SubmitPublicApplication`
|
||||
- `CreateKtmApplicant`
|
||||
- `ApproveApplication`
|
||||
- `RejectApplication`
|
||||
- `ChangeApplicantRole`
|
||||
- `AssignStaffToSaluran`
|
||||
- `RecordAttendance`
|
||||
- `VerifyBankDetails`
|
||||
- `RecordWheelchairTransaction`
|
||||
|
||||
### 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:
|
||||
|
||||
```text
|
||||
/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_uuid` or 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 `users` for login identity.
|
||||
- Use `applications` or staff records for applicant/staff biographical and banking data.
|
||||
- Use `staff_assignments` as the canonical placement table.
|
||||
- A person can have multiple active `staff_assignments` within the same election when business rules allow it.
|
||||
- `staff_assignments` references `position_id`, `pusat_mengundi_id`, optional `saluran_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_documents` with document type, disk, path, original name, MIME type, size, uploader, and timestamps.
|
||||
|
||||
## Export Strategy
|
||||
|
||||
- `maatwebsite/excel` will 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.
|
||||
Reference in New Issue
Block a user