Lewati ke isi

Sentra Healthcare — Ops (Security + Deployment + Testing)

Security — Healthcare Delta

Baseline security patterns: _shared/security-patterns.md

Overrides

  • MFA Requirement: Seluruh role klinis (Dokter, Perawat, Apoteker) wajib menggunakan MFA untuk login — tidak cukup hanya password. Ini adalah override dari baseline yang hanya merekomendasikan MFA untuk admin. Di healthcare, MFA adalah mandatory tanpa pengecualian sesuai Permenkes 24/2022.

Tambahan Sistem-Spesifik

RME Immutability & BSrE Signature Chain: - Rekam medis yang telah ditandatangani oleh dokter dengan BSrE (Balai Sertifikasi Elektronik) tidak dapat dimodifikasi secara langsung. - Hash BSrE (SHA-256) disimpan di kolom soap_notes.digital_signature_hash. Setiap request UPDATE ke record yang sudah memiliki signed_at ditolak di level aplikasi (middleware layer) sebelum menyentuh database. - Modifikasi setelah sign-off hanya diperbolehkan melalui endpoint Addendum (POST /soap/:id/addendum) yang: (a) memerlukan BSrE re-signing dengan justifikasi tertulis, (b) menyimpan versi lama ke soap_notes_history, (c) mencatat JSON diff penuh ke audit_logs. - Tanda tangan BSrE memberikan legal validity kepada RME — setara dengan tanda tangan basah dalam hukum Indonesia (UU ITE + Permenkes 24/2022).

Patient Data Privacy (UU PDP No. 27/2022 Compliant): - Data sensitif klinis (diagnosa, anamnesa SOAP, alergi, riwayat penyakit) dienkripsi di level kolom PostgreSQL menggunakan AES-256-GCM sebelum disimpan. Aplikasi mendekripsi saat membaca. - Kunci enkripsi dikelola oleh HashiCorp Vault — tidak pernah disimpan di database yang sama dengan data medis. - Data rekam medis di-anonymized (nama disingkat, alamat hanya setingkat kecamatan) di server analitik pelaporan kesehatan. - Retensi Data: Sesuai Permenkes, rekam medis dewasa disimpan minimal 5 tahun setelah kunjungan terakhir; rekam medis anak disimpan hingga 25 tahun atau minimal 5 tahun setelah pasien dewasa. Data tidak boleh dihapus sebelum masa retensi berakhir. - Permintaan akses data pasien dari pihak ketiga (termasuk penyidik hukum) wajib melalui proses persetujuan Owner/Direktur Klinik dan dicatat ke audit_logs dengan kategori EXTERNAL_DATA_REQUEST.

Doctor Authentication for Sign-Off (2FA Dual-Layer): - Sign & Lock SOAP memerlukan 2 faktor autentikasi: 1. Session Login: JWT aktif dari Keycloak (username + password + OTP). 2. PIN BSrE Khusus: PIN terpisah yang terdaftar ke BSrE dan terikat pada identitas dokter (NIK + SIP dokter). PIN ini tidak sama dengan password login dan tidak bisa direset oleh admin klinik. - Percobaan PIN BSrE yang salah > 3 kali membekukan kemampuan sign-off dokter tersebut dan memicu alert ke Clinic Manager.

Audit Logs Append-Only Enforcement: - Di level PostgreSQL, hak UPDATE dan DELETE pada tabel audit_logs direvoke dari semua application roles:

REVOKE UPDATE, DELETE ON audit_logs FROM app_role;
- Hanya SELECT dan INSERT yang diizinkan — mencegah manipulasi jejak audit oleh insider. - Faktur billing yang sudah terbit dikunci secara absolut. Void/diskon wajib PIN Supervisor dan dicatat ke audit log.

Anti-Allergy Prescription Guard: - Setiap item resep divalidasi terhadap profil alergi pasien (kolom patients.allergies) sebelum disimpan. - Jika terdapat konflik alergi, sistem menampilkan modal peringatan warna merah yang memaksa dokter memilih antara batalkan atau bypass dengan justifikasi tertulis yang dilog ke audit_logs dengan level HIGH_SEVERITY_ALLERGY_OVERRIDE.


Deployment — Healthcare Delta

Baseline deployment: _shared/deployment-baseline.md

Overrides

  • Database: Amazon Aurora PostgreSQL (Active-Passive Multi-AZ) — bukan RDS standar — untuk memastikan failover otomatis < 30 detik tanpa kehilangan data transaksi klinis.

Tambahan Sistem-Spesifik

SatuSehat Bridging Service (Dedicated Microservice): - Karena SatuSehat IHS API bersifat rate-limited dan frekuensi timeout-nya lebih tinggi dari API eksternal lain, adapter SatuSehat dijalankan sebagai dedicated ECS/EKS pod terpisah dari core monolith. - Pod SatuSehat bisa di-scale independen saat volume kunjungan klinik meningkat (misal: musim flu). - RabbitMQ FHIR Queue berfungsi sebagai buffer decoupling antara core backend dan SatuSehat pod.

