Module: Medical Record (RME)¶
Modul RME adalah inti dari SentraClinic EMR. Landasan legalitasnya berasal dari Permenkes RI No. 24/2022 yang mewajibkan seluruh RME: (1) terstruktur digital, (2) ditandatangani digital oleh dokter, (3) terhubung ke SatuSehat, dan (4) bersifat immutable setelah sign-off.
RME Lifecycle Flowchart¶
sequenceDiagram
participant P as Pasien
participant N as Perawat/Nurse
participant D as Dokter/Clinician
participant DB as Secure DB
participant BSrE as BSrE Signature API
participant SS as SatuSehat Kemenkes
P->>N: Registrasi & Cek Tensi
N->>DB: Simpan Vital Sign (Encounter created)
N->>D: Pasien siap diperiksa
D->>DB: Baca riwayat rekam medis (Generate audit log READ)
D->>D: Isi SOAP notes & Diagnosa ICD-10
D->>DB: Kirim e-Prescribing (Stok terpotong sementara via FEFO)
D->>BSrE: Request Digital Signature dengan PIN Dokter (2FA required)
BSrE-->>D: Return BSrE signature hash (SHA-256)
D->>DB: Simpan SOAP + digital_signature_hash (Lock SOAP)
Note over DB: RME status = LOCKED. UPDATE diblokir.
DB-->>SS: Kirim payload HL7 FHIR Encounter (Background Job via RabbitMQ)
Note over D,DB: Addendum Mode diaktifkan jika perlu revisi setelah lock
SOAP Immutability Rules¶
Setelah dokter melakukan sign-off:
- Kolom
signed_atdandigital_signature_hashpada tabelsoap_notesterisi. - Semua request
PUT /encounters/:id/soapsetelah ini akan dikembalikanHTTP 423 Locked. - Modifikasi hanya diperbolehkan melalui endpoint
POST /soap/:id/addendumyang: - Menyalin baris SOAP lama ke
soap_notes_historydenganversionincremental. - Tidak menghapus atau menimpa data SOAP original.
- Memerlukan BSrE re-signing dengan justifikasi tertulis (
addendum_reason). - Mencatat entry baru ke
audit_logsdenganaction_type = 'UPDATE'danjson_diffpenuh.
Catatan penting: Mekanisme 2FA (PIN khusus sign-off) diwajibkan saat dokter menekan tombol "Sign & Lock SOAP". PIN ini terpisah dari password login biasa dan divalidasi oleh Keycloak + BSrE sebelum tanda tangan diterbitkan.
Patient Queue State Machine¶
[*] --> REGISTERED : Pasien Terdaftar / Walk-in / Booking Online
REGISTERED --> TRIAGE : Dipanggil ke Ruang Triage oleh Perawat
TRIAGE --> WAITING_DOCTOR : Selesai Vital Sign
WAITING_DOCTOR --> CONSULTATION : Dipanggil oleh Dokter
CONSULTATION --> PHARMACY : Selesai SOAP & Dokter Mengirimkan Resep
PHARMACY --> BILLING : Obat Selesai Dipacking
BILLING --> COMPLETED : Pembayaran Diterima / Pasien Keluar
TRIAGE --> BILLING : Batal Berobat / Rujukan Langsung ke RS (Emergency)
CONSULTATION --> BILLING : Selesai Konsultasi Tanpa Resep
Integrity Auditing & SOAP Modification Rules¶
Setiap akses ke database RME memicu trigger audit tingkat rendah. Jika seorang dokter memodifikasi rekam medis sebelum sign-off:
- Sistem menyalin baris SOAP lama ke tabel
soap_notes_history. - Data lama tidak ditimpa secara permanen; melainkan data terbaru dipasang sebagai versi
v2. - Audit log mencatat:
TIMESTAMP,USER_ID,ACTION=UPDATE,DIFFERENCE=JSON_DIFF.
Triage & Prioritisation Algorithm¶
- Triage Red (IGD / Critical): Melompati seluruh urutan antrean poli, memicu alarm visual di EMR Dokter dan memindahkan status pasien langsung ke ruang tindakan utama.
- Triage Yellow (Urgent): Diberikan bobot penambah prioritas sebesar +10 tingkat dalam antrean reguler.
- Triage Green (Non-Urgent): Mengikuti antrean reguler berdasarkan timestamp registrasi.
Emergency Bypass: Kasir/Suster dapat memicu tombol "Emergency Bypass" di antrean. Sistem segera menghasilkan nomor rekam medis darurat otomatis (RM-EMERGENCY-TEMP-#####), menerbitkan tiket prioritas tertinggi, dan membuka EMR SOAP IGD secara instan tanpa mengharuskan input NIK/KTP pasien di awal. Profil dapat dilengkapi setelah pasien stabil.
Pharmacy FEFO Flow¶
graph TD
A[Dokter Kirim e-Prescription] --> B[Apotek: Masuk Antrean Resep Farmasi]
B --> C{Pemeriksaan Resep: Interaksi Obat & Dosis}
C -- Ada Isu --> D[Picu Konfirmasi ke Dokter]
C -- Lolos Verifikasi --> E{Jenis Obat?}
E -- Non-Racikan --> F[Auto-Alokasi Stok FEFO dari Batch Terdekat]
E -- Racikan --> G[Compounding: Input Bahan Baku & Jumlah]
F --> H[Pengemasan & Pemberian Etiket Obat]
G --> H
H --> I[Double-Check oleh Apoteker Kedua]
I --> J[Kirim Notifikasi Pembayaran ke Kasir]
J --> K[Obat Diserahkan ke Pasien & Edukasi Aturan Minum]
FEFO Allocation Engine (pseudo-code):
async function allocateStockFEFO(medicineId, requestedQty, trx) {
const activeBatches = await trx('medicine_batches')
.where('medicine_id', medicineId)
.where('stock_qty', '>', 0)
.where('expiry_date', '>', new Date())
.orderBy('expiry_date', 'asc'); // First Expired, First Out
let remainingToAllocate = requestedQty;
const allocations = [];
for (const batch of activeBatches) {
if (remainingToAllocate <= 0) break;
const allocQty = Math.min(batch.stock_qty, remainingToAllocate);
allocations.push({
batchId: batch.id,
batchNumber: batch.batch_number,
allocatedQty: allocQty
});
remainingToAllocate -= allocQty;
// Deduct stock temporarily inside atomic transaction
await trx('medicine_batches')
.where('id', batch.id)
.decrement('stock_qty', allocQty);
}
if (remainingToAllocate > 0) {
throw new Error(`Insufficient stock for medicine ID: ${medicineId}.`);
}
return allocations;
}
Allergy Conflict Detection¶
Begitu dokter menambahkan obat yang bertentangan dengan profil alergi terdaftar ke dalam tabel resep EMR, sistem secara instan menampilkan modal peringatan berkedip warna merah yang mengharuskan dokter memilih antara:
- (a) Membatalkan resep obat, atau
- (b) Melakukan bypass manual dengan memasukkan justifikasi medis darurat (misal: "Manfaat melebihi risiko klinis, dilakukan pengawasan ketat") — yang dicatat ke audit log dengan level HIGH_SEVERITY.
User Story: Dokter Menandatangani Rekam Medis¶
- As a Dokter Spesialis/Umum
- I want to Menandatangani rekam medis SOAP secara digital dan menguncinya setelah selesai mendiagnosa pasien.
- So that Data pemeriksaan terekam dengan aman, terinteroperabilitas dengan SatuSehat, dan mematuhi regulasi Permenkes No. 24/2022.
Acceptance Criteria:
- Given Dokter telah selesai memasukkan data SOAP dan Encounter berstatus
CONSULTATION. - When Dokter mengklik "Sign & Lock SOAP" dan memasukkan PIN tanda tangan digital medis yang sah.
- Then Sistem menghasilkan hash SHA-256 kriptografis via BSrE API dari payload SOAP tersebut.
- And Mengubah status Encounter menjadi
PHARMACYdan status SOAP menjadi locked. - And Memicu antrean background job asinkron untuk mengirimkan data FHIR ke SatuSehat Kemenkes.
- And Menampilkan pesan sukses "EMR Locked and Sync Triggered".