# Tech Stack

Daftar lengkap teknologi yang dipakai di proyek ini, beserta penjelasan singkat kegunaannya.

---

## 1. Runtime & Bahasa

| Teknologi | Versi | Kegunaan |
|-----------|-------|----------|
| **PHP** | 8.2+ | Bahasa utama backend. Kelas utility pakai `declare(strict_types=1)`. |
| **Node.js** | 20+ | Build asset frontend (Vite) + tooling mobile |
| **PostgreSQL** | 15+ | Database relasional utama (ACID-compliant). Skema pakai FK + cascade penuh. |
| **Redis** | 7.x | Cache, session store, queue, broadcast driver |

---

## 2. Framework Inti

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `laravel/framework` | ^13.0 | Framework PHP utama (routing, ORM, middleware, dll) |
| `laravel/sanctum` | ^4.0 | Autentikasi API berbasis token untuk mobile app |
| `laravel/socialite` | ^5.24 | OAuth login (Google, Facebook, GitHub) |
| `laravel/reverb` | ^1.10 | WebSocket server native untuk notifikasi real-time |
| `laravel/pulse` | ^1.7 | Monitoring performa app (request, queue, cache, slow queries) |
| `laravel/horizon` | ^5.46 | Queue dashboard (Redis-backed) |
| `laravel/breeze` | ^2.3 | Scaffolding autentikasi (login, register, reset password) |
| `laravel/tinker` | ^3.0 | REPL interaktif untuk debugging via terminal |

---

## 3. Database & Storage

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `predis/predis` | ^3.4 | Client PHP untuk Redis (PSR-compliant) |
| `masbug/flysystem-google-drive-ext` | ^2.5 | Driver Flysystem untuk Google Drive (backup) |

> Driver S3 sudah built-in di Laravel — cukup set `FILESYSTEM_DISK=s3` di `.env`.

### Skema database

- 40+ tabel, semua bermigrasi (lihat `database/migrations/`).
- FK constraint penuh: audit `created_by`/`updated_by` → `users(id) ON DELETE SET NULL`; data milik user → `ON DELETE CASCADE` (lihat `2026_05_14_110000_add_fk_to_audit_columns.php`).
- Composite indexes pada tabel hot (`password_histories`, `system_setting_revisions`, `notifications`) — lihat `2026_05_14_100000_add_performance_indexes.php`.
- **Data retention otomatis** via Laravel `Prunable` trait pada 8 model + `telescope:prune` + `activitylog:clean`. Retention policy lengkap ada di `SECURITY.md`.

---

## 4. Autentikasi & Keamanan

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `laragear/webauthn` | ^5.0 | Passkey / biometric login (FIDO2/WebAuthn) — ⚠️ marked abandoned upstream; replacement: `laravel/passkeys` |
| `anhskohbo/no-captcha` | ^3.7 | Integrasi Google reCAPTCHA v2/v3 di form login |

### Built-in (no extra package)

- **2FA via email OTP** + trust-device cookie (file: `app/Http/Controllers/Auth/TwoFactorController.php`)
- **Password policy** — `App\Services\Auth\PasswordPolicyService` (min/max/charset/expiry/history-reuse-block)
- **IP access control** — `app/Http/Middleware/IpAccessControl.php` (blacklist, admin whitelist, auto-block on burst, HSTS toggle)
- **Security headers** — `app/Http/Middleware/SecurityHeaders.php` (X-Frame, X-CTO, Referrer, Permissions-Policy, X-XSS, HSTS)
- **Session manager** — list & force-logout active sessions
- **Impersonate** — `ImpersonateController` dengan guard self/Developer/inactive + loop prevention
- **Single-session enforcement** opsional (di-toggle dari Global Settings)

---

## 5. Manajemen Hak Akses & Audit (Spatie)

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `spatie/laravel-permission` | ^6.24 | Sistem role & permission granular |
| `spatie/laravel-activitylog` | ^4.10 | Audit trail — mencatat perubahan data |
| `spatie/laravel-backup` | ^10.2 | Backup database & file ke Local/S3/GDrive |
| `spatie/laravel-medialibrary` | ^11.21 | Upload & manajemen file media (avatar, dokumen) |

