Les pèlerins au-dessus des nuages

Pendahuluan

Sistem Informasi Manajemen Rumah Sakit (SIMRS) itu seperti kokpit pesawat: mustahil dipahami hanya dari brosur. Tetapi mencobanya di rumah sakit sungguhan jelas bukan ide bagus. Salah klik di sistem hidup bisa berakibat ke pasien nyata.

Solusinya: bangun laboratorium simulasi. Tulisan ini adalah catatan perjalanan saya memasang SIMRS Khanza, SIMRS gratis berbasis Java yang dikembangkan Khanza.Soft Media, di ChromeOS lewat Linux (Crostini). Saya menulisnya kronologis, lengkap dengan perintah, alasannya, dan jebakan yang saya temui.

Hasil akhirnya: aplikasi desktop dan web berjalan, ada 40 pasien fiktif, dua kasus rawat inap lengkap sampai nota, dan jar aplikasi yang dibangun ulang dari kode sumber GitHub.

Pembaca yang paling terbantu: staf IT rumah sakit, mahasiswa informatika kesehatan atau rekam medis, dan hobiis yang ingin mencoba tanpa risiko.

Daftar Isi

  1. Lingkungan dan bahan
  2. Langkah 1: Periksa paket unduhan
  3. Langkah 2: Pasang Java, MariaDB, Git
  4. Langkah 3: Bagian web (Apache + PHP)
  5. Langkah 4: Perketat akses database
  6. Langkah 5: Akun login aplikasi
  7. Langkah 6: Update dari GitHub
  8. Langkah 7: Ikon peluncur
  9. Langkah 8: Data simulasi dasar
  10. Langkah 9: Dua kasus rawat inap
  11. Langkah 10: Billing dan nota
  12. Catatan keamanan dan etika
  13. Penutup, ide lanjutan, dan checklist

Lingkungan dan bahan

  • Perangkat: ChromeOS dengan Linux (Debian 13 “trixie”, kontainer Crostini), pengguna sudo aktif.
  • Prasyarat: fitur Linux sudah diaktifkan di ChromeOS (Settings > Developers > Linux). Ini asumsi saya; perlu diverifikasi sesuai versi ChromeOS.
  • Disk: awalnya sekitar 10 GB dengan sisa ±4 GB. Disk sempat penuh 95% saat kompilasi, dan di akhir terlihat membesar menjadi 27 GB total. Tip: jalankan df -h / sebelum mulai.
  • Bahan: zip rilis siap pakai KhanzaHMSLinux-....zip (±1,1 GB) dari folder Downloads, yaitu rilis resmi pengembang lewat Google Drive yang ditautkan di README repositori, dan repositori sumber mas-elkhanza/SIMRS-Khanza di GitHub.
  • Lisensi: README repo menyebut Aladdin Free Public License. Perangkat lunak ini gratis dan dilarang diperjualbelikan tanpa izin pembuatnya (Khanza.Soft Media).

Gambaran besar arsitektur yang akan kita bangun:

ChromeOS > Linux (Debian 13, Crostini)Aplikasi desktopkhanza.jar (Java 21)Bagian webApache + PHP 8.4 (webapps)MariaDB 11.8database "sik" (1.186 tabel)setting/database.xmlwebapps/conf/conf.php

Langkah 1: Periksa paket unduhan

Zip berisi folder KhanzaHMSLinux: jar aplikasi, sik.sql (±12,7 MB), folder webapps, lib, skrip .sh, dan panduan.

unzip belum terpasang, jadi saya ekstrak dengan Python (gunakan path absolut):

python3 -I -c "import zipfile; zipfile.ZipFile('NAMA.zip').extractall('~/khanza-extract')"

Hasil ekstraksi ±1,7 GB. Panduan bawaan meminta: JRE, MySQL/XAMPP, impor sik.sql, salin webapps ke htdocs, dan atur database.xml untuk klien-server.

Langkah 2: Pasang Java, MariaDB, Git

sudo apt-get update && sudo apt-get install -y git default-jre mariadb-server

Ini memberi Java 21 dan MariaDB 11.8. Lalu buat database dan impor skemanya:

sudo mariadb -e "CREATE DATABASE sik CHARACTER SET latin1;"
sudo mariadb sik < sik.sql

Hasilnya 1.186 tabel.

database.xml menyimpan kredensial terenkripsi, jadi untuk awal saya membuat user root tanpa password agar aplikasi bisa terhubung. Ini hanya untuk uji lokal, dan di Langkah 4 kita perbaiki.

