This commit is contained in:
Saufi
2026-06-03 08:51:22 +08:00
commit a14d43fe34
347 changed files with 38197 additions and 0 deletions

247
docs/08-deployment-notes.md Normal file
View File

@@ -0,0 +1,247 @@
# Deployment Notes
## Target Environment
The application is intended for a standard Laravel production deployment using:
- PHP compatible with selected Laravel version.
- Composer.
- MySQL.
- Web server such as Nginx or Apache.
- Node/npm only for building frontend assets, not necessarily required on production runtime if assets are built during deployment.
- Queue worker for mail and background jobs.
- Scheduler for Laravel scheduled tasks where needed.
## Local Environment Findings
Inspection date: 2026-05-28
- PHP CLI: 8.5.1.
- Composer: 2.9.4.
- Node: 25.1.0.
- npm works through `npm.cmd`; `npm` PowerShell shim is blocked by execution policy.
- MySQL CLI is not available in PATH and must be confirmed before database setup.
- `pdo_mysql` PHP extension is available.
- MySQL 8.4.8 connection was confirmed through Laravel/PDO during Phase 2.
- Local `.env` is configured for MySQL database `prn2026`.
## Environment Configuration
Required `.env` values:
```text
APP_NAME="Sistem Pengurusan Pusat Mengundi"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=
APP_TIMEZONE=Asia/Kuala_Lumpur
DB_CONNECTION=mysql
DB_HOST=
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
QUEUE_CONNECTION=database
MAIL_MAILER=
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME=
FILESYSTEM_DISK=local
SEED_ADMIN_NAME="Admin Sistem"
SEED_ADMIN_EMAIL=admin@prn.local
SEED_ADMIN_PASSWORD=password
```
Production must override the seeded Admin password before deployment or disable default seeding after the first secure Admin account is created.
## Storage
Sensitive documents:
- IC document.
- Bank statement.
Rules:
- Store sensitive documents on private disk.
- Do not expose sensitive uploads through public storage symlink.
- Serve document downloads through authorized controller actions only.
- Use secure file validation for MIME type, extension, and size.
## Deployment Steps
Initial production deployment should follow this sequence:
1. Pull or upload application source.
2. Install Composer dependencies without dev packages.
3. Install/build frontend assets.
4. Configure `.env`.
5. Generate app key if not already configured.
6. Run migrations.
7. Run seeders for roles, permissions, positions, and initial Admin user where appropriate.
8. Cache configuration, routes, and views.
9. Start queue worker.
10. Configure scheduler.
11. Validate login and critical workflows.
Planned commands:
```bash
composer install --no-dev --optimize-autoloader
npm.cmd ci
npm.cmd run build
php artisan key:generate
php artisan migrate --force
php artisan db:seed --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart
```
Commands may need adjustment for the actual hosting environment.
## Queue Worker
Queue should handle:
- KTM-created applicant email notifications.
- Potentially larger exports.
- Future notification jobs.
Recommended:
- Use database queue initially for simplicity.
- Use Supervisor, Windows service wrapper, or hosting panel worker support to keep queue running.
## Scheduler
Active scheduled tasks:
| Command | Schedule | Purpose |
|---|---|---|
| `exports:purge --days=30` | Daily at 00:00 | Purge export files older than 30 days |
To change the retention period, edit `routes/console.php` and update `--days=30`.
Scheduler entry (add to OS cron):
```bash
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
```
To run purge manually:
```bash
php artisan exports:purge --days=30
php artisan exports:purge --days=7 # shorter retention for testing
```
## Security Checklist
- `APP_DEBUG=false` in production.
- Strong database credentials.
- HTTPS enabled.
- Private document storage.
- Correct file permissions for storage and cache.
- Document downloads must use authorized controller routes; do not expose `storage/app/private`.
- Admin Kewangan document access is limited to bank statements.
- Queue worker runs under least-privilege user.
- Audit log retention policy defined.
- Regular backups.
- Admin accounts reviewed before launch.
- Default development accounts removed or password-changed.
## Index Verification After Migration
After running migrations on a fresh database, verify the performance indexes exist:
```sql
SHOW INDEX FROM applications WHERE Key_name IN (
'app_election_status_idx',
'app_ktm_position_idx'
);
SHOW INDEX FROM staff_assignments WHERE Key_name IN (
'sa_election_pusat_position_idx',
'sa_election_saluran_position_idx',
'sa_reports_to_pos_status_idx'
);
```
All of the above should return rows. If any are missing, re-run `php artisan migrate`.
Use `EXPLAIN` on critical service queries to confirm index usage:
```sql
-- KtmVacancyService: reserved application count
EXPLAIN SELECT * FROM applications
WHERE selected_ktm_assignment_id = ? AND requested_position_id = ?
AND status IN ('submitted', 'under_ppm_review', 'approved');
-- KtmVacancyService: active KP count under a KTM
EXPLAIN SELECT COUNT(*) FROM staff_assignments
WHERE reports_to_assignment_id = ? AND position_id = ? AND status = 'active';
```
Both should show `key` as the respective composite index, not NULL.
## Final Quality Gate
Run before production release:
```bash
php artisan route:list --except-vendor
php artisan test
vendor/bin/pint --test
vendor/bin/phpstan analyse --memory-limit=1G
npm.cmd run build
```
The Windows local environment uses `.bat` wrappers for vendor binaries:
```bash
vendor\bin\pint.bat --test
vendor\bin\phpstan.bat analyse --memory-limit=1G
```
## Backup Checklist
Back up:
- MySQL database.
- Private storage documents.
- Export files if retained.
- `.env` securely through infrastructure secret management, not public repository.
Recommended frequency:
- Daily database backups during active registration and polling period.
- More frequent backup before and on polling day.
- Storage backup aligned with database backups.
## Performance Notes
- Use server-side pagination for large lists.
- Add indexes for election, Pusat Mengundi, status, role, and IC lookup.
- Avoid loading documents or large relationship graphs on index pages.
- Use queued exports if datasets become large.
- Cache role/permission checks through Spatie package defaults.
- Keep attendance, finance, Admin management, and setup index pages paginated.
- For very large datasets, move XLSX exports to queued jobs and notify users when complete.
## Release Notes Process
Every deployment should update:
- `docs/changelog.md` for user-facing changes.
- `docs/progress-log.md` for implementation phase completion.
- `docs/decision-log.md` for architecture, database, security, and package decisions.