Skip to content

[ND-183/LNSW.34/2026] Perbaikan Sequence Flag Single Billing COP Sinkarkes dan Eliminasi Log Status Redundan ​

Modul: Pengangkut | Tipe: Bugfix | Stage Saat Ini: STAGING | Tanggal Dokumen: 2026-08-24


1. Informasi Tugas & Referensi Bisnis ​

  • Task ID / Nomor Referensi: ND-183/LNSW.34/2026
  • Sumber Instruksi: Nota Dinas Resmi ND-183/LNSW.34/2026
  • Dokumen Referensi / Lampiran: ND-183-LNSW.34-2026.pdf, ND-183_fix_billing_flag_sequence_postman_collection.json
  • Modul Terkait: Pengangkut
  • Service / Repository: pengangkut-backend
  • PIC Pengembang: Hermansyah Efendi
  • Latar Belakang & Ringkasan Kebutuhan: Berdasarkan evaluasi dan temuan anomali bisnis pada Nota Dinas ND-183/LNSW.34/2026 (rujukan No. Aju 101019B37E2D6):
    1. Ditemukan celah (bypass) pada alur layanan Sinkarkes dengan metode Single Billing: saat pengiriman pengajuan berstatus gagal, sistem sebelumnya tetap melakukan flagging isSingleBilling pada database. Akibatnya pengguna dapat langsung melanjutkan proses ke tahapan keberangkatan padahal pengajuan kedatangannya secara sistem masih gagal.
    2. Terdapat penambahan status "Proses Permintaan Tagihan" (kode 101) yang tidak diperlukan dalam alur berjalan, serta kesalahan logika pencatatan status "Tagihan Diterima" (kode 103/111) dari respons balikan Sinkarkes yang belum memiliki data billing riil. Secara proses bisnis, status tagihan diterima seharusnya hanya dicatat dari API /tagihan saat data tagihan aktual masuk ke sistem.
    3. Dilakukan evaluasi konsistensi data nomor registrasi kapal pada integrasi Sinkarkes terhadap database superset kapal.

2. Deployment Lifecycle ​

#EnvironmentTanggal & WaktuPICStatusCatatan
1Development2026-08-13 12:06Hermansyah EfendiDEPLOYEDBranch: development
2Staging (UAT)2026-09-09 11:34achmad fauziDEPLOYEDRelease Candidate v1.18.2 via MR !2080. Co-deployed: [TASK-DRAGONFLYDB-MIGRATION, TASK-SPLIT-BILLING-202608, FEAT-MANUAL-BILLING-REQUEST, MAINT-SUPERSET-SUMMARY-SHIP-SYNC-SECURITY, REFACTOR-DEPRECATE-POST-STATUS-SERVICE-MIGRATION, TASK-PINO-LOGGER-REFACTOR, ND-304-LNSW.34-2026, ND-256-LNSW.34-2026, ND-183-LNSW.34-2026]
3Production——PENDING—

Riwayat Update Log ​

TanggalEnvironmentPerubahanPIC
2026-09-09StagingPromosi ke STAGING via MR !2080 (Release Candidate v1.18.2)Hermansyah Efendi
2026-08-24DevelopmentInisialisasi draft audit log dari context block backend (commit 349ec61b)Hermansyah Efendi

3. Analisis Teknis & Rincian Perubahan ​

  • Alur Logika & Bisnis:

    • Penutupan Celah Bypass Flag Billing: Urutan eksekusi pemanggilan updateFlagBillingWarta(idLayanan, isSingleBilling, 'karkes') dipindahkan ke dalam blok try setelah fungsi eksternal sendLayanan berhasil terkirim tanpa error. Apabila pengiriman gagal atau melempar exception, status flag di database tidak diperbarui, sehingga user dicegah melompati tahapan dari kedatangan ke keberangkatan.
    • Eliminasi Log Status Prematur & Redundan: Menghapus pencatatan status asynchronous (postStatusAsync) untuk kode status 101 (proses permintaan tagihan), 103 (tagihan diterima), dan 111 (penerbitan tagihan) pada RequestBillingService. Pencatatan status tagihan kini murni terisolasi dan hanya dipicu oleh webhook/endpoint API /tagihan saat payload tagihan riil diterima sistem.
    • Code Clean-up: Menghapus variabel logging mati (postStatusTagihan, postStatusPenerbitanTagihan, postStatusFailed) pada cop_controller.js serta dependensi logger yang tidak terpakai pada request-billing.service.js.
  • Perubahan Database (DDL / DML):

    sql
    -- Tidak ada perubahan skema database (DDL/DML) untuk task ini.
    -- Perubahan berupa perbaikan urutan transaksi state flag dan pembersihan log status redundan.
  • Kontrak API & Response Payload: Tidak ada perubahan kontrak request/response API publik. Perubahan terjadi pada alur internal transactional logging dan sequence flagging database pada endpoint pengiriman COP/PHQC Sinkarkes (sendFormSINKARKES).