---

## 5b. Dashboard Widget System

Per-user persisted widget layout. Architecture:

| Layer | Class / File | Fungsi |
|-------|-------------|--------|
| Model | `DashboardWidgetPreference` | `forUser()` merge defaults + DB prefs, sorted by `sort_order` |
| Migration | `2026_05_16_220000_create_dashboard_widget_preferences_table` | `user_id` FK cascade, unique `(user_id, widget_key)` |
| Controller | `DashboardController@saveWidgetPreferences` | upsert prefs via `updateOrCreate` |
| Controller | `DashboardController@resetWidgetPreferences` | delete all prefs → restore defaults |
| Route | `POST /dashboard/widgets` (`dashboard.widgets.save`) | — |
| Partials | `resources/views/pages/dashboard/widget-*.blade.php` | cpu, ram, disk, live-users, queues, quick-actions |
| JS | SortableJS (CDN) | drag-to-reorder grid |
| Broadcasting | `DashboardStatsUpdated` event → Reverb → Echo | push stats every minute via `dashboard:broadcast-stats` |

### Sidebar Toggle

Sidebar submenus use **vanilla JS** `initSidebarSubmenus()` (bottom of `navigation.blade.php`). Uses `data-sidebar-toggle` attribute, `e.stopPropagation()`, and `cloneNode()` to replace buttons and prevent duplicate listeners. Does **not** depend on Alpine.js (theme JS conflict prevented Alpine `x-on:click` from working).

---

## 6. Modular & Arsitektur

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `nwidart/laravel-modules` | ^13.0 | Memisahkan fitur ke folder `Modules/` agar codebase rapi |

### Custom Exception Hierarchy

`App\Exceptions\*` — domain-specific exceptions instead of generic `\Exception`:

- `SystemConfigException::unknownKey()`, `::imageUploadFailed()`
- `BackupOperationException::missingBinary()`, `::diskNotConfigured()`, `::restoreFailed()`
- `MonitoringException::unsupportedOs()`, `::probeFailed()`

---

## 7. Admin Panel & API Docs

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `filament/filament` | ^5.5 | Admin panel builder (resource management cepat) |
| `darkaonline/l5-swagger` | ^11.0 | Auto-generate Swagger/OpenAPI docs dari annotation. Spec di `storage/api-docs/`. |

---

## 8. Monitoring & Error Tracking

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `sentry/sentry-laravel` | ^4.25 | Error monitoring & performance tracking untuk production |

> Set `SENTRY_LARAVEL_DSN` di `.env` untuk mengaktifkan. Log error otomatis terkirim ke Sentry dashboard.

Endpoint `GET /api/health` mengembalikan status `database`/`redis`/`storage`/`queue`. Kembalikan `503` hanya saat ada check yang `fail` — `warn` (disk >90%) tetap `200`.

---

## 9. Frontend Build

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `vite` | ^7.0 | Build tool — hot reload & bundling JS/CSS |
| `laravel-vite-plugin` | ^2.0 | Integrasi Vite dengan Blade |
| `tailwindcss` | ^4.2 | CSS utility-first |
| `@tailwindcss/forms` | ^0.5.2 | Plugin Tailwind untuk styling form |
| `alpinejs` | ^3.4 | Reactive JS ringan (toggle, modal, tabs) |
| `axios` | ^1.15 | HTTP client untuk AJAX |
| `laravel-echo` | ^2.3 | Client untuk subscribe ke WebSocket channel |
| `pusher-js` | ^8.5 | Transport layer untuk Echo (kompatibel Reverb) |
| `rollup` | ^4.60 | Module bundler (digunakan Vite secara internal) |
| `concurrently` | ^9.0 | Menjalankan beberapa command paralel saat dev |

### Dev Script (`composer run dev`)

Menjalankan beberapa proses secara paralel:

| Proses | Command |
|--------|---------|
| SERVER | `php artisan serve --host=0.0.0.0 --port=8000` |
| VITE | `npm run dev` |
| QUEUE | `php artisan queue:listen --tries=1` |

