2
Arsitektur Sistem
badaso/core dikemas sebagai satu library composer dengan namespace Uasoft\Badaso\ yang dipetakan ke direktori src/ (composer.json:62-661). Karena BadasoServiceProvider tercantum di kunci extra.laravel.providers, Laravel memuatnya sendiri lewat auto-discovery, tanpa entri tambahan di config/app.php (composer.json:72-782).
Dari satu paket itu lahir dua permukaan yang berbagi kode yang sama: API JSON di bawah prefix badaso-api dan SPA admin di bawah prefix badaso-dashboard (src/Config/badaso.php:32-383).
graph LR
SP["BadasoServiceProvider"] --> APIR["src/Routes/api.php"]
SP --> WEBR["src/Routes/web.php"]
APIR -->|"prefix badaso-api"| CTRL["Controllers JSON"]
WEBR -->|"prefix badaso-dashboard"| VIEW["badaso::admin-panel.index"]
VIEW --> SPA["app.js dan style.scss via Vite"]
SPA -.->|"request JSON"| APIR
style APIR fill:#f59e0b,color:#000
style WEBR fill:#f59e0b,color:#000
style CTRL fill:#2d7d46,color:#fff
style SPA fill:#8b5cf6,color:#fff
%% fig: Dua permukaan dari satu paket
%% desc: Service provider memuat dua berkas route; group API melayani JSON, sedangkan route web menyajikan cangkang SPA admin yang memanggil balik API.Dua permukaan dari satu paket
Route API didaftarkan sebagai satu group dengan prefix dari badaso.api_route_prefix, namespace Uasoft\Badaso\Controllers, dan middleware ApiRequest untuk seluruh group (src/Routes/api.php:7-114). Route web tidak melayani banyak halaman: satu route menangkap semua path di bawah badaso.admin_panel_route_prefix lalu mengembalikan view badaso::admin-panel.index (src/Routes/web.php:19-225). View itu hanya cangkang, berisi satu <div id="app"> dan dua aset Vite, style.scss serta app.js dari vendor/badaso/core/src/resources/badaso/ (src/resources/views/admin-panel/index.blade.php:27-366).
Konsekuensinya, seluruh navigasi panel berjalan di sisi klien. Server hanya melihat request JSON ke group API.
Registrasi saat boot Laravel
boot() melakukan lima hal sekaligus: mengalikan alias Badaso ke Uasoft\Badaso\Facades\Badaso, mendorong CheckForMaintenanceMode dan GenerateForSwagger ke group middleware web, mengikat singleton badaso ke kelas Uasoft\Badaso\Badaso, mendaftarkan model token Sanctum, lalu memuat migrations, views, translations, dan dua berkas route langsung dari direktori src/ (src/Providers/BadasoServiceProvider.php:30-497).
register() mendaftarkan sub-provider pihak ketiga (Doctrine, Dropbox, Google Drive, LogViewer, L5Swagger) dan command konsol lewat registerConsoleCommands (src/Providers/BadasoServiceProvider.php:104-1138). Langkah publish dan command setup dibahas di Instalasi dan Setup.
Alur satu request API
graph TD
REQ["Request ke /badaso-api/v1/..."] --> AR["ApiRequest"]
AR --> AUTH["BadasoAuthenticate"]
AUTH --> PERM["BadasoCheckPermissions"]
PERM --> CTRL["BadasoMenuController@browseMenu"]
CTRL --> MDL["Menu"]
CTRL --> RESP["ApiResponse::success"]
MDL --> DB[("MySQL")]
RESP --> JSON["JSON camelCase"]
AR -->|"maintenance aktif"| DOWN["ApiResponse::serviceUnavailable"]
PERM -->|"permission tidak ada"| FORB["ApiResponse::forbidden"]
style DB fill:#336791,color:#fff
style AR fill:#f59e0b,color:#000
style PERM fill:#f59e0b,color:#000
style RESP fill:#2d7d46,color:#fff
style JSON fill:#2d7d46,color:#fff
style DOWN fill:#dc2626,color:#fff
style FORB fill:#dc2626,color:#fff
%% fig: Pipeline satu request API
%% desc: Request melewati middleware maintenance, autentikasi, dan permission sebelum mencapai controller, model, dan pembungkus response.ApiRequest berjalan paling depan karena dipasang di level group, bukan per route (src/Routes/api.php:7-114). Di dalam handle() middleware itu memilih locale dari header Accept-Language, menormalkan body lewat CaseConvert::snake dan HandleFile::normalize, lalu menolak request saat maintenance dengan ApiResponse::serviceUnavailable() kecuali pemanggilnya administrator atau path-nya masuk whitelist (src/Middleware/ApiRequest.php:60-859).
Setelah itu BadasoAuthenticate::isAuthorize memeriksa guard dari badaso.authenticate.guard dan menolak token yang koneksinya sudah timeout lewat TokenManagement::fromAuth() (src/Middleware/BadasoAuthenticate.php:31-5010). BadasoCheckPermissions memperluas BadasoAuthenticate, jadi permission per route hanya dicek setelah autentikasi lolos; permission yang tidak dimiliki berakhir di ApiResponse::forbidden() (src/Middleware/BadasoCheckPermissions.php:9-3311). Status yang dipakai adalah 403 untuk forbidden() dan 503 untuk serviceUnavailable() (src/Helpers/ApiResponse.php:121-13712). Rincian guard dan permission ada di Autentikasi dan Otorisasi.
Controller, helper, dan model
Controller Badaso tipis. BadasoMenuController::browseMenu menjalankan Menu::orderBy('order')->get(), membungkus hasilnya dengan ApiResponse::success(collect($data)->toArray()), dan meneruskan exception apa pun ke ApiResponse::failed (src/Controllers/BadasoMenuController.php:17-2813).
ApiResponse::send menutup semua jalur keluar: payload diubah ke camelCase dengan CaseConvert::camel, dan khusus method GET dipetakan ulang lewat HandleFile::handle sebelum response()->json (src/Helpers/ApiResponse.php:14-2314). Helper lain membaca langsung ke database tanpa lapisan tambahan; Config::get menjalankan Configuration::where('key', $key)->first() (src/Helpers/Config.php:9-1715). Pola route ke controller ke model ke ApiResponse ini berulang di hampir semua controller di src/Controllers/.
Registry model dan facade
Properti $models memetakan sepuluh nama pendek ke kelas Eloquent: DataRow, DataType, Permission, Role, User, UserRole, RolePermission, Menu, MenuItem, dan Configuration (src/Badaso.php:19-3016). model($name) mengembalikan app($this->models[Str::studly($name)]), sehingga nama seperti 'DataType' bisa dipakai dari route dan controller tanpa use (src/Badaso.php:253-26117). Facade Badaso hanya meneruskan panggilan statis ke container dengan accessor 'badaso' (src/Facades/Badaso.php:7-1718).
Route dinamis dari data_types
Group entities membaca tabel data_types saat route dimuat, lalu mendaftarkan sebelas route per data_type dengan slug sebagai path dan check_crud_permission per slug (src/Routes/api.php:159-16719).
⚠️ Seluruh loop itu dibungkus
try/catch.InvalidArgumentExceptiondilempar ulang dengan pesanCustom routes hasn't been configured because:, tetapiExceptionlain ditelan dengan komentarmight just be because table not yet migrated.Bila migration belum dijalankan, routeentitiestidak terdaftar sama sekali dan request berakhir 404 tanpa petunjuk penyebabnya (src/Routes/api.php:207-21120).
Konfigurasi sebagai titik sambung
Key di badaso.php | Nilai | Efek |
|---|---|---|
api_route_prefix | badaso-api | prefix group API |
admin_panel_route_prefix | badaso-dashboard | prefix route SPA |
middleware.authenticate | BadasoAuthenticate::class | pemeriksaan token pada route |
middleware.check_permission | BadasoCheckPermissions::class | cek permission per route |
middleware.check_crud_permission | BadasoCheckPermissionsForCRUD::class | cek permission per slug entities |
authenticate.guard | sanctum | guard yang dipakai isAuthorize |
Peta middleware dan guard di atas dibaca langsung oleh route dan middleware (src/Config/badaso.php:4-821, src/Config/badaso.php:10-1222), sedangkan kedua prefix berasal dari blok yang sama dengan default_menu dan secret_login_prefix (src/Config/badaso.php:32-383).