4. Bukti Teknis (Technical Proof & Audit Trail) ​

Cuplikan Kode / Implementasi Inti ​

javascript
// app/controllers/cop_controller.js - Perbaikan urutan updateFlagBillingWarta
try {
  const resultLayanan = await sendLayanan(payloadSinkarkes);
  
  // Flagging hanya diupdate jika pengiriman layanan sukses
  if (resultLayanan && resultLayanan.status) {
    await updateFlagBillingWarta(idLayanan, isSingleBilling, 'karkes');
  }
} catch (error) {
  // Flagging tidak dieksekusi saat pengiriman gagal
  logger.error("Failed to send layanan Sinkarkes:", error);
  throw error;
}

5. Bukti Verifikasi Pengujian (QA / API Verification) ​

Diisi saat naik ke Staging atau Production.

A. Hasil Test Runner Lokal (Unit / Integration Test) ​

json
{
  "test_suites": [
    "tests/services/request-billing.service.test.js (PASS)"
  ],
  "verification_status": "DEV_PASSED"
}
  • Hasil Pengujian Unit Test: PASSED (Lokal Dev)
  • Status Verifikasi Staging: PENDING (Menunggu pengujian integrasi UAT Staging)
  • Catatan QA: Unit test disesuaikan pasca penghapusan kode status 101/103/111 dan telah lulus secara empiris pada local runner.

B. Panduan Pengujian QA & Verifikasi Staging (QA Playbook) ​

Panduan eksekusi pengujian tim QA untuk memvalidasi urutan flagging Single Billing pada COP Sinkarkes dan memastikan eliminasi kode status redundan.

  • Cakupan Pengujian: UI Frontend Pengangkut (End-to-End) & Backend API
  • Endpoint Terkait:
    • POST /submit-cop (Pengiriman formulir Karantina Kesehatan Sinkarkes)
    • POST /request-billing (Permintaan manual Single Billing)
  • Postman Collection File: ND-183_fix_billing_flag_sequence_postman_collection.json
  • Akses & Role: Role Agen Pengangkut / PPJK

1. Konfigurasi Variabel Postman Collection ​
Variable NameDefault Value / TemplateFungsi & Deskripsi
baseUrlhttps://demo-backend.insw.go.id/pengangkut/apiBase URL API pengangkut core
bearerTokenKZ6IlAA4NxocmCozKC71xaYymS7sMAgM_94h0gftFnGBearer token otentikasi user PPJK/Agen
inswKemenhubKeyxxxKey otentikasi header insw-kemenhub-key respons approval LK3
billingKemenhubKeyxxxKey otentikasi tagihan Kemenhub (KL 022)
billingKemenkesKeyxxxKey otentikasi tagihan Kemenkes (KL 024)
serviceNumber102019B83694CNomor aju keberangkatan kapal target uji billing
serviceNumberKedatangan101019543877BNomor aju kedatangan kapal target uji Sinkarkes
idempotencyKey""Key idempotency otomatis di-set saat eksekusi pre-request

2. Simulasi Data Prasyarat (Data Seeding) ​

Sebelum menjalankan pengujian sequence flagging dan request billing, siapkan data prasyarat di environment Staging menggunakan cURL berikut:

A. Simulasi Approval LK3 Kemenhub (POST /warta-kapal/send/putResponse) ​
bash
curl --location 'https://demo-backend.insw.go.id/pengangkut/api/warta-kapal/send/putResponse' \
--header 'Content-Type: application/json' \
--header 'insw-kemenhub-key: xxx' \
--data '{
  "no_aju": "{{serviceNumber}}",
  "tipe": "LK3",
  "nomor_layanan": "BDN.IDMAK.2609.000140",
  "status": 2,
  "message": "",
  "nomor_produk": "SL003.IDMAK.0926.000142",
  "waktu_approve": "2026-09-09 11:10:22",
  "link_produk": "https://simpadu-inaportnet.dephub.go.id/index.php/document/pdfs/lk3_nakhoda/SL003.DN.IDMAK.2609.000139",
  "kode_dermaga": ""
}'
B. Simulasi Tagihan Inaportnet Kemenhub KL 022 (POST /tagihan) ​
bash
curl --location 'https://demo-backend.insw.go.id/pengangkut/api/tagihan' \
--header 'Content-Type: application/json' \
--data '{
  "simponi_req": {
    "method": "billingcode",
    "key": "{{billingKemenhubKey}}",
    "data": [
      {
        "header": [
          "{{serviceNumber}}",
          "INV.IDMAK.2609.000003",
          "",
          null,
          "022",
          "04",
          "413439",
          "F",
          "1",
          834660,
          "Labuh-PU-PT. JELAJAH LAUT NUSANTARA",
          "413439",
          "014844831042001"
        ],
        "detail": [
          [
            "Labuh-PU-PT. JELAJAH LAUT NUSANTARA",
            "000401",
            "201615C",
            "425513",
            90,
            9274,
            "Per GT/15 Hari",
            834660,
            "19",
            "51",
            0
          ]
        ]
      }
    ]
  }
}'
C. Simulasi Tagihan Sinkarkes Kemenkes KL 024 Keberangkatan (POST /tagihan) ​
bash
curl --location 'https://demo-backend.insw.go.id/pengangkut/api/tagihan' \
--header 'Content-Type: application/json' \
--data '{
  "simponi_req": {
    "method": "billingcode",
    "key": "{{billingKemenkesKey}}",
    "data": {
      "header": [
        "{{serviceNumber}}",
        "58830",
        "SIxxxxx",
        "2026-09-08 07:23:44",
        "024",
        "05",
        "416145",
        "F",
        "1",
        85000,
        "PT JELAJAH LAUT NUSANTARA",
        "416145",
        "014844831042001"
      ],
      "detail": [
        [
          "PT JELAJAH LAUT NUSANTARA",
          "001111",
          "2024045",
          "425314",
          85000,
          1,
          "Per Pemeriksaan Per Kapal",
          85000,
          "19",
          "51"
        ]
      ]
    }
  }
}'
D. Simulasi Tagihan Sinkarkes Kemenkes KL 024 Kedatangan (POST /tagihan) ​
bash
curl --location 'https://demo-backend.insw.go.id/pengangkut/api/tagihan' \
--header 'Content-Type: application/json' \
--data '{
  "simponi_req": {
    "method": "billingcode",
    "key": "{{billingKemenkesKey}}",
    "data": {
      "header": [
        "{{serviceNumberKedatangan}}",
        "58830",
        "SIxxxxx",
        "2026-09-08 07:23:44",
        "024",
        "05",
        "416145",
        "F",
        "1",
        85000,
        "PT JELAJAH LAUT NUSANTARA",
        "416145",
        "014844831042001"
      ],
      "detail": [
        [
          "PT JELAJAH LAUT NUSANTARA",
          "001111",
          "2024045",
          "425314",
          85000,
          1,
          "Per Pemeriksaan Per Kapal",
          85000,
          "19",
          "51"
        ]
      ]
    }
  }
}'