### Scheduled Tasks (Production)

| Waktu | Command | Fungsi |
|-------|---------|--------|
| Setiap menit | `dashboard:broadcast-stats` | Broadcast stats dashboard ke WebSocket channel `admin.monitoring` (withoutOverlapping) |
| Setiap menit | `MaintenanceManagementService::autoCheckAndRelease()` | Auto-release maintenance mode |
| Setiap menit | `WorkerHeartbeatJob` | Queue worker monitoring |
| Setiap 30 menit | `system:health-check` | System health check |
| Harian 03:00 | `model:prune` | Pruning OtpCode, UserTrustedDevice, AiHealingLog, PasswordHistory, dll |
| Harian 03:05 | `telescope:prune --hours=48` | Hapus Telescope entries > 48 jam |
| Harian | `activitylog:clean` | Hapus activity log > 365 hari |
| Senin 07:00 | `backups:verify` | Verifikasi integritas backup |
| Senin 07:05 | `permissions:audit --json` | Audit permission (log only) |
| Senin 08:00 | `system:send-digest` | Weekly health digest ke admin |
| Dinamis | DB backup + cleanup | Frekuensi dikonfigurasi dari Global Settings |

> Untuk dev penuh (termasuk Reverb + Scheduler), pakai Sail (`./vendor/bin/sail up -d`).

---

## 10. Frontend Library (CDN/Blade)

Dimuat via CDN di template Blade:

| Library | Kegunaan |
|---------|----------|
| Bootstrap 5 | Layout grid & komponen UI |
| Bootstrap Icons | Ikon SVG |
| jQuery | DOM manipulation & AJAX |
| SweetAlert2 | Dialog & notifikasi toast |
| CKEditor 5 | WYSIWYG editor (Privacy Policy, ToS, About, dll) |
| FilePond | Upload file drag-and-drop |
| Animate.css | Animasi entrance/exit elemen |
| Marked.js | Render Markdown untuk laporan analisis AI |
| Choices.js | Dropdown searchable & multi-select |
| SortableJS | Drag-to-reorder dashboard widget grid (loaded via CDN in dashboard.blade.php) |
| Google Fonts | Inter, Outfit, Fira Code |

---

## 11. Development & Quality Tools

### Code Quality

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `laravel/pint` | ^1.24 | Code formatter (PSR-12). Wajib hijau sebelum merge. |
| `larastan/larastan` | ^3.9 | Static analysis Laravel-aware (PHPStan). Level 5 + baseline. |
| `laravel/sail` | ^1.41 | Docker dev environment (app + Postgres + Redis) |
| `laravel/pail` | ^1.2 | Live log viewer di terminal |
| `laravel/telescope` | ^5.20 | Debug tool (request, query, job, mail) — hanya dev |
| `laravel/boost` | ^2.0 | AI assistant untuk Laravel dev |

### Testing

| Package | Versi | Kegunaan |
|---------|-------|----------|
| `pestphp/pest` | ^4.0 | Testing framework modern |
| `pestphp/pest-plugin-laravel` | ^4.0 | Helper Pest untuk Laravel |
| `mockery/mockery` | ^1.6 | Library mocking untuk test |
| `fakerphp/faker` | ^1.23 | Generator data dummy |
| `nunomaduro/collision` | ^8.6 | Error reporting yang readable di terminal |

### Test Suite Statistics

| Kategori | File | Tests |
|----------|------|-------|
| Feature: Auth + WebAuthn + Social + 2FA + Impersonate | 9 | ~50 |
| Feature: AccessControl (User/Role/Permission) | 3 | 37 |
| Feature: Middleware (IP, ActivePermission, Legal, PwdExpiry, SecurityHeaders, CheckTabPermission) | 6 | 30 |
| Feature: Services (SystemConfig, PasswordPolicy, Backup) | 3 | 31 |
| Feature: Performance (N+1 regression) | 1 | 3 |
| Feature: Database (FK + Cascade) | 1 | 9 |
| Feature: API (Health, MobileConfig, Rate-limit, OTP, AuthAPI, DeviceToken) | 6 | 25 |
| Feature: Dashboard (widget prefs, broadcast event) | 2 | 18 |
| Feature: Helpers (ApiResponse, PasswordRule) | 2 | 18 |
| Unit: Pure logic (Formatter, Caster, Helpers, Exceptions) | 5 | 88 |
| Granular tab permission system | — | +62 |
| **Total** | **38** | **371** |

