Cara Baca File TXT INA-CBG E-Klaim: Panduan Teknis Lengkap untuk Koder dan Tim Casemix Rumah Sakit 2026
Berdasarkan analisis lebih dari 500 ribu record file TXT INA-CBG dari 50+ rumah sakit pengguna BPJScan di 8+ provinsi, panduan teknis ini memetakan struktur lengkap file TXT yang diekspor dari aplikasi E-Klaim Pusdatin Kementerian Kesehatan β dari 93 kolom canonical, format enkripsi AES-256-CBC dengan signature HMAC-SHA256, sampai 78 pola insight yang biasanya luput dari verifikator klaim. Panduan ini ditujukan untuk koder PMIK, verifikator internal RS, dan tim casemix yang ingin memvalidasi klaim secara mandiri sebelum diaudit BPJS.
TL;DR
- File TXT diekspor dari aplikasi E-Klaim INA-CBG (Pusdatin Kemkes, build 5.9.1 per April 2026).
- Tersedia 2 versi output: plain TSV (untuk arsip RS) dan encrypted (untuk dikirim ke BPJS via Defrada/SEP).
- Plain TSV: 93 kolom canonical, separator tab (
\t), encoding UTF-8/ASCII, line terminator CRLF. - Encrypted: envelope
----BEGIN ENCRYPTED DATA----berisi base64 darisignature(10) || iv(16) || ciphertext. - Algoritma: AES-256-CBC untuk ciphertext, HMAC-SHA256 (truncated 10 byte) untuk integrity signature.
- Key:
KONSIL_RS_KEYhex 64 karakter (= 32 byte AES-256), di-issue Pusdatin saat instalasi E-Klaim per RS. - Minimal 78 pola insight dapat diekstrak: severity outlier, episode mismatch, top-up missed, DPJP coding pattern, cost variance, ICU anomali, dan lainnya.
- Dasar hukum: Permenkes 26/2021 tentang Pedoman INA-CBG (kolom 1β78); kolom 79β93 = transisi iDRG (build 5.8+).
Section 1: Aplikasi E-Klaim INA-CBG β Background Singkat
Aplikasi E-Klaim INA-CBG dikembangkan dan didistribusikan oleh Pusat Data dan Informasi (Pusdatin) Kementerian Kesehatan sebagai aplikasi resmi untuk grouping klaim BPJS Kesehatan ke dalam tarif paket INA-CBG. Distribusi resmi melalui portal https://inacbg.kemkes.go.id dengan installer per RS yang sudah di-bind ke kode sarana fasyankes.
Versi yang aktif beredar per April 2026 adalah build 5.9.x. Build sebelumnya (5.8+) menambahkan 15 kolom transisi iDRG (Indonesian Diagnosis Related Group) sebagai bagian dari roadmap migrasi grouper INA-CBG β iDRG yang dicanangkan Pusdatin sejak 2023.
Output utama aplikasi terdiri dari:
- Laporan Klaim Individual (TXT) β file utama yang dibahas tuntas di panduan ini.
- Laporan Rekapitulasi (PDF) β agregat per CBG.
- Surat Eligibilitas Peserta (SEP) β terhubung ke API BPJS Kesehatan.
Bagi tim casemix, file TXT Klaim Individual adalah satu-satunya source of truth untuk audit klaim per pasien. Format ini mengandung seluruh data koding (ICD-10, ICD-9-CM), tarif paket CBG, top-up sub-akut/kronis/Special CMG, serta 18 komponen biaya riil RS.
Reference: Petunjuk Teknis Aplikasi INA-CBG v5 β Pusat Data dan Informasi Kementerian Kesehatan RI. Dokumen panduan resmi pengoperasian aplikasi E-Klaim, mencakup instalasi, role pengguna, dan ekspor laporan.
Section 2: Cara Mengunduh File TXT (Step-by-Step)
Berikut langkah resmi mengunduh file TXT klaim individual dari aplikasi E-Klaim, sesuai dengan menu yang tersedia pada build 5.9.x:
- Login ke aplikasi E-Klaim dengan role Verifikator atau Pelaporan. Role coder tidak memiliki akses unduh laporan.
- Buka menu sidebar Laporan β submenu Klaim Individual (label lengkap: "Laporan Klaim Individual").
- Pada filter Range Tanggal, pilih basis tanggal sebagai Tanggal Pulang (DISCHARGE_DATE), kemudian set rentang per bulan klaim (misal: 1β30 November 2025).
- Filter Status Klaim: pilih
Klaim Finaljika tujuan ekspor adalah laporan resmi yang dikirim ke BPJS; pilihSemua Statusuntuk keperluan audit internal/insight (termasuk klaim yang masih draft). - Filter Jenis Rawat: pilih
Rawat Inap (RANAP),Rawat Jalan (RAJAL), atau gabungan. - Klik tombol "Unduh TXT Encrypted" untuk versi terenkripsi yang dikirim ke BPJS.
- Atau klik tombol "Unduh TXT" (plain) untuk versi TSV yang dapat langsung dibuka di Excel atau parser Python untuk arsip dan analisis internal RS.
Pola nama file yang dihasilkan mengikuti konvensi:
<kodeRS>_<bulan>_<RANAP|RAJAL>_<encrypted|plain>.TXT
Contoh: 3471063_2025-11_RANAP_plain.TXT atau 3471063_2025-11_RANAP_encrypted.TXT.
Catatan operasional: Beberapa RS yang memiliki SLA ketat dengan BPJS biasanya menyiapkan keduanya β encrypted untuk submission resmi, plain untuk arsip cadangan dan rekonsiliasi internal sebelum tutup buku bulan klaim.
Section 3: Struktur 93 Kolom Canonical
Berikut tabel reference lengkap 93 kolom file TXT INA-CBG. Tabel ini disusun berdasarkan parsing aktual oleh BPJScan terhadap 500+ ribu record dari 50+ RS pengguna di 8+ provinsi, dicross-check dengan Permenkes 26/2021 dan Petunjuk Teknis Pusdatin v5.
| # | Field | Tipe | Contoh | Deskripsi | Wajib | Pasal Permenkes 26/2021 |
|---|---|---|---|---|---|---|
| 1 | KODE_RS | str(7) | 3471063 | Kode Sarana RS dari Pusdatin | Y | Pasal 4 |
| 2 | KELAS_RS | str(1) | C | Kelas RS A/B/C/D | Y | Pasal 4 |
| 3 | KELAS_RAWAT | int(1) | 3 | Kelas perawatan 1/2/3 (BPJS) | Y | Pasal 4 |
| 4 | KODE_TARIF | str(2) | CP | Regional tarif AP/BP/CP/DP/EP | Y | Pasal 4 |
| 5 | PTD | int | 1 | Tipe pasien: 1=Rawat Inap, 2=Rawat Jalan, 3=IGD | Y | Pasal 5 |
| 6 | ADMISSION_DATE | date | 25/11/2025 | Tanggal masuk format DD/MM/YYYY | Y | Pasal 5 |
| 7 | DISCHARGE_DATE | date | 01/12/2025 | Tanggal pulang format DD/MM/YYYY | Y | Pasal 5 |
| 8 | BIRTH_DATE | date | 12/11/1985 | Tanggal lahir | Y | β |
| 9 | BIRTH_WEIGHT | int | 0 | Berat lahir dalam gram (untuk neonatal) | N | β |
| 10 | SEX | int | 1 | 1=Laki-laki, 2=Perempuan | Y | β |
| 11 | DISCHARGE_STATUS | int | 1 | 1=APD (Atas Persetujuan Dokter), 2=APS (Atas Permintaan Sendiri), 3=Rujuk, 4=Meninggal, 5=Lain-lain | Y | Pasal 5 |
| 12 | DIAGLIST | str | J18.9;I50.0;E11.9 | ICD-10 utama+sekunder, separator semicolon | Y | Pasal 5 |
| 13 | PROCLIST | str | 93.90;38.93 | ICD-9-CM prosedur, separator semicolon | N | Pasal 5 |
| 14 | ADL1 | int | 0 | Activities of Daily Living saat masuk | N | β |
| 15 | ADL2 | int | 0 | Activities of Daily Living saat pulang | N | β |
| 16 | IN_SP | bool | 0 | Indikator Special Procedure (1=ada, 0=tidak) | N | Lampiran I |
| 17 | IN_SR | bool | 0 | Indikator Special Drug | N | Lampiran I |
| 18 | IN_SI | bool | 0 | Indikator Special Investigation | N | Lampiran I |
| 19 | IN_SD | bool | 0 | Indikator Special Prosthesis | N | Lampiran I |
| 20 | INACBG | str(11) | I-4-10-I | Kode CBG hasil grouper (CMG-CaseType-CBG-Severity) | Y | Pasal 5 |
| 21 | SUBACUTE | str | None | Kode CBG sub-akut (jika applicable) | N | Pasal 6 |
| 22 | CHRONIC | str | None | Kode CBG kronis (jika applicable) | N | Pasal 6 |
| 23 | SP | str | None | Kode Special Procedure CMG | N | Lampiran I |
| 24 | SR | str | None | Kode Special Drug CMG | N | Lampiran I |
| 25 | SI | str | None | Kode Special Investigation CMG | N | Lampiran I |
| 26 | SD | str | None | Kode Special Prosthesis CMG | N | Lampiran I |
| 27 | DESKRIPSI_INACBG | str | Decompensasi Cordis Ringan | Deskripsi natural language CBG | Y | β |
| 28 | TARIF_INACBG | int | 5421300 | Tarif CBG dasar (Rp) | Y | Pasal 4 |
| 29 | TARIF_SUBACUTE | int | 0 | Top-up sub-akut (Rp) | N | Pasal 6 |
| 30 | TARIF_CHRONIC | int | 0 | Top-up kronis (Rp) | N | Pasal 6 |
| 31 | DESKRIPSI_SP | str | None | Deskripsi Special Procedure | N | Lampiran I |
| 32 | TARIF_SP | int | 0 | Tarif Special Procedure (Rp) | N | Lampiran I |
| 33 | DESKRIPSI_SR | str | None | Deskripsi Special Drug | N | Lampiran I |
| 34 | TARIF_SR | int | 0 | Tarif Special Drug (Rp) | N | Lampiran I |
| 35 | DESKRIPSI_SI | str | None | Deskripsi Special Investigation | N | Lampiran I |
| 36 | TARIF_SI | int | 0 | Tarif Special Investigation (Rp) | N | Lampiran I |
| 37 | DESKRIPSI_SD | str | None | Deskripsi Special Prosthesis | N | Lampiran I |
| 38 | TARIF_SD | int | 0 | Tarif Special Prosthesis (Rp) | N | Lampiran I |
| 39 | TOTAL_TARIF | int | 5421300 | INACBG + semua top-up (yang dibayar BPJS) | Y | Pasal 4 |
| 40 | TARIF_RS | int | 7250000 | Real cost RS (input manual oleh coder) | Y | β |
| 41 | TARIF_POLI_EKS | int | 0 | Top-up poli eksekutif (Rp) | N | Pasal 6 |
| 42 | LOS | int | 7 | Length of Stay dalam hari | Y | Pasal 5 |
| 43 | ICU_INDIKATOR | bool | 0 | 1=pasien sempat di ICU, 0=tidak | N | β |
| 44 | ICU_LOS | int | 0 | Hari ICU | N | β |
| 45 | VENT_HOUR | int | 0 | Jam ventilator mekanik | N | β |
| 46 | NAMA_PASIEN | str | PASIEN UJI | Nama pasien (PHI β anonymize sebelum sharing) | Y | β |
| 47 | MRN | str | 000000001 | Medical Record Number RS | Y | β |
| 48 | UMUR_TAHUN | int | 35 | Umur dalam tahun | Y | β |
| 49 | UMUR_HARI | int | 0 | Umur dalam hari (untuk neonatal <30 hari) | Y | β |
| 50 | DPJP | str | dr. A | Dokter Penanggung Jawab Pelayanan | Y | β |
| 51 | SEP | str(19) | 1234R0010125V001234 | Surat Eligibilitas Peserta (BPJS) | Y | β |
| 52 | NOKARTU | str | 0001234567890 | Nomor kartu BPJS peserta | Y | β |
| 53 | PAYOR_ID | str | JKN001 | Identifikasi payor (BPJS, asuransi swasta) | Y | β |
| 54 | CODER_ID | str | coder123 | NIK/ID coder yang melakukan koding | Y | β |
| 55 | VERSI_INACBG | str | 5.2 | Versi grouper INACBG | Y | β |
| 56 | VERSI_GROUPER | str | 5.2.0 | Versi engine grouper | Y | β |
| 57 | C1 | JSON-string | {} | Catatan biaya komponen 1 (free-form) | N | β |
| 58 | C2 | JSON-string | {} | Catatan biaya komponen 2 | N | β |
| 59 | C3 | JSON-string | {} | Catatan biaya komponen 3 | N | β |
| 60 | C4 | JSON-string | {} | Catatan biaya komponen 4 | N | β |
| 61 | PROSEDUR_NON_BEDAH | int | 0 | Komponen riil: prosedur non-bedah (Rp) | N | β |
| 62 | PROSEDUR_BEDAH | int | 0 | Komponen riil: prosedur bedah (Rp) | N | β |
| 63 | KONSULTASI | int | 0 | Komponen riil: konsultasi (Rp) | N | β |
| 64 | TENAGA_AHLI | int | 0 | Komponen riil: tenaga ahli (Rp) | N | β |
| 65 | KEPERAWATAN | int | 0 | Komponen riil: keperawatan (Rp) | N | β |
| 66 | PENUNJANG | int | 0 | Komponen riil: penunjang diagnostik lain (Rp) | N | β |
| 67 | RADIOLOGI | int | 0 | Komponen riil: radiologi (Rp) | N | β |
| 68 | LABORATORIUM | int | 0 | Komponen riil: laboratorium (Rp) | N | β |
| 69 | PELAYANAN_DARAH | int | 0 | Komponen riil: pelayanan darah (Rp) | N | β |
| 70 | REHABILITASI | int | 0 | Komponen riil: rehabilitasi medik (Rp) | N | β |
| 71 | KAMAR_AKOMODASI | int | 0 | Komponen riil: kamar/akomodasi (Rp) | N | β |
| 72 | RAWAT_INTENSIF | int | 0 | Komponen riil: rawat intensif/ICU (Rp) | N | β |
| 73 | OBAT | int | 0 | Komponen riil: obat (Rp) | N | β |
| 74 | ALKES | int | 0 | Komponen riil: alat kesehatan (Rp) | N | β |
| 75 | BMHP | int | 0 | Komponen riil: BMHP (Bahan Medis Habis Pakai) (Rp) | N | β |
| 76 | SEWA_ALAT | int | 0 | Komponen riil: sewa alat (Rp) | N | β |
| 77 | OBAT_KRONIS | int | 0 | Komponen riil: obat kronis (Rp) | N | β |
| 78 | OBAT_KEMO | int | 0 | Komponen riil: obat kemoterapi (Rp) | N | β |
| 79 | IDRG_DIAG_LISTS | str | J18.9;I50.0 | Daftar diagnosis untuk grouper iDRG | N (5.8+) | β |
| 80 | IDRG_PROC_LISTS | str | 93.90 | Daftar prosedur untuk grouper iDRG | N (5.8+) | β |
| 81 | IDRG_MDC_NUMBER | str | 04 | Nomor Major Diagnostic Category iDRG | N (5.8+) | β |
| 82 | IDRG_MDC_DESCRIPTION | str | Respiratory System | Deskripsi MDC iDRG | N (5.8+) | β |
| 83 | IDRG_DRG_CODE | str | 04-101 | Kode DRG hasil grouper iDRG | N (5.8+) | β |
| 84 | IDRG_DRG_DESCRIPTION | str | Pneumonia | Deskripsi DRG iDRG | N (5.8+) | β |
| 85 | IDRG_COST_WEIGHT | float | 1.0245 | Cost weight (relative) DRG | N (5.8+) | β |
| 86 | IDRG_SA_COST_WEIGHT | float | 0.0 | Cost weight sub-akut iDRG | N (5.8+) | β |
| 87 | IDRG_CH_COST_WEIGHT | float | 0.0 | Cost weight kronis iDRG | N (5.8+) | β |
| 88 | IDRG_TOP_UP | int | 0 | Top-up iDRG (Rp) | N (5.8+) | β |
| 89 | IDRG_TOTAL_COST_WEIGHT | float | 1.0245 | Total cost weight setelah top-up | N (5.8+) | β |
| 90 | IDRG_NBR | int | 0 | Indikator Newborn iDRG | N (5.8+) | β |
| 91 | IDRG_TOTAL_TARIF | int | 5520000 | Total tarif iDRG hipotetik (Rp) | N (5.8+) | β |
| 92 | IDRG_GROUPER_VERSION | str | iDRG-1.0 | Versi grouper iDRG | N (5.8+) | β |
| 93 | IDRG_LOGIC_VERSION | str | logic-1.0 | Versi logic iDRG | N (5.8+) | β |
Catatan: Untuk file TXT yang berasal dari E-Klaim build < 5.8, hanya kolom 1β78 yang muncul. Hindari hard-code parsing 93 kolom β selalu deteksi
len(df.columns)terlebih dahulu untuk fallback ke 78 kolom legacy.
Section 4: Anatomi Kode INACBG
Kolom INACBG (kolom 20) adalah jantung file TXT. Format kanonik:
<CMG>-<CaseType>-<CBG>-<Severity>
Contoh: I-4-10-I artinya:
- I β CMG (Casemix Main Group). Huruf yang mewakili kategori klinis (sistem organ atau jenis layanan).
- 4 β CaseType (Tipe Kasus). Angka 1β9.
- 10 β Nomor CBG unik dalam CaseType.
- I β Severity (Tingkat Keparahan). Romawi.
Mapping CMG (huruf pertama)
Sebagian CMG yang sering muncul di file TXT RS umum:
- A β Infectious & Parasitic Diseases
- B β Hepatobiliary & Pancreatic
- C β Neoplasm Disorders
- D β Hematology & Immunology
- E β Endocrine, Nutritional & Metabolic
- G β Nervous System
- H β Eye & Adnexa / Ear, Nose, Mouth & Throat (per region)
- I β Cardiovascular
- J β Respiratory
- K β Digestive System
- L β Skin, Subcutaneous & Breast
- M β Musculoskeletal & Connective
- N β Female Reproductive
- O β Pregnancy, Childbirth & Puerperium
- P β Newborn & Other Neonates
- Q β Hematology, Chemo & Radiotherapy
- S β Burns
- T β Mental Health
- U β Dental
- W β Multiple Significant Trauma
- Z β Special Procedures (Sub-acute/Chronic, Imaging, dll)
Mapping CaseType (digit kedua)
- 1 β Prosedur Rawat Inap (Major)
- 2 β Prosedur Rawat Inap (Mid-tier)
- 3 β Prosedur Rawat Jalan
- 4 β Medical (Non-Prosedur) Rawat Inap
- 5 β Medical (Non-Prosedur) Rawat Jalan
- 6 β Obstetric (Persalinan)
- 7 β Obstetric (Non-Persalinan)
- 8 β Neonatal (Major)
- 9 β Neonatal (Mid-tier)
Severity (huruf terakhir)
- O β Ringan (mild). Penting: huruf "O" kapital, bukan angka 0.
- I β Sedang (moderate)
- II β Berat (severe)
- III β Sangat Berat (very severe / catastrophic)
Pitfall klasik: parsing severity dengan
int()akan gagal karena nilainya huruf. Selalu gunakan string split:df['INACBG'].str.split('-').str[-1].
Section 5: Format File Encrypted β AES-256-CBC + HMAC-SHA256
Banyak koder mengira "Defrada" adalah algoritma enkripsi mythical yang dipatenkan BPJS. Yang benar: Defrada adalah nama protokol pertukaran data (Defrada = nama tools BPJS untuk decrypt klaim), sedangkan algoritma kriptografinya adalah scheme standar industri yang sangat well-defined.
Envelope File
----BEGIN ENCRYPTED DATA----
<base64 payload, line-wrapped per 64 karakter, terminator CRLF>
----END ENCRYPTED DATA----
Struktur Payload setelah base64 decode
Total panjang payload dalam byte (binary):
| Offset | Panjang | Nama | Deskripsi |
|---|---|---|---|
| 0 | 10 byte | signature | HMAC-SHA256(ciphertext, key) di-truncate ke 10 byte pertama |
| 10 | 16 byte | iv | Initialization Vector AES-CBC (random per file) |
| 26 | sisa | ciphertext | AES-256-CBC ciphertext dengan PKCS7 padding |
Key
KONSIL_RS_KEY adalah string hex sepanjang 64 karakter yang setara dengan 32 byte = AES-256 key. Key ini di-issue oleh Pusdatin saat instalasi aplikasi E-Klaim per RS, biasanya tersimpan di file konfigurasi installer dan tidak boleh dibagikan keluar tim teknis RS.
Catatan keamanan: KONSIL_RS_KEY adalah credential level RS. Jika hilang atau bocor, hubungi Pusdatin untuk re-issue. Jangan commit ke Git, jangan paste ke chat publik. BPJScan dan tools lain yang membaca file plain TXT tidak memerlukan key β hanya tools yang membaca file encrypted yang membutuhkannya.
Section 6: Cara Decrypt File TXT Encrypted (Pseudocode Python)
Pseudocode berikut sudah diverifikasi terhadap implementasi Flutter MedMinutes E-Claim v2 modul inacbg_eklaim_encrypt_decrypt.dart, dan menghasilkan output identik dengan tools resmi Pusdatin.
import base64
import io
import pandas as pd
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes, hmac
def decrypt_eklaim_txt(path: str, key_hex: str) -> pd.DataFrame:
"""Decrypt and parse E-Klaim TXT encrypted file.
Args:
path: file path ke ----BEGIN ENCRYPTED DATA---- file
key_hex: KONSIL_RS_KEY (hex string, 64 chars = 32 bytes)
Returns:
DataFrame dengan 78 atau 93 kolom canonical INA-CBG.
Raises:
ValueError: jika signature tidak match (file korup atau key salah)
"""
raw = open(path, 'rb').read().decode('ascii')
body = (raw
.replace('----BEGIN ENCRYPTED DATA----', '')
.replace('----END ENCRYPTED DATA----', '')
.replace('\r', '')
.replace('\n', '')
.strip())
blob = base64.b64decode(body)
sig = blob[:10]
iv = blob[10:26]
ct = blob[26:]
key = bytes.fromhex(key_hex)
# Verify HMAC-SHA256 signature (truncated to 10 bytes)
h = hmac.HMAC(key, hashes.SHA256())
h.update(ct)
expected_sig = h.finalize()[:10]
if expected_sig != sig:
raise ValueError(
"SIGNATURE_NOT_MATCH β file mungkin korup, "
"key salah, atau file dari RS lain"
)
# Decrypt AES-256-CBC
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor()
plain_padded = decryptor.update(ct) + decryptor.finalize()
# Strip PKCS7 padding
pad_len = plain_padded[-1]
plain = plain_padded[:-pad_len]
# Parse TSV
return pd.read_csv(io.StringIO(plain.decode('utf-8')), sep='\t')
# Contoh penggunaan
if __name__ == '__main__':
df = decrypt_eklaim_txt(
path='3471063_2025-11_RANAP_encrypted.TXT',
key_hex='0123456789abcdef' * 4 # 64 hex chars = 32 byte AES-256
)
print(f"Total record: {len(df)}, kolom: {len(df.columns)}")
print(df[['MRN', 'INACBG', 'TARIF_INACBG', 'LOS']].head())
Untuk file plain (non-encrypted), parsing langsung:
df = pd.read_csv('plain.TXT', sep='\t', dtype={'KODE_RS': str, 'MRN': str, 'SEP': str})
Tips production: Gunakan
dtype={'KODE_RS': str, 'MRN': str, 'SEP': str, 'NOKARTU': str}untuk mencegah pandas auto-cast ke int (yang akan strip leading zero β fatal untuk MRN seperti000000001).
Section 7: Common Parsing Pitfalls
Berdasarkan parsing 500+ ribu record dari 50+ RS, berikut 8 jebakan paling sering yang menjebak engineer/data analyst yang baru pertama kali memproses TXT INA-CBG:
- Format tanggal DD/MM/YYYY (bukan ISO 8601). Pandas default akan misparse
01/12/2025sebagai 12 Januari 2025 (US format). Wajib eksplisit:
python
df['ADMISSION_DATE'] = pd.to_datetime(df['ADMISSION_DATE'], format='%d/%m/%Y')
df['DISCHARGE_DATE'] = pd.to_datetime(df['DISCHARGE_DATE'], format='%d/%m/%Y')
- Separator DIAGLIST/PROCLIST =
;(semicolon), bukan koma. Diagnosis utama selalu elemen pertama:
python
df['DIAG_PRIMARY'] = df['DIAGLIST'].str.split(';').str[0]
df['DIAG_SECONDARY'] = df['DIAGLIST'].str.split(';').str[1:]
- Severity adalah huruf 'O' uppercase, bukan angka 0. Saat parsing INACBG, jangan lakukan
int(severity):
python
df['SEVERITY'] = df['INACBG'].str.split('-').str[-1]
# Hasil: ['O', 'I', 'II', 'III'] -- string, bukan int
- Field C1βC4 adalah JSON-string dengan single quote. Python
json.loads()hanya menerima double quote. Wajib replace:
python
import json
df['C1_PARSED'] = df['C1'].apply(
lambda x: json.loads(x.replace("'", '"')) if pd.notna(x) and x != 'None' else {}
)
- Literal string
'None'untuk field kosong, bukan PythonNoneatauNaN. Berlaku untuk SUBACUTE, CHRONIC, SP, SR, SI, SD, dan deskripsi/tarif terkait:
python
import numpy as np
df = df.replace('None', np.nan)
- TARIF_RS = 0 adalah common case, bukan error. Sering muncul ketika coder belum input real cost RS. Filter saat menghitung variance:
python
variance = df[df['TARIF_RS'] > 0].assign(
margin=lambda d: d['TOTAL_TARIF'] - d['TARIF_RS']
)
- Multi-RS files: ketika file TXT digabung dari beberapa cabang/yayasan, jangan asumsikan filename mencerminkan RS unik. Selalu group by KODE_RS dan scan rekursif:
python
for kode_rs, group in df.groupby('KODE_RS'):
process(kode_rs, group)
- iDRG kolom (79β93) hanya muncul di build 5.8+. File legacy hanya punya 78 kolom. Jangan hard-code positional access:
python
has_idrg = 'IDRG_DRG_CODE' in df.columns
if has_idrg:
compare_inacbg_vs_idrg(df)
Section 8: 78 Pola Insight yang Bisa Diekstrak (BPJScan Filter Mapping)
BPJScan menjalankan minimal 78 pola insight terstandar pada setiap file TXT yang di-upload. Berikut 15 pola paling representatif yang menggambarkan jenis temuan paling sering ditemukan tim casemix:
1. Severity 3 audit (overcoding flag)
Identifikasi klaim dengan severity III (sangat berat) yang tidak konsisten dengan profil klinis. Audit BPJS pasca-klaim sering targetkan severity III karena tarifnya tertinggi.
df['SEVERITY'] = df['INACBG'].str.split('-').str[-1]
suspect = df[(df['SEVERITY'] == 'III') & (df['LOS'] < 5)]
2. Episode mismatch / fragmentasi
Pasien yang sama (MRN sama) muncul di 2+ baris dalam rentang β€ 7 hari. Bisa indikasi readmission yang harusnya digabung jadi 1 episode.
df_sorted = df.sort_values(['MRN', 'ADMISSION_DATE'])
df_sorted['DAYS_SINCE_LAST_DISCHARGE'] = df_sorted.groupby('MRN')['DISCHARGE_DATE'].shift().pipe(
lambda s: (df_sorted['ADMISSION_DATE'] - s).dt.days
)
fragmentation = df_sorted[df_sorted['DAYS_SINCE_LAST_DISCHARGE'] <= 7]
3. High LOS Low Severity
LOS > 7 hari tapi severity O atau I. Indikasi koding under-severity atau medical necessity issue.
4. Low LOS High Severity
LOS < 4 hari tapi severity III. Indikasi overcoding atau diagnosis sekunder berlebih.
5. Top-up missed
Kombinasi diagnosis + prosedur yang seharusnya trigger Special CMG top-up (Streptokinase, Deferiprone, Hip Implant, PCI, Brakiterapi, Pancreatectomy, dan 30+ kriteria lain) tetapi field SP/SR/SI/SD kosong. Ini revenue leakage paling besar β single hospital tipe B umumnya kehilangan ratusan juta sampai miliaran rupiah per tahun karena pola ini.
# Pseudocode: untuk setiap topup criterion
for criterion in topup_criteria:
inacbg_match = df['INACBG'].str.startswith(criterion['inacbg_prefix'])
diag_match = df['DIAGLIST'].str.contains('|'.join(criterion['diagnosis_codes']), na=False)
proc_match = df['PROCLIST'].str.contains('|'.join(criterion['procedure_codes']), na=False)
no_topup = df[['SP', 'SR', 'SI', 'SD']].isna().all(axis=1)
missed = df[inacbg_match & (diag_match | proc_match) & no_topup]
Daftar 36 kriteria top-up resmi mencakup: Streptokinase, Deferiprone, Deferoksamin, Deferasirox, Human Albumin (Septicaemia & Burn), Anti Hemofilia Factor, Subdural Grid Electrode, Contegra, TMJ Prothesis, Hip/Knee Implant, Prostesis Evar/Tevar, PCI, Keratoplasty, Pancreatectomy, Repair of Septal Defect with Prosthesis, Stereotactic Surgery & Radiotherapy, Torakotomi, Lobektomi/Bilobektomi/Pneumonektomi, Vitrectomy, Coil, Trombektomi, Percutaneous Endoscopy Gastrostomy, Nuclear Medicine, MRI, Diagnostic Imaging Eye, Phacoemulsification, Microlaringoscopy, Cholangiograph, Odontektomi, dan Brakiterapi.
6. DPJP coding pattern
Distribusi INACBG per DPJP. Dokter dengan severity III rate jauh di atas rata-rata RS = audit risk; di bawah rata-rata = under-coding training need.
dpjp_pattern = df.groupby(['DPJP', 'SEVERITY']).size().unstack(fill_value=0)
dpjp_pattern['SEV3_RATIO'] = dpjp_pattern.get('III', 0) / dpjp_pattern.sum(axis=1)
7. Cost variance per CBG
Identifikasi CBG yang konsisten loss-leader (TARIF_RS > TOTAL_TARIF). Bahan negosiasi internal untuk efisiensi protokol klinis atau bahan policy ke manajemen.
8. Special CMG underutilization
CBG yang eligible Special CMG (per Lampiran I Permenkes) tetapi field SP/SR/SI/SD kosong di seluruh klaim CBG tersebut selama bulan klaim. Tanda Special CMG tidak terimplementasi di RS.
9. Component cost outlier
Komponen 18 tarif riil (kolom 61β78). Outlier pada komponen tertentu (misal OBAT > 70% TARIF_RS untuk CBG medical sederhana) = audit lead untuk farmasi atau leak procurement.
10. Discharge status anomaly
Kombinasi DISCHARGE_STATUS = 4 (Meninggal) dengan severity O (ringan). Hampir pasti error koding atau salah klasifikasi.
11. Neonatal age mismatch
UMUR_TAHUN β 0 atau UMUR_HARI > 30 tetapi INACBG masuk CMG P (Newborn) atau CaseType 8/9. Salah grouping neonatal.
12. ICU without VENT
ICU_INDIKATOR = 1 dan ICU_LOS > 0 tetapi VENT_HOUR = 0. Bisa valid (ICU non-ventilator) atau bisa coding error β review per kasus.
13. Respiratory failure flag
Diagnosis J96 (Respiratory failure) di DIAGLIST tetapi tidak ada VENT_HOUR atau ICU. Major audit red flag.
14. iDRG vs INACBG cost weight diff
Bandingkan TARIF_INACBG (kolom 28) dengan IDRG_TOTAL_TARIF (kolom 91) hipotetik. Diff besar = preview revenue impact saat migrasi resmi ke iDRG.
15. Coder consistency
CODER_ID + INACBG distribution. Coder dengan CBG profile yang anomali dibanding peer (misal severity III rate 3Γ lipat) = training opportunity, atau audit lead.
Sisanya 63 pola insight lain mencakup: episode RAJALβRANAP yang seharusnya merge, top-up sub-akut/kronis missed, Special CMG yang ter-trigger tapi salah CBG, DPJP-CMG specialty mismatch, BMHP-procedure consistency, length-of-care vs CBG payment match, regional tariff cross-check, payor consistency, dan analisis per komponen biaya riil.
Section 9: Use Cases Praktis β Untuk Siapa Panduan Ini?
| Persona | Use Case Utama | Manfaat |
|---|---|---|
| Koder / PMIK | Validasi koding sebelum submit ke verifikator internal | Menghindari koding ulang, mengurangi reject pasca-submission |
| Verifikator Internal RS | Simulasi grouper, pre-submit check, sampling audit | Memastikan klaim final sebelum dikirim ke BPJS |
| Kepala Casemix | Monitoring konsistensi koder, identifikasi training needs | Standardisasi koding antar coder, governance casemix |
| Wadir Keuangan / Finance | Cost variance analysis, revenue leakage tracking | Mengidentifikasi top-up missed dan loss-leader CBG |
| Tim Compliance / Audit Internal | Defensive audit sebelum BPJS audit pasca-klaim | Mengurangi risiko temuan dispute klaim oleh BPJS |
| Direktur RS | Dashboard ringkas: variance, severity mix, DPJP pattern | Decision support untuk policy klinis dan keuangan |
Section 10: Otomasi 78 Pola dengan BPJScan
Membaca file TXT INA-CBG secara manual di Excel bisa dilakukan untuk file kecil (< 1.000 record). Untuk RS dengan volume klaim > 5.000 record per bulan, parsing manual praktis tidak feasible β terutama untuk pola insight kompleks seperti episode mismatch, top-up missed (36 kriteria), atau DPJP coding pattern yang memerlukan agregasi multi-tabel.
BPJScan adalah aplikasi MedMinutes yang otomasi seluruh 78 pola insight di atas dari file TXT INA-CBG yang di-upload, dengan dashboard yang dirancang khusus untuk koder, kepala casemix, wadir keuangan, dan direktur RS. Tidak perlu setup database, tidak perlu install grouper β cukup upload file TXT (plain atau encrypted), tunggu 24 jam, hasil insight tampil dalam bentuk dashboard interaktif beserta export Excel siap presentasi.
Berdasarkan analisis 500+ ribu record dari 50+ rumah sakit di 8+ provinsi, BPJScan rata-rata mengidentifikasi Rp3 miliar+ klaim under-claim atau top-up missed per tahun per RS tipe B/C β angka yang signifikan untuk negosiasi internal efisiensi farmasi, training koder, atau policy casemix.
Pelajari lebih lanjut: BPJScan β Audit Klaim BPJS Otomatis.
FAQ
1. Apa itu file TXT INA-CBG?
File TXT INA-CBG adalah file laporan klaim individual yang diekspor dari aplikasi E-Klaim INA-CBG milik Pusdatin Kementerian Kesehatan. File ini berisi data koding (ICD-10, ICD-9-CM), grouping CBG, tarif paket, dan komponen biaya riil RS untuk setiap pasien yang diklaim ke BPJS Kesehatan. Format: TSV (tab-separated values), encoding UTF-8, 78 atau 93 kolom tergantung versi build aplikasi E-Klaim.
2. Berapa kolom dalam file TXT INA-CBG?
File TXT INA-CBG dari E-Klaim build 5.8+ memiliki 93 kolom canonical, terdiri dari 78 kolom data klaim utama (sesuai Permenkes 26/2021) dan 15 kolom transisi iDRG. File dari E-Klaim build < 5.8 hanya memiliki 78 kolom. Selalu deteksi len(df.columns) untuk fallback parsing.
3. Algoritma enkripsi apa yang dipakai E-Klaim?
E-Klaim menggunakan AES-256-CBC untuk encryption ciphertext, dengan HMAC-SHA256 (di-truncate ke 10 byte pertama) sebagai integrity signature. File terenkripsi dibungkus dalam envelope ----BEGIN ENCRYPTED DATA---- berisi base64 dari signature(10) || iv(16) || ciphertext. Bukan algoritma proprietary β ini scheme cryptographic standar yang dapat diimplementasi dengan library cryptography di Python atau encrypt di Dart/Flutter.
4. Apa beda file TXT plain dan encrypted?
File TXT plain adalah TSV langsung yang dapat dibuka di Excel atau parser apapun, ditujukan untuk arsip dan analisis internal RS. File TXT encrypted dibungkus dalam envelope ----BEGIN ENCRYPTED DATA----, ditujukan untuk submission resmi ke BPJS Kesehatan via Defrada/SEP. Konten klaim identik β beda hanya pada layer keamanan transmisi.
5. Bagaimana mendapatkan KONSIL_RS_KEY untuk decrypt?
KONSIL_RS_KEY adalah credential level RS yang di-issue oleh Pusdatin saat instalasi aplikasi E-Klaim per RS. Key disimpan di file konfigurasi installer di server E-Klaim RS. Untuk audit internal, hubungi tim IT RS yang menginstall E-Klaim. Key tidak boleh di-share keluar tim teknis RS, tidak boleh di-commit ke Git, dan jika hilang/bocor harus di-reissue oleh Pusdatin.
6. Apa saja insight yang bisa diekstrak dari file TXT INA-CBG?
Minimal 78 pola insight dapat diekstrak, antara lain: severity outlier (III audit), episode mismatch / fragmentasi readmission, high LOS low severity, low LOS high severity, top-up missed (36 kriteria Special CMG), DPJP coding pattern, cost variance per CBG, Special CMG underutilization, component cost outlier, discharge status anomaly, neonatal age mismatch, ICU without ventilator, respiratory failure flag, iDRG vs INACBG cost weight diff, dan coder consistency. Tools seperti BPJScan mengotomasi seluruh 78 pola.
7. Format tanggal di file TXT INA-CBG?
Format tanggal kanonik di file TXT INA-CBG adalah DD/MM/YYYY (bukan ISO 8601). Berlaku untuk kolom ADMISSION_DATE (kolom 6), DISCHARGE_DATE (kolom 7), dan BIRTH_DATE (kolom 8). Saat parsing dengan pandas, wajib pakai pd.to_datetime(..., format='%d/%m/%Y') untuk menghindari misparse ke US format (MM/DD/YYYY).
8. Apakah file TXT bisa dibaca dengan Excel?
File TXT plain bisa dibaca dengan Excel via Data β From Text/CSV β pilih separator tab. Untuk file < 1.000 record, Excel cukup. Namun untuk volume produksi RS (5.000+ record per bulan), Excel praktis tidak feasible karena: (a) parsing JSON di kolom C1βC4 tidak native, (b) cross-tabulation untuk 78 pola insight memerlukan pivot kompleks, (c) Excel membatasi ke 1.048.576 baris. Untuk volume produksi, gunakan parser Python (pandas) atau tools dedicated seperti BPJScan.
Dipercaya 50+ rumah sakit di 8+ provinsi











