Files
cpone_midleware/README.md

6.5 KiB

CPONE Middleware Go

Service Go untuk endpoint:

GET /api/cpone/paket
GET /api/cpone/paket/{id}
Authorization: Bearer <your-secure-token>

GET /api/cpone/tarif-kerjasama?search=&perusahaan_id=&tarif_id=&page=1&per_page=15
Authorization: Bearer <your-secure-token>

GET /api/cpone/tarif-kerjasama/{id}?group_tarif_id=&active=N&effective_date=2026-08-22
Authorization: Bearer <your-secure-token>

GET /api/cpone/layanan-mapping-harga?periodeTarifID=10&layananID=6413,6414,1309
Authorization: Bearer <your-secure-token>

POST /api/cpone/patients/lab-registration
Authorization: Bearer <your-secure-token>
Content-Type: application/json

POST /api/cpone/patients/lab-registration/{regId}/services
Authorization: Bearer <your-secure-token>
Content-Type: application/json

POST /api/cpone/patients/lab-registration/{regId}/packages
Authorization: Bearer <your-secure-token>
Content-Type: application/json

POST /api/cpone/patients/medrec
Authorization: Bearer <your-secure-token>
Content-Type: application/json

Format payload dan response dibuat mengikuti controller PHP CPONE terkait.

Contoh payload pembuatan pasien HIS:

{
  "rs": "PRIMAYA",
  "nama": "BUDI SANTOS",
  "jenis_kelamin": "L",
  "tgl_lahir": "1990-01-15",
  "jenis_nomer_sosial": "KTP",
  "nomer_sosial": "3174011501900001",
  "telepon": "081234567890",
  "ponsel": "081234567890",
  "email": "budi@example.com",
  "tempat_lahir": "JAKARTA",
  "alamat": "JL. CONTOH NO. 1",
  "propinsi": "DKI JAKARTA",
  "kabupaten": "JAKARTA",
  "kecamatan": "KECAMATAN CONTOH",
  "kelurahan": "KELURAHAN CONTOH",
  "kode_pos": "12345",
  "perusahaan_id": "PE260700001",
  "nik_karyawan": "TSB2026002",
  "dependant_id": "D001",
  "nama_karyawan": "BUDI SANTOS",
  "channel": "CPONE"
}

Endpoint mengembalikan created, already_exists, atau possible_duplicate sesuai hasil pemeriksaan identitas dan kemiripan data pasien di HIS.

Contoh payload registrasi laboratorium:

{
  "medrec_id": "00001234",
  "tanggal": "2026-08-18",
  "departemen_id": "LAB",
  "dokter_id": "DR01",
  "dokter_pengirim_id": "DR02",
  "perujuk": null,
  "jenis_pasien_id": "0",
  "periode_tarif_id": 10,
  "kelas_id": "Default",
  "shift_harian_id": null,
  "diagnosa_kerja": "Pemeriksaan laboratorium",
  "catatan": null,
  "channel": "CPONE"
}

dokter_pengirim_id atau perujuk wajib diisi. Endpoint ini membuat registrasi laboratorium tanpa layanan, sama seperti PatientController::registerLab; layanan ditambahkan melalui endpoint terpisah.

Contoh payload penambahan layanan:

{
  "layanan": [
    {
      "layanan_id": "6413",
      "jumlah": 1,
      "cito": false,
      "markup_cito": 0,
      "catatan": null
    }
  ],
  "channel": "CPONE"
}

Harga, diskon publik, share, unit cost, layanan multiple, dan spesimen diambil langsung dari master HIS. Layanan yang sudah ada akan dilewati dan dilaporkan melalui skipped_layanan_ids.

Contoh payload penambahan Paket Dispenser HIS:

{
  "paket_id": "DISP-260800011",
  "cito": false,
  "markup_cito": 0,
  "catatan": "",
  "channel": "CPONE"
}

Paket harus aktif, disetujui, berlaku untuk rawat jalan, dan belum memiliki layanan yang sama pada registrasi. Request ulang untuk paket yang sudah masuk bersifat idempoten dan tidak membuat transaksi ganda.

Config

