API Layanan Integrasi Faskes & Rujukan
Layanan ini dibangun menggunakan CodeIgniter 3 dan RestController untuk memfasilitasi autentikasi pengguna fasilitas kesehatan, pertukaran data master faskes (FKTP/FKRTL), serta pencatatan rujukan medis maternal/neonatal (PONEK).
Seluruh request body dan response menggunakan format application/json dengan encoding UTF-8.
Waktu transaksi dicatat menggunakan zona waktu Asia/Jakarta (WIB / UTC+7) dengan format Y-m-d H:i:s.
Struktur Standar JSON Response
Setiap endpoint mengembalikan objek metadata (berisi kode HTTP dan pesan status) serta objek response (berisi payload data apabila tersedia).
{
"metadata": {
"code": 200,
"message": "Ok"
},
"response": { ... }
}
Skema Autentikasi JWT (Bearer Token)
Sebagian besar endpoint dilindungi oleh fungsi helper validate_custom_token() yang memverifikasi tanda tangan JSON Web Token (HS256) sekaligus memastikan sesi pada tabel auth_sessions masih aktif (belum di-revoke dan belum kedaluwarsa).
| Header | Format Nilai | Keterangan |
|---|---|---|
Authorization |
Bearer <access_token> |
Direkomendasikan. Gunakan access_token yang diperoleh dari endpoint POST /auth/login.Masa berlaku token adalah 600 detik (10 menit). |
x-token |
<access_token> |
Header alternatif untuk kompatibilitas aplikasi klien versi lama. |
Content-Type |
application/json |
Wajib disertakan pada setiap request dengan method POST yang mengirimkan JSON body. |
Kode Status HTTP
| Kode | Status | Penjelasan |
|---|---|---|
200 |
OK | Permintaan berhasil diproses. |
201 |
Created | Data transaksi baru (seperti rujukan) berhasil disimpan ke database. |
400 |
Bad Request | Format JSON tidak valid atau parameter wajib (seperti username/password/refresh_token) kosong. |
401 |
Unauthorized | Kredensial salah, token JWT tidak valid/kedaluwarsa, atau sesi telah berakhir (logout). |
403 |
Forbidden | Token valid, tetapi akun tidak memiliki hak akses (misal: faskes asal bukan kategori FKTP atau kunjungan bukan milik faskes pengirim). |
422 |
Unprocessable Entity | Validasi aturan bisnis atau tipe data kolom gagal (detail kesalahan dikembalikan pada response.errors). |
500 / 503 |
Server Error | Kegagalan transaksi database atau konfigurasi kepemilikan kolom belum lengkap. |
Login Pengguna
Memvalidasi kredensial pengguna pada tabel m_user (status id_active = 1), mencatat sesi baru pada auth_sessions (berlaku 7 hari), dan menerbitkan pasangan access_token serta refresh_token.
Request Body (JSON)
{
"username": "{isi username pengguna faskes}",
"password": "{isi password pengguna faskes}"
}
Contoh Respons Sukses (200 OK)
{
"metadata": {
"code": 200,
"message": "Login berhasil."
},
"response": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 600,
"refresh_token": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"user": {
"id_user": "2",
"nama": "RIZKI AMALIA",
"username": "kiki",
"faskes": "Puskesmas Kecamatan A",
"role": "Bidan",
"status": "aktif"
}
}
}
Perbarui Token (Refresh Token)
Memperbarui access_token yang telah kedaluwarsa menggunakan refresh_token. Setiap kali berhasil dipakai, refresh_token lama otomatis dirotasi (tidak bisa digunakan dua kali).
Request Body (JSON)
{
"refresh_token": "{isi refresh token pengguna}"
}
Contoh Respons Sukses (200 OK)
{
"metadata": {
"code": 200,
"message": "Token diperbarui."
},
"response": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 600,
"refresh_token": "{isi refresh token pengguna}",
"user": {
"id_user": "2",
"nama": "RIZKI AMALIA",
"username": "{isi username pengguna}",
"faskes": "Puskesmas Kecamatan A",
"role": "Bidan",
"status": "aktif"
}
}
}
Profil Pengguna Aktif (Me)
Mengambil informasi profil pengguna yang sedang login berdasarkan klaim token JWT dan status sesi aktif di database.
Contoh Respons Sukses (200 OK)
{
"metadata": {
"code": 200,
"message": "Ok"
},
"response": {
"user": {
"id_user": "2",
"nama": "RIZKI AMALIA",
"username": "{isi username pengguna}",
"faskes": "Puskesmas Kecamatan A",
"role": "Bidan",
"status": "aktif"
}
}
}
Logout Sesi
Mengakhiri sesi aktif pengguna dengan mengisi kolom revoked_at pada tabel auth_sessions. Token yang terhubung dengan sesi ini tidak dapat digunakan lagi.
Contoh Respons Sukses (200 OK)
{
"metadata": {
"code": 200,
"message": "Logout berhasil."
}
}
Daftar Master Faskes
Mengambil seluruh daftar fasilitas kesehatan dari tabel m_faskes (baik kategori FKTP maupun rumah sakit rujukan FKRTL).
Contoh Respons Sukses (200 OK)
{
"response": [
{
"id_faskes": "1",
"nama_faskes": "Puskesmas Kecamatan A",
"kategori": "FKTP"
},
{
"id_faskes": "2",
"nama_faskes": "RSUD Kabupaten B",
"kategori": "FKRTL"
}
],
"metadata": {
"message": "Ok",
"code": 200
}
}
Simpan Rujukan Baru
Mencatat transaksi rujukan rekam medis baru ke tabel t_rm beserta daftar kode pilihan (checkbox) ke tabel t_rm_pilihan dalam satu transaksi database atomik.
- Akun pengirim harus berasal dari faskes dengan kategori
FKTP. id_kunjunganharus terdaftar dit_kunjungandan dimiliki oleh faskes pengirim (kolomid_faskes).id_faskes_tujuanharus terdaftar dim_faskesdengan kategoriFKRTLdan berbeda dari faskes asal.- Jika
perdarahan_statusbernilai"tidak_ada", maka kolomperdarahan_volumedanperdarahan_karakteristiktidak boleh diisi. - Jika array
pilihanmemuat kode"riwayat_tidak_ada", maka tidak boleh digabung dengan koderiwayat_*lainnya. - Jika memilih kode checkbox dengan awalan
bahaya_*,riwayat_*, atauterapi_*, maka flag penilaian terkait (skrining_bahaya_sudah_dinilai,riwayat_medis_sudah_dinilai, atauterapi_sudah_dinilai) wajib bernilai1.
Contoh Request Body Lengkap (JSON)
{
"id_kunjungan": 1,
"id_faskes_tujuan": 2,
"id_diagnosis": 1,
"skrining_bahaya_sudah_dinilai": 1,
"perdarahan_status": "tidak_ada",
"tfu_cm": 32.5,
"kepala_masuk_panggul": 1,
"djj_per_menit": 142,
"djj_irama": "teratur",
"his_frekuensi": "3",
"his_durasi": "20_40",
"vt_pembukaan": "4_7",
"ketuban": "utuh",
"penurunan_kepala": "hodge_1_2",
"riwayat_medis_sudah_dinilai": 1,
"riwayat_sc": "tidak",
"operasi_ginekologi": 0,
"td_sistolik_mmhg": 120,
"td_diastolik_mmhg": 80,
"nadi_per_menit": 84,
"rr_per_menit": 20,
"suhu_celsius": 36.7,
"spo2_persen": 98.0,
"kateter_urin_terpasang": 0,
"berat_badan_kg": 62.5,
"proteinuria": "negatif",
"hematuria": 0,
"oksigenasi": "tidak_diberikan",
"akses_iv": "single_line_18_20",
"jenis_cairan": "rl",
"cairan_total_ml": 500.0,
"tetesan_mode": "maintenance",
"tetesan_per_menit": 20,
"terapi_sudah_dinilai": 1,
"pilihan": [
"riwayat_tidak_ada"
]
}
Contoh Respons Sukses (201 Created)
{
"metadata": {
"code": 201,
"message": "Rujukan berhasil disimpan."
},
"response": {
"id_rm": 15
}
}
Contoh Respons Validasi Gagal (422 Unprocessable Entity)
{
"metadata": {
"code": 422,
"message": "Validasi gagal."
},
"response": {
"errors": {
"id_faskes_tujuan": "Wajib diisi.",
"perdarahan_status": "Pilihan tidak valid."
}
}
}
Referensi Skema Kolom Input Rujukan (51 Parameter)
Hanya kolom yang terdaftar pada application/config/rujukan_fields.json (ditambah array pilihan) yang diterima oleh server. Mengirimkan nama properti di luar daftar ini akan ditolak dengan kode 422.
| Nama Properti JSON | Status | Tipe Data | Aturan & Batasan Nilai |
|---|---|---|---|
id_kunjungan |
Wajib | integer (int) | ID referensi valid (minimal >= 1) |
id_faskes_tujuan |
Wajib | integer (int) | ID referensi valid (minimal >= 1) |
waktu_rujukan |
Opsional | string (datetime) | Format "Y-m-d H:i:s" (otomatis terisi waktu server Asia/Jakarta jika kosong) |
id_diagnosis |
Opsional | integer (int) | ID referensi valid (minimal >= 1) |
skrining_bahaya_sudah_dinilai |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
perdarahan_status |
Opsional | enum (string) | Pilihan nilai: "tidak_ada", "flek", "aktif" |
perdarahan_volume |
Opsional | enum (string) | Pilihan nilai: "lt_500", "500_1000", "gt_1000" |
perdarahan_karakteristik |
Opsional | enum (string) | Pilihan nilai: "darah_segar", "stelsel", "sisa_jaringan" |
tfu_cm |
Opsional | number / float (decimal(5,2)) | Maksimal 2 angka desimal, Nilai >= 0 (kurang dari 10^3) |
kepala_masuk_panggul |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
djj_per_menit |
Opsional | integer (smallint) | Rentang bilangan bulat: 0 s/d 65535 |
djj_irama |
Opsional | enum (string) | Pilihan nilai: "teratur", "ireguler", "unheard" |
his_frekuensi |
Opsional | enum (string) | Pilihan nilai: "tidak_ada", "lt_2", "3", "4", "5" |
his_durasi |
Opsional | enum (string) | Pilihan nilai: "relaksasi", "lt_20", "20_40", "gt_40" |
vt_pembukaan |
Opsional | enum (string) | Pilihan nilai: "belum", "1_3", "4_7", "8_9", "lengkap" |
ketuban |
Opsional | enum (string) | Pilihan nilai: "utuh", "pecah_jernih", "pecah_keruh_meconium", "pecah_berbau" |
penurunan_kepala |
Opsional | enum (string) | Pilihan nilai: "floating", "hodge_1_2", "hodge_3_4" |
bishop_dilatasi_cm |
Opsional | number / float (decimal(4,1)) | Maksimal 1 angka desimal, Nilai >= 0 (kurang dari 10^3) |
bishop_penipisan_persen |
Opsional | integer (tinyint) | Rentang bilangan bulat: 0 s/d 100 (%) |
bishop_station |
Opsional | integer (tinyint) | Rentang bilangan bulat: -128 s/d 127 |
bishop_konsistensi |
Opsional | string (varchar(30)) | Teks maksimal 30 karakter |
bishop_posisi |
Opsional | string (varchar(30)) | Teks maksimal 30 karakter |
riwayat_medis_sudah_dinilai |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
alergi_obat_detail |
Opsional | string (text) | Teks bebas maksimal 65.535 karakter |
riwayat_sc |
Opsional | enum (string) | Pilihan nilai: "tidak", "1_kali", "ge_2_kali" |
jarak_sc_tahun |
Opsional | number / float (decimal(4,1)) | Maksimal 1 angka desimal, Nilai >= 0 (kurang dari 10^3) |
operasi_ginekologi |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
operasi_ginekologi_detail |
Opsional | string (text) | Teks bebas maksimal 65.535 karakter |
td_sistolik_mmhg |
Opsional | integer (smallint) | Rentang bilangan bulat: 0 s/d 65535 |
td_diastolik_mmhg |
Opsional | integer (smallint) | Rentang bilangan bulat: 0 s/d 65535 |
nadi_per_menit |
Opsional | integer (smallint) | Rentang bilangan bulat: 0 s/d 65535 |
rr_per_menit |
Opsional | integer (smallint) | Rentang bilangan bulat: 0 s/d 65535 |
suhu_celsius |
Opsional | number / float (decimal(4,1)) | Maksimal 1 angka desimal, Nilai >= 0 (kurang dari 10^3) |
spo2_persen |
Opsional | number / float (decimal(5,2)) | Maksimal 2 angka desimal, Rentang 0 s/d 100 |
kateter_urin_terpasang |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
berat_badan_kg |
Opsional | number / float (decimal(6,2)) | Maksimal 2 angka desimal, Harus > 0 |
produksi_urin_total_ml |
Opsional | number / float (decimal(10,2)) | Maksimal 2 angka desimal, Nilai >= 0 (kurang dari 10^8) |
durasi_pengamatan_urin_jam |
Opsional | number / float (decimal(6,2)) | Maksimal 2 angka desimal, Harus > 0 |
urin_output_tercatat_ml_jam |
Opsional | number / float (decimal(10,2)) | Maksimal 2 angka desimal, Nilai >= 0 (kurang dari 10^8) |
proteinuria |
Opsional | enum (string) | Pilihan nilai: "negatif", "trace", "plus_1", "plus_2", "plus_3", "plus_4" |
hematuria |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
oksigenasi |
Opsional | enum (string) | Pilihan nilai: "tidak_diberikan", "nasal_kanul", "nrm", "bvm" |
oksigen_aliran_lpm |
Opsional | number / float (decimal(5,2)) | Maksimal 2 angka desimal, Nilai >= 0 (kurang dari 10^3) |
oksigen_konsentrasi_persen |
Opsional | number / float (decimal(5,2)) | Maksimal 2 angka desimal, Rentang 0 s/d 100 |
akses_iv |
Opsional | enum (string) | Pilihan nilai: "single_line_18_20", "double_line_16_18" |
jenis_cairan |
Opsional | enum (string) | Pilihan nilai: "rl", "nacl_0_9", "d5", "rd5" |
cairan_total_ml |
Opsional | number / float (decimal(10,2)) | Maksimal 2 angka desimal, Nilai >= 0 (kurang dari 10^8) |
tetesan_mode |
Opsional | enum (string) | Pilihan nilai: "maintenance", "guyur", "fast_drip" |
tetesan_per_menit |
Opsional | integer (smallint) | Rentang bilangan bulat: 0 s/d 65535 |
terapi_sudah_dinilai |
Opsional | integer (tinyint) | Flag boolean integer: 0 atau 1 |
pilihan |
Opsional | array of string | Daftar kode checkbox unik (maks 60 karakter per kode) yang terdaftar pada tabel m_rm_pilihan. |
Simpan Data Klinik (Legacy Endpoint)
Endpoint kompatibilitas pada controller Api.php yang memvalidasi kecocokan x-username dengan klaim pengguna pada JWT token.
| Header | Contoh Nilai | Keterangan |
|---|---|---|
x-username |
admin_fktp |
Harus sama dengan klaim username di dalam token JWT. |
x-token / Authorization |
Bearer <access_token> |
Token JWT aktif hasil login. |