eSchool Dev Docs

Multi-Tenant

Cara data tiap sekolah dipisahkan, koneksi, dan jebakan yang sering terjadi

Konsep

Setiap sekolah adalah satu tenant dengan database sendiri. Data umum disimpan di database central.

KoneksiDipakai untuk
mysqlDatabase central
schoolDatabase tenant yang sedang aktif

Bagaimana tenant dipilih

Pemilihan tenant dilakukan middleware SwitchDatabase (berbasis session) dan TenantSwitcher.

Memuat diagram...

Langkah rincinya:

User login. Sistem mengetahui sekolah milik user tersebut.

Middleware menyimpan sekolah aktif di session.

Pada setiap request, middleware mengarahkan koneksi school ke database sekolah tersebut.

TenantSwitcher memakai Redis untuk cache. Jika Redis tidak tersedia, sistem fallback ke resolusi berbasis token.

Di Windows lokal, ekstensi PHP Redis biasanya belum terpasang. Akibatnya log menampilkan Class "Redis" not found dari TenantSwitcher. Ini hanya peringatan, sistem tetap jalan lewat fallback token.

Web dan API memakai model user yang berbeda

AplikasiModel userCatatan
Web SekolahTenantUserKoneksi school
API-SekolahApp\Models\User\UserGuard terpisah

Karena itu nilai model_type di model_has_roles bisa berbeda. Untuk siswa dan wali, API memakai guard school dengan provider TenantUser.

Jebakan yang sering terjadi

Daftar bug berulang di arsitektur multi-tenant, urut dari yang paling sering:

  1. model_type tidak cocok antar koneksi mysql dan school. Role tidak terbaca atau login gagal.
  2. Scope ->role() memakai koneksi yang salah. Contoh: dropdown guru di jadwal kosong karena ->role('Teacher') mencari ke central, padahal model_has_roles ada di tenant.
  3. property_exists() pada model Eloquent selalu gagal untuk atribut magic. Pakai isset() atau $model->getAttribute().
  4. Middleware tenant menimpa koneksi mysql. Halaman super admin yang butuh data central harus memakai koneksi central secara eksplisit, bukan mysql. Contoh nyata: halaman /language kosong.
  5. Hierarki class user (TenantUser, App\Models\User, App\Models\User\User) membingungkan. Cek dulu class mana yang dipakai di konteks tersebut.

Kebocoran data antar tenant adalah bug paling berbahaya. Uji setiap fitur baru dengan minimal dua sekolah.

Aturan saat menulis kode

  • Selalu tentukan koneksi pada model: protected $connection = 'school';
  • Jangan campur query central dan tenant dalam satu transaksi.
  • Jangan buat foreign key lintas database.
  • Job queue harus membawa informasi tenant supaya berjalan di database yang benar.
  • Untuk data lintas tenant (misalnya super admin melihat semua contact inquiry), query ke setiap database sekolah satu per satu atau gabungkan dengan union, jangan mengandalkan koneksi aktif.

Membuat sekolah baru (provisioning)

Memuat diagram...

Menjalankan migration

php artisan migrate

Sesuaikan path migration tenant dengan struktur project yang sebenarnya.

On this page