Copy .env.example menjadi .env, lalu isi koneksi MySQL:

APP_HOST=0.0.0.0
APP_PORT=8080
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=primaya
DB_USERNAME=root
DB_PASSWORD=
DB_DEFAULT_RS_CODE=AWALBROS_DEV
DB_DEFAULT_RS_NAME=RS Dev Awalbros

CPONE_DB_HOST=127.0.0.1
CPONE_DB_PORT=3306
CPONE_DB_DATABASE=cpone_middleware
CPONE_DB_USERNAME=root
CPONE_DB_PASSWORD=
CPONE_BEARER_TOKEN=replace-with-a-secure-token
CPONE_DATABASE_SETTINGS_TOKEN=replace-with-a-different-admin-token
CPONE_DATABASE_CREDENTIAL_KEY=replace-with-a-long-random-encryption-key

DB_* tetap menjadi koneksi default (saat ini database dev Awalbros). Request lama yang tidak mengirim kode RS akan tetap menggunakan koneksi ini.

Multi-database per kode RS

Tambahkan atau perbarui koneksi RS melalui API berikut. Koneksi akan dites sebelum disimpan; bila Ping gagal, setting tidak disimpan.

POST /api/cpone/database-settings
Authorization: Bearer <your-database-settings-token>
Content-Type: application/json

{
  "kode_rs": "PRIMAYA_BEKASI_BARAT",
  "nama": "Primaya Hospital Bekasi Barat",
  "host": "10.10.10.20",
  "port": "3306",
  "database": "his_bekasi_barat",
  "username": "cpone",
  "password": "secret"
}

Endpoint pengelolaan yang tersedia:

POST /api/cpone/database-settings
GET  /api/cpone/database-settings
GET  /api/cpone/database-settings/{kodeRs}

Saat startup, service otomatis membuat database CPONE_DB_DATABASE beserta tabel hospitals dan hospital_databases. Koneksi HIS lama dari DB_* otomatis menjadi RS default. Akun CPONE_DB_USERNAME harus memiliki izin CREATE DATABASE pada bootstrap pertama; alternatifnya jalankan migration database/migrations/001_create_cpone_management.sql secara manual.

Response list/detail tidak pernah menampilkan password, hanya field has_password. Password koneksi RS disimpan terenkripsi AES-GCM menggunakan CPONE_DATABASE_CREDENTIAL_KEY. Jangan mengubah key tersebut setelah data mulai disimpan karena password lama tidak akan bisa didekripsi. Jika key belum diisi, service memakai CPONE_DATABASE_SETTINGS_TOKEN, lalu CPONE_BEARER_TOKEN sebagai fallback; token fallback itu juga tidak boleh diubah tanpa rotasi credential.

Endpoint pengelolaan memakai CPONE_DATABASE_SETTINGS_TOKEN. Jika variabel ini belum diisi, service memakai CPONE_BEARER_TOKEN untuk kompatibilitas; gunakan token admin yang berbeda di production.

Pilih database pada semua endpoint bisnis dengan header:

X-RS-Code: PRIMAYA_BEKASI_BARAT

Sebagai alternatif dapat memakai query ?kode_rs=PRIMAYA_BEKASI_BARAT. Header memiliki prioritas lebih tinggi daripada query. Response juga memuat header X-RS-Code agar koneksi yang terpilih mudah diaudit. Jika keduanya tidak ada, service memakai DB_DEFAULT_RS_CODE.

Run

cd cpone-middleware
go mod tidy
go run ./cmd/server

SQLC

File sqlc.yaml, sqlc/schema.sql, dan sqlc/query.sql sudah disiapkan.

Catatan penting: sqlc tidak bisa menerima nama tabel dinamis seperti harga_layanan_{periodeTarifID}. Implementasi runtime saat ini tetap memakai database/sql untuk menyusun nama tabel setelah periodeTarifID divalidasi angka, sama seperti PHP memakai HargaLayanan::makeTableName(). Kalau semua periode ingin digenerate oleh sqlc, buat query konkret per tabel periode, misalnya harga_layanan_10, harga_layanan_11, dan seterusnya.