Run via `./vendor/bin/sail artisan test`. Avg runtime ~35s.

---

## 12. CI/CD

Workflow di `.github/workflows/ci.yml` (GitHub Actions). 3 job paralel:

| Job | Tools |
|-----|-------|
| `test` | Pest 4 (Postgres 15 + Redis 7 service containers) |
| `lint` | `pint --test` + `composer audit` + `permissions:audit` |
| `static-analysis` | Larastan level 5 + baseline |

Push ke `main`/`develop`/`config`/`advanced` dan PR ke `main`/`develop` mentrigger pipeline.

---

## 13. Integrasi Eksternal (Opsional)

Sebagian besar diatur dari **Global Settings** di admin panel — tidak perlu edit `.env`.

| Layanan | Kegunaan |
|---------|----------|
| **OpenAI GPT** | AI assistant di admin panel |
| **Google Gemini** | AI assistant alternatif |
| **Anthropic Claude** | AI assistant alternatif |
| **DeepSeek** | AI assistant alternatif |
| **xAI Grok** | AI assistant alternatif |
| **Mistral AI** | AI assistant alternatif |
| **OpenRouter** | Gateway multi-provider AI |
| **SAP NW RFC** | Koneksi ke sistem SAP ERP |
| **Google Drive** | Cloud backup |
| **Amazon S3** | Cloud backup |
| **SMTP (Mailgun/SES)** | Pengiriman email transaksional |
| **Telegram Bot** | Notifikasi ke channel Telegram (incl. firewall block alert) |
| **Google reCAPTCHA** | Anti-bot di form login |
| **Firebase Cloud Messaging** | Push notification ke mobile (device token) |
| **Sentry** | Error monitoring & performance tracing |

---

## Ringkasan Arsitektur

```
┌─────────────────────────────────────────────────────────┐
│              Browser / Mobile App (React Native)         │
└────────────┬────────────────────────────────┬───────────┘
             │ HTTPS (+ security headers)     │ HTTPS + WS
             ▼                                ▼
       ┌──────────┐                     ┌──────────┐
       │  Nginx   │◄────────────────────│  Reverb  │  WebSocket
       └─────┬────┘                     └─────┬────┘
             ▼                                ▼
       ┌──────────────────────────────────────────────┐
       │    Laravel 13 (PHP-FPM)                      │
       │                                              │
       │   Global middleware:                         │
       │   ┌──────────────────────────────────────┐   │
       │   │ SecurityHeaders                      │   │
       │   │ IpAccessControl                      │   │
       │   │ PasswordExpiry                       │   │
       │   │ CheckLegalAgreement                  │   │
       │   │ ThrottleRequests (per route)         │   │
       │   └──────────────────────────────────────┘   │
       │                                              │
       │  ┌──────────┐ ┌──────────┐ ┌─────────────┐  │
       │  │  Web     │ │  API v1  │ │   Reverb    │  │
       │  │  Routes  │ │ Sanctum  │ │  Broadcast  │  │
       │  └────┬─────┘ └────┬─────┘ └──────┬──────┘  │
       └───────┼────────────┼──────────────┼──────────┘
               │            │              │
    ┌──────────▼───┐   ┌────▼──┐   ┌──────▼─────┐
    │ PostgreSQL 15 │   │Redis 7│   │ Filesystem │
    │ (data utama)  │   │cache, │   │ local/S3/  │
    │ FK + indexes  │   │queue, │   │ GDrive     │
    │ + cascade     │   │session│   │            │
    └───────────────┘   └───────┘   └────────────┘
                              │
                       ┌──────▼──────┐
                       │   Sentry    │
                       │ (error mon) │
                       └─────────────┘
```
