# Analisis Mendalam Codebase: KP-ASOY + Laravel_KP > Dibuat: 2026-05-19 | Tujuan: Mempersiapkan integrasi penuh Frontend (KP-ASOY) ↔ Backend (Laravel_KP) --- ## 1. Gambaran Umum Arsitektur Sistem ini terdiri dari **dua proyek Laravel terpisah** yang dirancang untuk berkomunikasi via HTTP API: | Aspek | KP-ASOY (Frontend) | Laravel_KP (Backend) | |---|---|---| | **Peran** | UI / Presentasi Layer | API / Business Logic / Database | | **Port** | `8001` | `8000` | | **Laravel** | ^13.0 (PHP ^8.3) | ^12.0 (PHP ^8.2) | | **Auth** | Session-based (dari API token) | Laravel Sanctum Token | | **Database** | `database_monitoring` (sama) | `database_monitoring` | | **Env: Backend URL** | `BACKEND_API_URL=http://127.0.0.1:8000/api` | — | > **Catatan Kritis**: Kedua proyek masih mengarah ke **database yang sama**. Ini membuat banyak controller di KP-ASOY masih query langsung ke DB, padahal seharusnya semua data diambil via API dari Laravel_KP. --- ## 2. Struktur Direktori Lengkap ### 2.1 Laravel_KP (Backend API) ``` Laravel_KP/ ├── app/ │ ├── Exports/ │ │ └── PenugasanExport.php # Export Excel (Maatwebsite) │ ├── Http/ │ │ ├── Controllers/ │ │ │ ├── AuthController.php # Login, Logout, Register, Me, UpdateProfile │ │ │ ├── PegawaiController.php # CRUD Pegawai (TIDAK ada route-nya di api.php!) │ │ │ ├── UnitKerjaController.php # Index Unit Kerja │ │ │ └── Api/ │ │ │ └── PenugasanController.php # Dashboard, CRUD Penugasan, Export │ │ └── Middleware/ │ │ └── CheckRole.php # Role check via Auth::user() untuk Sanctum │ └── Models/ │ ├── User.php # HasApiTokens, relasi ke Pegawai & Penugasan │ ├── Pegawai.php # NIP, Nama, Jabatan, user_id → belonsgToMany Penugasan │ ├── Penugasan.php # SoftDeletes, pivot ke Pegawai via penugasan_pegawai │ └── UnitKerja.php ├── database/ │ └── migrations/ │ ├── 000...create_users_table.php # users, password_reset_tokens, sessions │ ├── 000...create_cache_table.php # cache │ ├── 000...create_jobs_table.php # jobs queue │ ├── 2026_04_21_create_pegawai_table.php # pegawai + softDeletes │ ├── 2026_04_21_create_penugasan_table.php # penugasan + penugasan_pegawai pivot │ ├── 2026_04_21_create_unit_kerjas_table.php │ └── 2026_04_28_create_personal_access_tokens_table.php # Sanctum ├── routes/ │ ├── api.php # Semua endpoint REST API │ └── web.php # Hanya redirect ke login (minimal) └── .env # APP_URL=http://127.0.0.1:8000 # DB_DATABASE=database_monitoring # CORS_ALLOWED_ORIGINS=http://localhost:8001,http://127.0.0.1:8001 ``` ### 2.2 KP-ASOY (Frontend) ``` KP-ASOY/ ├── app/ │ ├── Http/ │ │ ├── Controllers/ │ │ │ ├── UserLoginController.php # Login/Logout/Settings/User CRUD via API │ │ │ ├── ActivityController.php # CRUD Activity — MASIH query DB lokal! │ │ │ └── Admin/ │ │ │ ├── ActivityController.php # Monitor kegiatan Admin — MASIH DB lokal! │ │ │ └── SuperAdminController.php # Dashboard SuperAdmin — MASIH DB lokal! │ │ └── Middleware/ │ │ └── RoleMiddleware.php # Cek role dari session('user') │ └── Models/ │ ├── User.php # Tanpa HasApiTokens, relasi hasMany Activity │ └── Activity.php # SoftDeletes; fillable: nama_kegiatan, keterangan, status, user_id ├── resources/views/ │ ├── login-user.blade.php │ ├── welcome.blade.php │ ├── user/ │ │ ├── dashboard.blade.php │ │ ├── activity-list.blade.php │ │ ├── activity-detail.blade.php │ │ ├── activity-edit.blade.php │ │ ├── input-activity.blade.php │ │ └── settings.blade.php │ ├── admin/ │ │ ├── dashboard.blade.php │ │ ├── users.blade.php │ │ ├── create-user.blade.php │ │ └── kegiatan/ │ └── superadmin/ │ ├── dashboard.blade.php │ └── user/ ├── routes/ │ └── web.php # Routing web dengan middleware role └── .env # APP_URL=http://127.0.0.1:8001 # DB_DATABASE=database_monitoring # BACKEND_API_URL=http://127.0.0.1:8000/api ``` --- ## 3. Alur Autentikasi (Sudah Terintegrasi) ``` [Browser] → POST /login-user (KP-ASOY:8001) → UserLoginController::login() → Http::post('http://127.0.0.1:8000/api/login', [username, password]) → Laravel_KP: AuthController::login() - Cek username/email di tabel users - Hash::check password - Hapus token lama - createToken('kp-asoy-token') → Sanctum → Response JSON: { token, user:{id,name,username,email,role,jabatan} } → KP-ASOY: session(['api_token', 'user', 'role', 'user_id', 'user_name', 'username']) → Redirect by role: - 'admin' → /admin/dashboard - 'superadmin' → /superadmin/dashboard - 'user' → /user/dashboard ``` --- ## 4. Semua Endpoint API Backend (Laravel_KP) ### Public (tanpa token) | Method | Endpoint | Controller | Fungsi | |--------|----------|------------|--------| | POST | `/api/login` | AuthController@login | Login, return Sanctum token | ### Protected — auth:sanctum | Method | Endpoint | Controller | Fungsi | |--------|----------|------------|--------| | POST | `/api/logout` | AuthController@logout | Hapus token aktif | | GET | `/api/me` | AuthController@me | Data user yang login | | PUT | `/api/profile/update` | AuthController@updateProfile | Update email/password | | POST | `/api/register` | AuthController@register | Buat user baru | | GET | `/api/users` | Closure inline | List semua user (semua role) | | GET | `/api/pegawai` | Closure inline | List user dengan role='user' | | GET | `/api/dashboard` | PenugasanController@dashboard | Stats + 5 aktivitas terbaru | | GET | `/api/penugasan` | PenugasanController@index | List semua penugasan | | POST | `/api/penugasan` | PenugasanController@store | Buat penugasan baru | | GET | `/api/penugasan/{id}` | PenugasanController@show | **METHOD TIDAK ADA** | | PUT | `/api/penugasan/{id}` | PenugasanController@update | **METHOD TIDAK ADA** | | POST | `/api/penugasan/{id}/update-status` | PenugasanController@updateStatus | Ubah status penugasan | | POST | `/api/penugasan/{id}/delete` | PenugasanController@destroy | Batalkan penugasan | | GET | `/api/notifications` | PenugasanController@notifications | **METHOD TIDAK ADA** | | GET | `/api/unit-kerja` | UnitKerjaController@index | List unit kerja | | GET | `/api/export-penugasan` | PenugasanController@export | Download Excel | --- ## 5. Skema Database Lengkap ### Tabel `users` | Kolom | Tipe | Keterangan | |-------|------|------------| | id | bigint PK | | | name | string | Nama lengkap | | username | string UNIQUE | Login identifier | | email | string UNIQUE | | | password | string | bcrypt hashed | | role | enum | **Migration: `superadmin,admin,pegawai`** tapi kode pakai `user` | | jabatan | string nullable | | | created_at / updated_at | timestamp | | ### Tabel `pegawai` | Kolom | Tipe | Keterangan | |-------|------|------------| | id | bigint PK | | | nip | string UNIQUE | | | nama | string | | | jabatan | string | | | user_id | FK → users | | | deleted_at | timestamp | SoftDeletes | ### Tabel `penugasan` | Kolom | Tipe | Keterangan | |-------|------|------------| | id | bigint PK | | | nomor_surat | string nullable UNIQUE | | | kegiatan | string | Nama kegiatan | | tanggal_mulai | date | | | tanggal_selesai | date nullable | | | status | enum | `proses`, `selesai`, `telah_ditinjau` | | created_by | FK → users | Admin yang membuat | | approved_by | FK → users nullable | SuperAdmin penyetuju | | approved_at | timestamp nullable | | | alasan_hapus | text nullable | Alasan pembatalan | | deleted_at | timestamp | SoftDeletes | ### Tabel `penugasan_pegawai` (Pivot) | Kolom | Tipe | Keterangan | |-------|------|------------| | id | bigint PK | | | penugasan_id | FK → penugasan | | | pegawai_id | FK → pegawai | | ### Tabel `activities` (KP-ASOY Lokal — TIDAK ADA di Backend) | Kolom | Tipe | Keterangan | |-------|------|------------| | id | bigint PK | | | user_id | FK → users | | | nama_kegiatan | string | | | keterangan | text nullable | | | status | string | `on_progres`, `selesai` | | deleted_at | timestamp | SoftDeletes | --- ## 6. Relasi Antar Model ### Laravel_KP (Backend) ``` User ─── hasOne ──────────── Pegawai User ─── hasMany ─────────── Penugasan (as created_by) User ─── hasMany ─────────── Penugasan (as approved_by) Pegawai ─ belongsToMany ──── Penugasan (via penugasan_pegawai) Penugasan ─ belongsToMany ── Pegawai (via penugasan_pegawai) Penugasan ─ belongsTo ────── User (pembuat) Penugasan ─ belongsTo ────── User (penyetuju) ``` ### KP-ASOY (Frontend) ``` User ─── hasMany ─────────── Activity Activity ─ belongsTo ──────── User ``` --- ## 7. Analisis Controller per Controller ### 7.1 `UserLoginController` (KP-ASOY) — SUDAH TERINTEGRASI ✅ Semua method sudah menggunakan `Http::withToken(session('api_token'))`: - `login()` → POST `/api/login` - `logout()` → POST `/api/logout` - `updateSettings()` → PUT `/api/profile/update` - `userList()` → GET `/api/users` - `storeUser()` → POST `/api/register` - `destroyUser()` → DELETE `/api/users/{id}` *(endpoint backend belum ada!)* **Kekurangan**: `editUser()` dan `updateUser()` hanya return view tanpa data dari API. ### 7.2 `ActivityController` (KP-ASOY) — BELUM TERINTEGRASI ❌ Semua method masih pakai `Auth::id()` dan model `Activity::` langsung: - `index()` → query `Activity::where('user_id', Auth::id())` - `store()` → `Activity::create([...])` - `list()`, `show()`, `edit()`, `update()`, `selesai()` > **Target**: Semua operasi ini harus diganti dengan HTTP call ke backend menggunakan `session('api_token')` dan memetakan `Activity` ke entitas `Penugasan` di backend. ### 7.3 `Admin/ActivityController` (KP-ASOY) — BELUM TERINTEGRASI ❌ - `dashboard()` → query `Activity::`, `User::` langsung ke DB - `index()` → query dengan filter search/status/bulan langsung ke DB - `show()`, `edit()`, `update()`, `destroy()` → langsung ke DB ### 7.4 `Admin/SuperAdminController` (KP-ASOY) — BELUM TERINTEGRASI ❌ - `index()` → query `Activity::`, `User::withCount('activities')` langsung ke DB - `approve()` → `Activity::findOrFail($id)->update(['status' => 'selesai'])` langsung ke DB - `destroy()` → SoftDelete langsung ke DB - `userIndex()`, `editUser()`, `updateUser()`, `destroyUser()` → langsung ke DB ### 7.5 `AuthController` (Laravel_KP) — BAIK ✅ Full implementasi login, register, me, logout, updateProfile. Semua return JSON. ### 7.6 `PenugasanController` (Laravel_KP) — PARTIAL ⚠️ - ✅ `dashboard()` → return JSON stats - ✅ `index()` → return JSON list - ❌ `store()` → **return redirect(), bukan JSON** (fatal untuk API) - ❌ `show()` → **method tidak ada** - ❌ `update()` → **method tidak ada** - ✅ `updateStatus()` → return JSON - ✅ `destroy()` → return JSON (tapi method hapus = batalkan, bukan delete) - ✅ `export()` → return Excel download - ❌ `notifications()` → **method tidak ada** ### 7.7 `PegawaiController` (Laravel_KP) — TIDAK DI-ROUTE ❌ Full CRUD tersedia (index, store, show, update, destroy, trash, restore) tapi **tidak ada satupun route** di `api.php` yang mengarah ke controller ini. --- ## 8. Middleware & Keamanan ### Backend: `CheckRole` Middleware ```php // Membaca dari Auth::user() (Sanctum) if (!$request->user() || !in_array($request->user()->role, $roles)) { return response()->json(['status' => false, 'message' => 'Akses ditolak'], 403); } ``` > **Catatan**: Middleware ini terdaftar tapi tidak digunakan di route manapun di `api.php`. ### Frontend: `RoleMiddleware` ```php // Membaca dari session('user') yang tersimpan saat login $user = session('user'); if (!in_array($user['role'], $roles)) { abort(403); } ``` > Ini sudah tepat untuk frontend yang menggunakan session. --- ## 9. GAP INTEGRASI — Daftar Lengkap ### GAP-01: Dua Entitas Data Yang Berbeda (KRITIS) - Backend punya `Penugasan` = penugasan dari admin ke pegawai (top-down) - Frontend punya `Activity` = kegiatan yang diinput sendiri user (bottom-up) - **Keputusan diperlukan**: Apakah `Activity` frontend = `Penugasan` backend? Atau keduanya berbeda? - Jika disamakan: field tidak cocok (Activity: `nama_kegiatan, tanggal, lokasi, deskripsi` vs Penugasan: `nomor_surat, kegiatan, tanggal_mulai, tanggal_selesai`) ### GAP-02: Inkonsistensi Nilai Role (KRITIS) - Migration users: enum `['superadmin', 'admin', 'pegawai']` - Kode backend (AuthController, api.php): menggunakan string `'user'` - Kode frontend (web.php, RoleMiddleware): menggunakan `'user'`, `'admin'`, `'superadmin'` - **Harus dipilih satu**: gunakan `user` atau `pegawai` secara konsisten ### GAP-03: Method Hilang di PenugasanController - `show($id)` → terdaftar di route, method tidak ada - `update(Request, $id)` → terdaftar di route, method tidak ada - `notifications()` → terdaftar di route, method tidak ada ### GAP-04: `store()` Return Redirect Bukan JSON ```php // SALAH (ini web controller, bukan API): return redirect()->back()->with('success', '...'); // BENAR (untuk API): return response()->json(['success' => true, 'data' => $penugasan], 201); ``` ### GAP-05: PegawaiController Tidak Di-Route - Full CRUD tersedia namun tidak ada satupun endpoint di `api.php` - Frontend tidak bisa mengakses data pegawai terpisah dari users ### GAP-06: DELETE `/api/users/{id}` Tidak Ada di Backend - `UserLoginController::destroyUser()` di frontend memanggil `DELETE /api/users/{id}` - Route ini tidak terdaftar di backend → HTTP 404 ### GAP-07: ActivityController Masih Pakai DB Lokal - Semua CRUD Activity di frontend (user, admin, superadmin) query langsung ke database - Padahal database = database yang sama dengan backend, yang idealnya hanya diakses backend ### GAP-08: Activity Model Fillable Tidak Lengkap ```php // Saat ini: protected $fillable = ['nama_kegiatan', 'keterangan', 'status', 'user_id']; // Tapi controller menyimpan: Activity::create([..., 'tanggal' => ..., 'lokasi' => ...]); // Field 'tanggal' dan 'lokasi' tidak ada di fillable → Mass Assignment Error! ``` ### GAP-09: CORS Belum Dipastikan Terkonfigurasi - Backend `.env` sudah ada `CORS_ALLOWED_ORIGINS=http://localhost:8001,http://127.0.0.1:8001` - Perlu verifikasi `config/cors.php` membaca env ini dengan benar ### GAP-10: Session vs Token Auth Tidak Sinkron untuk SuperAdmin - SuperAdmin di KP-ASOY masih menggunakan `Auth::user()` dan Eloquent langsung - Harus diubah menggunakan `session('api_token')` untuk semua request ke backend --- ## 10. Peta Alur Integrasi Target ``` KP-ASOY (FE :8001) Laravel_KP (BE :8000) ───────────────────────────────────────────────────────────────────── [LOGIN] POST /login-user ──────────────────────────► POST /api/login ◄────────────────────────── {token, user} [USER — Input Kegiatan] POST /activities/store ────────────────────► POST /api/penugasan Http::withToken($token)->post(...) PenugasanController@store ◄────────────────────────── {success, data} [USER — List Kegiatan] GET /activity-list ────────────────────────► GET /api/penugasan?user_id={id} ◄────────────────────────── {success, data:[...]} [USER — Update Kegiatan] POST /activity/{id}/update ────────────────► PUT /api/penugasan/{id} ◄────────────────────────── {success, data} [ADMIN — Dashboard] GET /admin/dashboard ──────────────────────► GET /api/dashboard ◄────────────────────────── {stats, recent_activities} [ADMIN — Tinjau Kegiatan] POST /admin/kegiatan/{id}/update ──────────► POST /api/penugasan/{id}/update-status {status: 'telah_ditinjau'} PenugasanController@updateStatus [SUPERADMIN — Approve] POST /superadmin/kegiatan/{id}/approve ───► POST /api/penugasan/{id}/update-status {status: 'selesai'} PenugasanController@updateStatus [SUPERADMIN — Export] GET /superadmin/export ────────────────────► GET /api/export-penugasan ◄────────────────────────── file: Laporan_Kegiatan.xlsx [ADMIN — Tambah User] POST /admin/users/store ───────────────────► POST /api/register ◄────────────────────────── {message, user} [ADMIN — Hapus User] DELETE /admin/users/{id} ──────────────────► DELETE /api/users/{id} [BELUM ADA!] ``` --- ## 11. Status Integrasi Per Fitur | # | Fitur | FE Controller | BE Endpoint | Status | |---|-------|--------------|-------------|--------| | 1 | Login | UserLoginController@login | POST /api/login | ✅ Terintegrasi | | 2 | Logout | UserLoginController@logout | POST /api/logout | ✅ Terintegrasi | | 3 | Update Profil | UserLoginController@updateSettings | PUT /api/profile/update | ✅ Terintegrasi | | 4 | Tambah User (Admin) | UserLoginController@storeUser | POST /api/register | ✅ Terintegrasi | | 5 | List User (Admin) | UserLoginController@userList | GET /api/users | ✅ Terintegrasi | | 6 | Hapus User (Admin) | UserLoginController@destroyUser | ❌ Route belum ada | ❌ Belum | | 7 | Input Kegiatan (User) | ActivityController@store | POST /api/penugasan | ❌ FE masih DB lokal | | 8 | List Kegiatan (User) | ActivityController@list | GET /api/penugasan | ❌ FE masih DB lokal | | 9 | Detail Kegiatan (User) | ActivityController@show | ❌ Method belum ada | ❌ Belum | | 10 | Edit Kegiatan (User) | ActivityController@update | ❌ Method belum ada | ❌ Belum | | 11 | Selesaikan Kegiatan | ActivityController@selesai | POST /api/penugasan/{id}/update-status | ❌ FE masih DB lokal | | 12 | Dashboard Admin | Admin/ActivityController@dashboard | GET /api/dashboard | ❌ FE masih DB lokal | | 13 | Monitor Kegiatan (Admin) | Admin/ActivityController@index | GET /api/penugasan | ❌ FE masih DB lokal | | 14 | Tinjau Kegiatan (Admin) | Admin/ActivityController@update | POST /api/penugasan/{id}/update-status | ❌ FE masih DB lokal | | 15 | Dashboard SuperAdmin | SuperAdminController@index | GET /api/dashboard | ❌ FE masih DB lokal | | 16 | Approve Kegiatan (SA) | SuperAdminController@approve | POST /api/penugasan/{id}/update-status | ❌ FE masih DB lokal | | 17 | Hapus Kegiatan (SA) | SuperAdminController@destroy | POST /api/penugasan/{id}/delete | ❌ FE masih DB lokal | | 18 | Manajemen User (SA) | SuperAdminController@userIndex | GET /api/users | ❌ FE masih DB lokal | | 19 | Export Laporan | SuperAdminController@export | GET /api/export-penugasan | ❌ FE hanya redirect error | | 20 | Notifikasi User | ActivityController (statis) | ❌ Method belum ada | ❌ Belum | | 21 | CRUD Pegawai | ❌ Tidak ada di FE | ❌ Tidak di-route | ❌ Belum | **Ringkasan**: 5 dari 21 fitur (24%) sudah terintegrasi. 16 fitur (76%) belum terintegrasi. --- ## 12. Prioritas Perbaikan ### 🔴 Prioritas 1 — Perbaiki Backend (Harus Selesai Dulu) 1. **Seragamkan role value** → ubah migration/kode dari `pegawai` ke `user` secara konsisten 2. **Implementasi method hilang** di `PenugasanController`: - `show($id)` → return JSON detail penugasan + petugas - `update(Request, $id)` → update data penugasan, return JSON - `notifications()` → return list penugasan yang sudah `telah_ditinjau` untuk user tertentu 3. **Perbaiki `store()`** → ganti `redirect()->back()` dengan `response()->json(201)` 4. **Tambah route di api.php**: - `DELETE /api/users/{id}` → untuk hapus user - Route lengkap `PegawaiController` (index, store, show, update, destroy, trash, restore) 5. **Tambah filter by user** di `GET /api/penugasan` → user hanya boleh lihat tugasnya sendiri ### 🟡 Prioritas 2 — Refactor Frontend Controllers 6. **Refactor `ActivityController`** → ganti semua `Activity::` dan `Auth::id()` dengan `Http::withToken(session('api_token'))->...` 7. **Refactor `Admin/ActivityController`** → semua operasi via API backend 8. **Refactor `SuperAdminController`** → gunakan endpoint API, bukan query DB langsung 9. **Perbaiki `Activity` model fillable** → tambahkan `tanggal`, `lokasi`, `deskripsi` ### 🟢 Prioritas 3 — Penyempurnaan 10. **Verifikasi konfigurasi CORS** di `config/cors.php` backend 11. **Hapus koneksi DB dari KP-ASOY** (kecuali sessions/cache) 12. **Implementasi notifikasi real** berdasarkan status perubahan penugasan 13. **Tambah endpoint edit/delete user** untuk SuperAdmin di backend 14. **Implementasi `editUser()` dan `updateUser()`** di `UserLoginController` KP-ASOY --- ## 13. Kesimpulan Secara arsitektur, rancangan pemisahan frontend (KP-ASOY) dan backend (Laravel_KP) **sudah benar dan tepat**. Fondasi integrasi sudah ada: autentikasi via Sanctum sudah berjalan, `BACKEND_API_URL` sudah dikonfigurasi, dan pattern `Http::withToken()` sudah digunakan di `UserLoginController`. **Masalah utama** adalah sebagian besar fitur di KP-ASOY (terutama semua yang berhubungan dengan Activity/Kegiatan dan Dashboard) masih bypass API dan langsung mengakses database. Ini terjadi kemungkinan karena pengembangan dilakukan secara bertahap: login terintegrasi lebih dulu, sementara fitur-fitur lainnya masih dalam proses refactoring. **Langkah terpenting** sebelum integrasi penuh: 1. Putuskan apakah `Activity` (KP-ASOY) = `Penugasan` (Laravel_KP) atau dua entitas berbeda 2. Perbaiki method-method yang hilang di backend 3. Seragamkan nilai role di seluruh codebase 4. Refactor semua controller frontend untuk menggunakan API