Jalankan aplikasi:

java -Xss2m -Xmx1024m -jar khanza.jar

Flag PermSize di Aplikasi.sh khusus Java 8, jadi saya hapus. Aplikasi tersambung ke database tanpa error akses.

Langkah 3: Bagian web (Apache + PHP)

sudo apt-get install -y apache2 libapache2-mod-php php-mysql php-gd php-mbstring php-xml php-curl php-zip
sudo cp -r webapps /var/www/html/webapps
sudo chown -R www-data:www-data /var/www/html/webapps
sudo a2enmod rewrite

Lalu ubah AllowOverride None menjadi All di /etc/apache2/apache2.conf dan restart Apache. PHP yang terpasang adalah 8.4.

Uji dengan membuka http://localhost/webapps/. Halaman login tampil (HTTP 200), sedangkan halaman lain mengalihkan (302) ke login. Pengaturan koneksi database web ada di webapps/conf/conf.php.

Langkah 4: Perketat akses database

Root tanpa password tidak boleh dipelihara, bahkan di laptop sendiri. Kebiasaan buruk itu cepat menempel.

  1. Buat user database khusus (contoh cahya, password sesuai pilihan sendiri, di sini saya tulis sebagai PASSWORD_ANDA) dengan hak penuh pada sik.
  2. Hapus root tanpa password dan jadikan root hanya lewat socket:
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket;

Kredensial di setting/database.xml dienkripsi AES-CBC. Kunci dan IV ada di pustaka KhanzaSecurity16bit.jar, dan saya menemukannya dengan membaca string di dalam class. Buktinya: mendekripsi nilai lama menghasilkan root dan localhost. Nilai baru saya enkripsi dengan skema yang sama (Python cryptography) dan cadangan file disimpan.

Setelah itu, perbarui conf.php web agar memakai user yang sama.

Masalah & solusi
pkill -f khanza.jar ikut mematikan shell, karena pola itu cocok dengan baris perintah pkill sendiri. Pakai kill $(pgrep -x java).

Langkah 5: Akun login aplikasi (bukan akun database)

Banyak orang tertukar di sini, jadi baca pelan. Ada tiga jenis akun: akun database, akun aplikasi, dan akun web.

Login jendela Khanza memakai tabel admin. Kolomnya terenkripsi dengan AES_ENCRYPT(...) MariaDB, kunci nur untuk user dan windi untuk password. Akun bawaan paket: spv / server.

Untuk menggantinya:

UPDATE admin SET usere=AES_ENCRYPT('USER','nur'), passworde=AES_ENCRYPT('PASSWORD','windi');

Verifikasi dengan AES_DECRYPT. Jika hasilnya sesuai, selesai.

Langkah 6: Update Khanza dari GitHub

Repo tidak menyediakan jar jadi pada rilis terbaru, jadi harus dibangun dari sumber. Repo berukuran ±2,8 GB, sehingga saya memakai clone dangkal:

git clone --depth 1 --filter=blob:none https://github.com/mas-elkhanza/SIMRS-Khanza.git

Hasil checkout tetap ±1,1 GB. Commit saat itu 6ccc813 (10 Okt 2026). sik.sql di repo berukuran sama dengan yang sudah diimpor, sehingga skema dianggap tidak berubah.

Pasang JDK:

sudo apt-get install -y default-jdk-headless

Lalu kompilasi 1.673 file .java dengan javac. Classpath diambil dari kunci javac.classpath di nbproject/project.properties, dipetakan ke JAR di folder lib paket rilis (526 JAR ditemukan semua).

