Keputusan Arsitektur¶
Status: DISEPAKATI (9 Juli 2026), belum diimplementasikan
Tiga keputusan di bawah adalah hasil diskusi awal — dicatat di sini supaya jadi rujukan tunggal sebelum implementasi dimulai, dan supaya alasan/trade-off di baliknya tidak hilang seiring waktu.
1. Model Multi-Tenancy — Shared Database + Row-Level Security¶
| Item | Keputusan |
|---|---|
| Database | Reuse postgres-cluster yang sudah ada (HA 3-node, synchronous_mode, backup WAL-G — lihat Instalasi PostgreSQL + Patroni) |
| Isolasi tenant | Kolom tenant_id di setiap tabel + Row-Level Security (RLS) PostgreSQL, bukan database/schema terpisah per kampus |
| Penegakan isolasi | Di level database (policy RLS), bukan hanya WHERE tenant_id = ? di kode aplikasi — defense-in-depth, satu bug lupa filter di kode tidak otomatis bocor data antar-kampus |
Kenapa bukan database/schema terpisah per tenant?
Database-per-tenant lebih kuat isolasinya tapi operasionalnya cepat tidak terkelola begitu jumlah kampus bertambah (migrasi schema harus diulang N kali, backup/monitoring per-tenant, dst). Shared database + RLS memberi isolasi yang cukup kuat untuk kebutuhan saat ini dengan biaya operasional jauh lebih rendah.
Trade-off yang disadari
Bila suatu saat ada kampus yang mensyaratkan isolasi fisik penuh (compliance/data residency ketat, mis. data harus di server terpisah), migrasi tenant tersebut ke database terpisah adalah kerja tambahan — bukan sesuatu yang otomatis didukung pola ini sejak awal.
2. Routing — Domain Bersama (default) + Custom Domain (opsional per tenant)¶
| Mode akses | Cara kerja |
|---|---|
| Domain bersama (default) | Satu domain aplikasi (mis. sia.oneke.ums.id), tenant ditentukan dari pilihan/deteksi saat login — bukan dari subdomain per kampus |
| Custom domain (opsional) | Kampus mengarahkan domain miliknya sendiri (mis. sia.bim.ac.id) via CNAME ke oneKE. Tenant di-resolve dari Host header request — kampus dengan custom domain langsung masuk ke tenant-nya tanpa perlu memilih tenant di layar login |
Langkah onboarding custom domain per tenant (dilakukan tim oneKE, bukan otomatis):
- Kampus membuat CNAME
sia.bim.ac.id→ domain oneKE - Tambah
IngressRoutebaru denganHost(sia.bim.ac.id)ke Service aplikasi SIA (pola sama seperti IngressRoute Longhorn/Dashboard/Grafana yang sudah ada) cert-managermenerbitkan sertifikat TLS otomatis (HTTP-01) untuk domain baru itu — syarat: DNS harus sudah diarahkan lebih dulu sebelum langkah ini- Tambah mapping
domain → tenant_iddi tabel tenant aplikasi
Kenapa bukan subdomain per kampus di domain oneKE sendiri (mis. bim.oneke.ums.id)?
Custom domain milik kampus sendiri (sia.bim.ac.id) memberi kesan "sistem milik kampus
tersebut" — lebih baik untuk branding — dan tidak butuh wildcard cert/DNS di sisi oneKE.
Subdomain di domain oneKE tetap jadi fallback bila kampus belum punya/tidak butuh domain
sendiri.
3. Dokumentasi — Digabung ke Situs /plan/ yang Sudah Ada¶
Bukan situs terpisah di /sia-multitenant/docs/. Alasan: pipeline build (MkDocs via Docker) dan
deploy (kubectl cp ke pod oneke-docs) sudah teruji jalan untuk /plan/ — tinggal tambah nav
section baru tanpa perlu pod/PVC/IngressRoute baru. Bisa dipisah belakangan bila dokumentasi ini
berkembang jadi besar (isinya cuma file markdown, gampang dipindah).
4. Stack Aplikasi Backend — Django¶
| Item | Keputusan |
|---|---|
| Framework | Django (Python) — dipilih dibanding Laravel (PHP) |
| Admin UI (saat ini) | Django admin default, hanya beberapa label yang disesuaikan (bahasa/istilah akademik) — belum pakai tema pihak ketiga |
| Keputusan tampilan visual | Ditunda — akan dipikirkan lagi nanti, bukan prioritas di tahap ini |
Kenapa Django, bukan Laravel?
Pertimbangan utama: pola isolasi tenant yang sudah diputuskan (§1)
butuh SET LOCAL app.tenant_id dibungkus transaksi per-request secara konsisten — Django
punya prior art yang lebih matang & terdokumentasi untuk pola RLS-per-request ini
dibanding ekosistem Laravel (yang mayoritas paket multi-tenancy-nya berorientasi
database/schema-per-tenant, bukan RLS). Dependency tree Django untuk aplikasi CRUD admin
seperti ini juga cenderung lebih ramping — beban patching jangka panjang lebih ringan untuk
tim ops yang kecil.
Soal integrasi PDDIKTI/Feeder Dikti — bukan penghalang teknis
Sempat dipertimbangkan Laravel unggul untuk integrasi PDDIKTI karena ekosistem SIA kampus
Indonesia mayoritas PHP. Setelah ditelaah lebih detail: integrasi Feeder dilakukan lewat web
service (SOAP/REST) yang bisa dikonsumsi Python sama baiknya (library zeep untuk SOAP,
requests/httpx untuk REST) — jadi ini soal ketersediaan prior art/dukungan komunitas,
bukan keterbatasan teknis Django. Tim perlu verifikasi dokumentasi Feeder API terbaru
langsung ke Kemdikbud/BPPT saat implementasi nanti.
4.1 Eksperimen Tema Admin (dicoba, tidak dipakai)¶
Dua tema pihak ketiga sempat di-preview berdampingan (namespace sementara sia-preview,
sudah dihapus) untuk bahan perbandingan visual:
- django-unfold — flat/minimalis, aksen ungu, gaya dashboard SaaS modern
- django-jazzmin — Bootstrap (tema "flatly"), sidebar gelap, lebih konvensional tapi matang
Hasil: keduanya dinilai belum sesuai yang diharapkan. Keputusan: pakai Django admin default dulu (dengan penyesuaian label), keputusan tema visual final ditunda ke kemudian hari.
Opsi SPA (React-admin/Refine + Django REST Framework sebagai backend API) juga sempat dibahas — dinilai belum terjustifikasi untuk skala "administrasi akademik pokok" (maks 5.000 mahasiswa/250 staf per tenant) karena butuh maintain dua codebase terpisah (API + frontend). Opsi ini disimpan sebagai catatan bila suatu saat ada kebutuhan konkret yang mengarah ke sana (mis. API yang sama dipakai aplikasi mobile terpisah).
Lihat Roadmap Implementasi untuk urutan langkah teknis berikutnya.