3. Skenario Pengujian ​
Skenario 1: Simulasi Gagal Kirim Layanan Sinkarkes via Frontend dan Integritas Flag Single Billing ​
  • Tujuan: Memvalidasi bahwa kegagalan transmisi layanan Sinkarkes (misalnya downstream Kemenkes timeout, service unavailable, atau network failure) TIDAK memperbarui flag single billing menjadi true. Hal ini memastikan penutupan celah keamanan bypass kedatangan menuju keberangkatan.
  • Cakupan Pengujian: Alur UI Frontend Pengangkut -> hit ke endpoint POST /submit-cop.
  • Prasyarat & Pre-condition:
    1. Nomor aju kedatangan kapal () telah dibuat di aplikasi Pengangkut.
    2. Warta Kapal Belum Dikirim (Non Single Billing): Layanan Warta Kapal (Inaportnet Kemenhub) pada aju kedatangan belum dikirim atau belum memilih Single Billing (fl_billing_warta masih false/null).

      Catatan Teknis Evaluasi Single Billing: Sistem mengevaluasi status Single Billing kapal berdasarkan logika OR (CASE WHEN a.fl_billing_warta OR a.fl_billing_sinkarkes = true THEN true ELSE false END AS fl_billing). Agar verifikasi visual di UI Frontend valid menampilkan Non Single Billing, Warta Kapal kedatangan tidak boleh berstatus Single Billing.

    3. Layanan Sinkarkes (COP) belum berstatus sukses/terkirim.
    4. Downstream Kemenkes pada environment Staging disimulasikan gagal merespon (atau koneksi pengiriman terputus/error).
  • Langkah Pengujian (Via UI Frontend):
    1. Buka aplikasi web Pengangkut di browser dan login dengan akun Agen Pelayaran / PPJK.
    2. Masuk ke menu Kedatangan Kapal -> Cari dan pilih Nomor Aju Kedatangan target ().
    3. Buka tab formulir Karantina Kesehatan (Sinkarkes / COP / PHQC).
    4. Pada opsi Single Billing, centang / aktifkan toggle Single Billing.
    5. Lengkapi isian data formulir COP/PHQC sesuai kebutuhan uji, kemudian klik tombol Kirim Formulir.
    6. Frontend secara otomatis menembak endpoint POST /submit-cop dengan membawa payload isSingleBilling: true.
    7. Karena downstream Sinkarkes gagal, sistem menampilkan notifikasi/modal error pada UI (misal: "Gagal mengirim layanan Sinkarkes" / respon HTTP status 500/502).
  • Verifikasi Hasil Pengujian (UI Frontend & Database):
    1. Pemeriksaan Sisi Frontend UI: Buka kembali halaman detail Kedatangan Kapal target (). Pastikan pada kolom / label informasi Jenis Pengajuan tetap berstatus Non Single Billing (karena fl_billing_warta dan fl_billing_sinkarkes keduanya bernilai false).
    2. Pemeriksaan Sisi Database (Query SQL):
    sql
    -- Verifikasi kolom flag single billing warta kapal kedatangan
    SELECT 
      service_number, 
      fl_billing_warta,
      fl_billing_sinkarkes,
      (CASE WHEN fl_billing_warta OR fl_billing_sinkarkes THEN 'Single Billing' ELSE 'Non Single Billing' END) AS jenis_pengajuan_ui
    FROM pengangkut.agents 
    WHERE service_number = '{{serviceNumberKedatangan}}';
  • Kriteria Penerimaan (Acceptance Criteria):
    1. Respon kegagalan pengiriman ditangani secara aman oleh sistem (tidak menyebabkan crash atau unhandled state).
    2. Pada tampilan Frontend UI, Jenis Pengajuan permohonan kedatangan tetap tertera Non Single Billing.
    3. Nilai kolom fl_billing_sinkarkes pada database pengangkut.agents TETAP FALSE (bernilai false, 0, atau null).
    4. State database tidak terpolusi oleh update prematur.
    5. Pengguna DILARANG melanjutkan pengajuan Keberangkatan kapal; jika pengguna mencoba membuat aju keberangkatan yang merujuk pada aju kedatangan ini, sistem memblokir dengan pesan validasi: "Harap ajukan Pemberitahuan Kedatangan kapal (Layanan Sinkarkes) dengan memilih Single Billing pada aju ... sebelum melanjutkan."

Skenario 2: Request Billing Positif dan Verifikasi Eliminasi Log Status Redundan ("Proses Permintaan Tagihan") ​
  • Tujuan: Memastikan bahwa ketika proses permintaan billing berhasil dieksekusi (POST /request-billing), sistem TIDAK LAGI mencatat kode status prematur dan redundan 101 ("Proses Permintaan Tagihan"), 103 ("Tagihan Diterima"), atau 111 ("Penerbitan Tagihan").
  • Prasyarat & Pre-condition:
    1. Data Keberangkatan Kapal () telah berstatus siap billing (contoh: Approval LK3 Kemenhub telah disetujui / status valid).
  • Langkah Pengujian:
    1. Buka halaman detail Keberangkatan Kapal pada UI Frontend, lalu klik tombol Permintaan Billing (atau jalankan eksekusi cURL di bawah).
    bash
    curl --location 'https://demo-backend.insw.go.id/pengangkut/api/request-billing' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{bearerToken}}' \
    --data '{
      "serviceNumber": "{{serviceNumber}}"
    }'
    1. Respon API mengembalikan status 200 OK (atau 201 Created) yang menandakan permintaan billing berhasil diteruskan:
    json
    {
      "status": 200,
      "message": "Berhasil memproses permintaan billing",
      "data": {
        "serviceNumber": "{{serviceNumber}}",
        "status": "SUCCESS"
      }
    }
  • Verifikasi Tampilan Antarmuka (Frontend UI):
    1. Login ke aplikasi web Pengangkut dengan akun Agen/PPJK.
    2. Buka menu permohonan terkait dan masuk ke tab Karantina Kesehatan (Sinkarkes) atau riwayat status permohonan.
    3. Amati daftar status alur yang ditampilkan pada antarmuka pengguna.
  • Kriteria Penerimaan (Acceptance Criteria):
    1. Pada linimasa / tabel status permohonan Sinkarkes di Frontend UI, TIDAK ADA LAGI status "Proses Permintaan Tagihan".

Single Source of Truth (SSOT) Arsitektur & Perubahan Teknis Backend