Masalah & solusi 1: Base64 bentrok
Memakai semua jar lib/* sebagai classpath memunculkan error Base64.encodeBase64String, karena ada kelas Base64 lain yang menimpa. Solusinya: ikuti urutan classpath proyek.

Masalah & solusi 2: --release 8 gagal
readAllBytes() butuh Java 9+. Pakai --release 17.

Hasilnya 51.220 class tanpa error. Resource non-Java disalin dari src.

Membuat JAR ternyata punya jebakan sendiri. Manifest harus memuat Main-Class: simrskhanza.SIMRSKhanza dan Class-Path yang sama dengan jar lama (280 entri).

Masalah & solusi 3: baris manifest
Baris manifest maksimum 72 byte. Baris lebih panjang harus dilipat (baris lanjutan diawali spasi, akhiran CRLF), kalau tidak jar error.

khanza.jar yang baru berukuran ±62 MB. Jar lama saya cadangkan sebagai khanza.jar.old, lalu aplikasi dijalankan ulang dan hidup tanpa error di log. Folder webapps repo juga saya bandingkan dengan yang terpasang: sama, tidak ada perubahan berarti.

Catatan jujur: jar layanan lain (antrian, anjungan, service BPJS, dan seterusnya) tidak saya bangun ulang.

Langkah 7: Ikon peluncur di ChromeOS

Aplikasi yang harus dibuka lewat terminal setiap kali itu cepat membosankan. Saya membuat ikon SVG sendiri: kotak teal-biru, salib medis putih, dan garis detak jantung merah. Ikon dirender ke PNG ukuran 48, 128, dan 256 dengan librsvg2-bin (rsvg-convert) ke:

~/.local/share/icons/hicolor/<ukuran>/apps/simrs-khanza.png

Lalu buat ~/.local/share/applications/simrs-khanza.desktop:

  • Exec: java -Xss2m -Xms32m -Xmx1024m -jar khanza.jar
  • Path: folder aplikasi
  • Icon=simrs-khanza

Setelah beberapa saat, ikon muncul di launcher ChromeOS dan bisa dipin ke shelf.

Langkah 8: Data simulasi dasar

Database awal sudah berisi obat (2.011), tarif lab (410) dan radiologi (468), poliklinik, dan lainnya, jadi tidak saya duplikasi. Yang ditambahkan lewat skrip SQL buatan Python (setelah membuat cadangan dump):

  • 18 dokter fiktif (umum dan spesialis) beserta jadwal praktik tiap poli
  • 10 perawat, 5 bidan, 3 apoteker, 4 TTK, 3 analis lab, 2 radiografer, 2 penata anestesi, 3 perawat OK
  • 9 bangsal dan 27 kamar/bed baru, serta 3 ruang operasi
  • 3 supplier
  • 40 pasien fiktif, dengan NIK palsu berawalan 9999
  • Stok obat apotek, gudang, dan IGD

Tekniknya: pegawai dibuat dengan menyalin baris pegawai templat lalu menimpa kolomnya, supaya foreign key tetap utuh. Tabel dokter dan petugas mengacu ke pegawai.nik.

Langkah 9: Dua kasus rawat inap lengkap

Pendekatannya: skrip Python membaca information_schema untuk memvalidasi panjang kolom dan nilai enum, mengisi kolom wajib, lalu menjalankan semuanya dalam satu transaksi, dengan cadangan database sebelum eksekusi. Master data buatan sendiri diberi awalan SIM-: 14 jenis lab dengan template, tarif tindakan, paket operasi, dan 17 obat/BMHP baru.

Kasus A (28 Sep-4 Okt 2026, 6 hari): pria 26 tahun via IGD, appendisitis akut dengan peritonitis lokal (K35.3). Alurnya: asesmen IGD, 12 pemeriksaan lab (leukosit 15.800, CRP 48), USG abdomen, konsul bedah, rawat inap Kelas 2, operasi cito appendektomi terbuka + evakuasi abses + drain (spinal anestesi), laporan operasi rinci, SOAP harian, catatan keperawatan, lab kontrol (leukosit 9.100, CRP 14), drain dilepas, resume pulang, dan resep pulang.

Kasus B (1-8 Okt 2026, 7 hari): anak 7 tahun via Poli Anak dengan demam 8 hari, demam tifoid (A01.0). Lab menunjukkan leukopenia 3.900, Widal O 1/320, dan TUBEX 6. Terapinya ceftriaxone IV 7 hari, ditambah USG abdomen. Kurva suhu turun bertahap, lab kontrol normal, lalu resume dan cefixime untuk pulang.

Tabel yang terisi mencakup reg_periksa, kamar_inap, pemeriksaan_ralan/ranap, penilaian medis dan keperawatan, diagnosa_pasien (ICD-10), prosedur_pasien (ICD-9), lab, radiologi, tindakan, resep dan pemberian obat, operasi, dan resume_pasien_ranap.

Masalah & solusi 1: panjang kolom
Misalnya kolom nyeri_waktu hanya 5 karakter. Validasi skema menangkapnya sebelum data masuk.

Masalah & solusi 2: enum ASA
Kode ASA “1E” tidak ada di enum, jadi dipakai “2E”.

Langkah 10: Billing dan nota

Format tabel billing meniru nota lama di database: baris header, kamar, tindakan, lab, radiologi, operasi, obat, resep pulang, dan total per seksi. Angkanya dihitung dari tabel tindakan, obat, lab, kamar, dan operasi.

KasusNotaTotal
A2026/10/04/RI0001Rp 16.500.007
B2026/10/08/RI0001Rp 4.421.940

Keduanya pasien BPJS, jadi dicatat sebagai piutang BPJS (Belum Lunas), bukan tunai. Tidak ada klaim INA-CBG, dan hasil PA/kultur kasus A ditulis “belum keluar”.

SIMRS Khanza Chromebook Plus
Tangkapan Layar penggunaan SIMRS Khanza pada Chromebook Plus (ChromeOS) yang dijalankan dalam kontainer Debian Linux

Catatan keamanan dan etika

  • Instalasi ini untuk simulasi dan pembelajaran, bukan untuk melayani pasien nyata tanpa audit keamanan, pembaruan, dan kepatuhan regulasi. Data kesehatan adalah data sensitif.
  • Apache mendengarkan di semua antarmuka secara bawaan. Batasi ke localhost bila perlu.
  • Hormati lisensi Khanza dan jangan menjualnya.
  • Pakai data fiktif yang bertanda jelas, dan jangan pernah memakai data pasien asli.

Penutup

Beberapa pelajaran yang saya bawa pulang:

  • Cadangkan database sebelum tiap perubahan besar (mariadb-dump | gzip). Saya melakukannya sebelum setiap skrip besar.
  • Bedakan akun database, akun aplikasi, dan akun web. Ketiganya hidup di tempat berbeda.
  • Jangan taruh password di artikel atau skrip publik.
  • Data fiktif harus bertanda jelas supaya tidak tercampur dengan data nyata.

Ide lanjutan: pelunasan piutang BPJS, pasien umum bayar tunai, akun user per staf, dan kasus persalinan atau ICU.

Checklist ringkas

  • ☐ Linux aktif di ChromeOS, df -h / dicek
  • ☐ Zip rilis diekstrak
  • ☐ Java, MariaDB, Git terpasang; sik.sql diimpor (1.186 tabel)
  • ☐ Apache + PHP terpasang; /webapps/ menampilkan login
  • ☐ User database khusus dibuat, root dibatasi socket
  • ☐ Akun aplikasi diganti
  • ☐ (Opsional) jar dibangun ulang dari GitHub
  • ☐ Ikon peluncur dibuat
  • ☐ Data simulasi dan dua kasus rawat inap terisi
  • ☐ Billing dan nota terbentuk

Artikel Baru Terbit

Commenting 101: “Be kind, and respect each other” // Bersikaplah baik, dan saling menghormati (Indonesian) // Soyez gentils et respectez-vous les uns les autres (French) // Sean amables y respétense mutuamente (Spanish) // 待人友善,互相尊重 (Chinese) // كونوا لطفاء واحترموا بعضكم البعض (Arabic) // Будьте добры и уважайте друг друга (Russian) // Seid freundlich und respektiert einander (German) // 親切にし、お互いを尊重し合いましょう (Japanese) // दयालु बनें, और एक दूसरे का सम्मान करें (Hindi) // Siate gentili e rispettatevi a vicenda (Italian)

3 tanggapan

  1. Avatar Nita

    Kuingin membangun RME yang benar-benar sesuai kebutuhan, tapi bingung belajar awalnya mulai dari apa. Baca post ini aku tersesat, bisakah kasih kisi-kisi bagaimana untuk memulainya?? PS. jadi banyak buka-buka blog ini siapa tau mendapatkan pencerahan.

    1. Avatar Cahya

      Build dari awal adalah pekerjaan besar. Biasanya kalau bukan direncanakan untuk dijadikan SaS (software as service), dianjurkan menggunakan yang sudah ada terlebih dahulu terutama yang open source (misal openEMR). Sementara untuk di Indonesia, semua EMR wajib sistem utamanya ke PlayBook SatuSehat (https://satusehat.kemkes.go.id/platform/docs/id/playbook/), sisanya bisa ditambahkan sesuai kebutuhan.

  2. […] rumah sakit. Bila logikanya kelak dibangun di dalam SIMRS, misalnya SIMRS Khanza yang pernah saya coba pasang di ChromeOS, isian kalkulator dapat dipetakan langsung ke elemen yang diminta modul Pelayanan IGD […]

Tinggalkan Balasan