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):

  1. Kampus membuat CNAME sia.bim.ac.id → domain oneKE
  2. Tambah IngressRoute baru dengan Host(sia.bim.ac.id) ke Service aplikasi SIA (pola sama seperti IngressRoute Longhorn/Dashboard/Grafana yang sudah ada)
  3. cert-manager menerbitkan sertifikat TLS otomatis (HTTP-01) untuk domain baru itu — syarat: DNS harus sudah diarahkan lebih dulu sebelum langkah ini
  4. Tambah mapping domain → tenant_id di 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.