BPJS Gateway Dedicated Network: - Akses ke BPJS PCare dan VClaim API mengharuskan IP Whitelist yang didaftarkan ke BPJS Kesehatan secara manual. - Klinik yang terdaftar di jaringan SentraClinic mendapatkan IP Elastic (static) yang didaftarkan satu kali ke BPJS. - Untuk VClaim (FKRTL), jaringan komunikasi menggunakan VPN dedicated atau leased line khusus BPJS FKRTL — tidak bisa menggunakan koneksi internet publik biasa. - BPJSAdapter berjalan di subnet terpisah dengan Security Group yang hanya mengizinkan outbound ke IP BPJS Kesehatan.

Edge Node (Offline-First Clinic Server): - Setiap cabang klinik memiliki mini PC lokal (Intel NUC / Raspberry Pi Server) yang menjalankan Go Sync Daemon + SQLCipher database. - SQLCipher passphrase disimpan di HashiCorp Vault Agent yang berjalan di edge node — bukan di environment variable atau file plain text. - Edge node dikonfigurasi dengan Docker Compose (lihat konfigurasi di bawah). - Sync daemon memonitor status internet setiap 5 detik; begitu internet pulih, outbox queue diproses secara batch.

# docker-compose.yml — Edge Clinic Node
version: '3.8'
services:
  edge-gateway:
    image: sentraclinic/edge-sync-daemon:latest
    container_name: local_sync_gateway
    restart: always
    environment:
      - CLINIC_BRANCH_ID=99ea7b42-1200-4b32-8411-d00db60ab292
      - CLOUD_API_URL=https://api.sentraclinic.co.id/v1
      - LOCAL_SQLITE_PATH=/data/sentraclinic_local.db
      - SQLCIPHER_PASSPHRASE_FILE=/vault/secrets/cipher_key.txt
      - RECONCILIATION_INTERVAL_SECS=30
    volumes:
      - edge-db-volume:/data
      - /etc/vault/secrets:/vault/secrets:ro
    ports:
      - "8080:8080"
    networks:
      - clinic-lan

  edge-queue-display:
    image: sentraclinic/queue-display-web:latest
    restart: always
    ports:
      - "80:80"
    environment:
      - EDGE_API_HOST=http://edge-gateway:8080
    networks:
      - clinic-lan

volumes:
  edge-db-volume:
    driver: local

networks:
  clinic-lan:
    driver: bridge

Backup & Georedundancy (Medical Records Compliance): - Rekam medis wajib disimpan dengan georedundant backup (minimal 2 region AWS) sesuai standar keamanan data kesehatan. - Backup PostgreSQL dilakukan setiap 6 jam dengan retenti snapshot 30 hari. - Immutable Backup: Backup RME menggunakan AWS Backup dengan Vault Lock (WORM — Write Once Read Many) untuk mencegah penghapusan backup sebelum periode retensi berakhir (sesuai kebutuhan retensi Permenkes 25+ tahun). - Recovery Point Objective (RPO): < 6 jam. Recovery Time Objective (RTO): < 2 jam.


Testing Checklist

Kategori Skenario Test Target / Expected Result Tipe
SatuSehat Integration Simulasi HTTP Timeout pada SatuSehat API saat pengiriman SOAP Sistem menyimpan payload FHIR ke antrian fallback SQLite dan tidak memblokir antrean dokter. Begitu koneksi pulih, background task memproses sinkronisasi secara tertib Integration / Mock API
RME Lock Enforcement Attempt PUT /soap setelah sign-off BSrE API mengembalikan HTTP 423 Locked. Data SOAP tidak berubah Unit / Security
BSrE Invalid Signature Submit SOAP dengan signature hash BSrE yang tidak valid API mengembalikan HTTP 422 Unprocessable. SOAP tidak tersimpan. Audit log mencatat percobaan gagal Unit / Security
Konkurensi Antrean 20 frontdesk menekan tombol "Ambil Antrean" secara bersamaan Database mengeluarkan nomor antrean unik berurutan tanpa duplikasi (Zero Duplicate) Performance / Concurrency
FEFO Resep E-Prescribing paralel untuk obat dengan stok tipis Stok batch terpotong tanpa race condition; batch ke-21 error Out of Stock jika stok habis, tidak ada stok minus Unit / Stress Test
PPh 21 Kalkulasi Kalkulasi PPh 21 jasa medis untuk dokter berstatus pegawai vs freelance Validasi kesesuaian formula slip gaji dokter dengan tabel PPh 21 progresif DJP RI Functional / QA Audit
Skenario Offline Cabut internet saat proses SOAP dokter berjalan Aplikasi desktop mendeteksi offline, merutekan query ke SQLite lokal, memperbolehkan input SOAP dasar, menahan antrian lokal dengan andal Operational / Chaos Test
BPJS API Downtime BPJS PCare API tidak merespons selama 30 menit Data kunjungan masuk antrian retry lokal; kasir tetap bisa memproses pembayaran cash; alert terkirim ke admin setelah 3 retry gagal Integration / Resilience
Allergy Guard Dokter menulis resep Amoxicillin untuk pasien dengan alergi Amoxicillin Modal peringatan warna merah muncul; resep tidak tersimpan sampai dokter konfirmasi bypass dengan justifikasi Unit / Safety
Audit Log Immutability Attempt UPDATE/DELETE langsung ke tabel audit_logs via psql PostgreSQL mengembalikan permission denied untuk app_role Security / DB