Skip to content

[TASK-ITEM-HSCODE-REFERENSI-MIGRATION-V1.18.7] Migrasi Validasi HS Code ke Service Referensi Terpusat & Stabilisasi Logger Test Suite (Release v1.18.7) ​

Modul: Pengangkut | Tipe: Refactoring | Stage Saat Ini: DEVELOPMENT | Tanggal Dokumen: 2026-10-15

DEVELOPMENT STAGE

Dokumen ini sedang berada dalam tahap DEVELOPMENT. Perubahan logika backend, client referensi terpusat, dan stabilisasi suite pengujian masih aktif di lingkungan pengembangan (Development) dan dipersiapkan untuk promosi ke Staging via MR v1.18.7.


1. Informasi Tugas & Referensi Bisnis ​

  • Task ID / Nomor Referensi: TASK-ITEM-HSCODE-REFERENSI-MIGRATION-V1.18.7

  • Sumber Instruksi: Internal Refactoring & Test Suite Stabilization (Release v1.18.7)

  • Dokumen Referensi / Lampiran: Tidak ada

  • Task / Dependensi Terkait (Cross-Service): Tidak ada

  • Modul Terkait: Pengangkut

  • Service / Repository: pengangkut-backend

  • PIC Pengembang: Hermansyah Efendi

  • Latar Belakang & Ringkasan Kebutuhan: Validasi kode HS barang sebelumnya mengandalkan helper legacy getHsRef yang mengakses endpoint v1 service referensi secara langsung tanpa autentikasi token. Berdasarkan kebijakan pengerasan keamanan (security hardening) arsitektur LNSW, endpoint v1 tanpa token tersebut telah dinonaktifkan secara permanen guna mencegah akses unauthenticated terbuka. Seluruh integrasi dialihkan ke endpoint /v2/hscode/getOneHs yang mewajibkan validasi Bearer Token SSO INSW. Selain itu, implementasi terdahulu rentan terhadap loose equality dan potensi unhandled TypeError saat objek referensi bernilai kosong atau null. Di sisi lain, suite pengujian simulasi client abort pada middleware HTTP logger mengalami intermittent race condition akibat penggunaan arbitrary timeout di bawah beban CPU tinggi. Rilis v1.18.7 menuntaskan migrasi verifikasi HS Code ke client referensiApi.getHsCode dengan propagasi otomatis SSO token, menerapkan validasi null-safe strictly-typed, serta menstabilkan test suite middleware logger berbasis event close deterministik.

  • Ruang Lingkup & Rincian Sub-Pekerjaan (Technical Scope & Milestones):

    • [x] Penambahan method getHsCode pada service client ReferensiApi (app/api/referensi.api.js)
    • [x] Migrasi pemanggilan HS reference pada createItem dan updateItem di ItemService (app/services/item.service.js)
    • [x] Penerapan validasi format HS null-safe dan perbandingan strict (RefHs?.hsCodeFormat !== item.hs_code)
    • [x] Penambahan unit test getHsCode dan penyesuaian mock pada tests/services/item.service.test.js dengan 100% coverage
    • [x] Stabilisasi sinkronisasi event res close pada tests/middlewares/http_logger_simulation.test.js
    • [x] Version bump release v1.18.7 pada package.json, package-lock.json, dan CHANGELOG.md

2. Deployment Lifecycle ​

#EnvironmentTanggal & WaktuPICStatusCatatan
1Development2026-10-15 16:11Hermansyah EfendiDEPLOYEDBranch: development
2Staging (UAT)——PENDINGRelease Candidate v1.18.7 via MR Staging
3Production——PENDING—

Riwayat Update Log ​

TanggalEnvironmentPerubahanPIC
2026-10-15DevelopmentInisialisasi draft audit log dari context block backend (commit 1ffa3e8a s.d. ee30c536)Hermansyah Efendi

3. Analisis Teknis & Rincian Perubahan ​

  • Alur Logika & Bisnis:

    1. Depresiasi Endpoint V1 Tanpa Token & Migrasi ke V2 Berproteksi SSO (referensiApi.getHsCode):
      • Endpoint v1 legacy publik tanpa otentikasi telah dinonaktifkan demi penegakan standar keamanan (Zero Trust & API Hardening).
      • Seluruh lookup referensi HS Code dialihkan ke endpoint /v2/hscode/getOneHs melalui service client referensiApi. Client ini secara otomatis menginjeksi token SSO pengguna (Authorization: Bearer <token>) dari request context ke header HTTP request menuju upstream referensi.
      • Mengeliminasi helper getHsRef ad-hoc, memusatkan konfigurasi timeout, serta menyelaraskan penanganan error status inter-service.
    2. Validasi Strict & Null-Safe Guard:
      • Menggantikan struktur validasi legacy !(RefHs.status === 200 && RefHs.data?.hsCodeFormat === item.hs_code) menjadi evaluasi null-safe:
        javascript
        const RefHs = await referensiApi.getHsCode(item.hs_code);
        if (RefHs?.hsCodeFormat !== item.hs_code) {
          throw new ResponseError(`HS ${item.hs_code} tidak ditemukan`, status.notfound);
        }
        item.desc_btki = RefHs.uraianId;
      • Ekstraksi deskripsi barang BTKI (desc_btki) langsung dipetakan dari payload flat RefHs.uraianId.
    3. Stabilisasi Event Listener Logger Test Runner:
      • Menghilangkan flaky test pada tests/middlewares/http_logger_simulation.test.js dengan mengganti arbitrary delay setTimeout menjadi event listener sinkronisasi deterministik pada event res.on('close').
  • Perubahan Database (DDL / DML):

    sql
    -- Tidak ada perubahan skema database (DDL/DML) untuk task ini.
    -- Perubahan murni pada layer service logic, integrasi API client referensi, dan test suite.
  • Kontrak API & Response Payload: Tidak ada penambahan atau perubahan kontrak API publik (perubahan terjadi pada internal inter-service call dan service logic).


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

  • Repository: pengangkut-backend
  • Branch Utama: development
  • Merge Request / PR: — (Diproses ke Staging via MR v1.18.7)

Daftar Commit Terkait (Multi-Commit Trail) ​

Commit IDBranchAuthorTanggal & JamRingkasan Perubahan
ee30c5368cd92527fd19e4e441a6d091dd224e23developmentHermansyah Efendi2026-10-15 16:11chore(release): v1.18.7
d3890fc1ca0e2a658f07b6168bd0cc3eb2deb3b1developmentHermansyah Efendi2026-10-15 10:53test(logger): eliminate race condition in client abort simulation test
1ffa3e8af23f57db3ef3ec0cb322044068f17863developmentHermansyah Efendi2026-10-15 10:23refactor(item): migrate hs code validation to referensi api

Cuplikan Kode / Implementasi Inti ​

javascript
// app/api/referensi.api.js
    async getHsCode(hsCode) {
        return this.#client.get("/v2/hscode/getOneHs", {
            params: { hs_code: hsCode },
        });
    }

// app/services/item.service.js (createItem & updateItem)
    const RefHs = await referensiApi.getHsCode(item.hs_code);
    if (RefHs?.hsCodeFormat !== item.hs_code) {
      throw new ResponseError(`HS ${item.hs_code} tidak ditemukan`, status.notfound);
    }
    item.desc_btki = RefHs.uraianId;

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

A. Verifikasi Unit Test (Development Stage) ​

  • Test Suite File:
    • tests/api/referensi.api.test.js
    • tests/middlewares/http_logger_simulation.test.js
    • tests/services/item.service.test.js
  • Status Eksekusi CLI: PASSED (42 tests passed)
Cuplikan Kode Test Kunci ​
javascript
// tests/services/item.service.test.js
  it('rejects create when HS reference is missing or quarantine lookup fails', async () => {
    ItemHeader.findOne.mockResolvedValue({ service_number: 'SRV-1' });
    referensiApi.getHsCode
      .mockResolvedValueOnce([])
      .mockResolvedValueOnce({ hsCodeFormat: 'OTHER', uraianId: 'BTKI' })
      .mockResolvedValueOnce({ hsCodeFormat: '0101', uraianId: 'BTKI' });
    await expect(itemService.createItem({ ...completeItem }, 'USER-1')).rejects.toMatchObject({ code: 404 });
    await expect(itemService.createItem({ ...completeItem }, 'USER-1')).rejects.toMatchObject({ code: 404 });
    checkHsQuarantine.mockResolvedValue({ status: 500 });
    await expect(itemService.createItem({ ...completeItem }, 'USER-1')).rejects.toMatchObject({
      message: 'Gagal cek HS 0101', code: 500,
    });
  });
Output Raw Eksekusi CLI Runner ​
text
 RUN  v4.1.11 D:/WORK/LNSW/pengangkut-backend

 ✓ tests/api/referensi.api.test.js (19 tests) 36ms
 ✓ tests/middlewares/http_logger_simulation.test.js (3 tests) 99ms
 ✓ tests/services/item.service.test.js (20 tests) 46ms

 Test Files  3 passed (3)
      Tests  42 passed (42)
   Start at  16:14:41
   Duration  1.16s (transform 413ms, setup 103ms, import 1.67s, tests 181ms, environment 1ms)

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

Diisi saat development sebagai panduan eksekusi pengujian QA, kemudian dilengkapi bukti response JSON saat verifikasi di Staging.

  • Cakupan / Surface Pengujian: API / Postman Only
  • Kebutuhan Akses / Role Akun: Token Pengangkut Aktif / Role PPJK / Operator Pengangkut
  • Hasil Pengujian UAT: PENDING
  • Catatan QA: —
Skenario Pengujian QA (Test Scenarios) ​
  1. Skenario 1 — Simpan / Perbarui Item dengan HS Code Valid (Happy Path):

    • Pre-kondisi: Data header aju dokumen pengangkut telah dibuat di database.
    • Trigger / Request: POST /item atau PUT /item/{itemId} dengan payload valid yang memuat hs_code: "0101.21.00".
    • Ekspektasi Response: HTTP 200 OK / 201 Created, objek item tersimpan dengan field desc_btki terisi otomatis dari uraian referensi HS.
    • Verifikasi Database / Log: Tabel pengangkut.items kolom desc_btki terisi dan log aplikasi menampilkan Updating item / Inserting item.
  2. Skenario 2 — Input Item dengan HS Code Tidak Terdaftar / Tidak Valid (Negative Case):

    • Pre-kondisi: Upstream Referensi aktif.
    • Trigger / Request: POST /item atau PUT /item/{itemId} dengan hs_code: "9999.99.99" (tidak terdaftar pada referensi BTKI).
    • Ekspektasi Response: HTTP 404 Not Found, body respon memuat pesan error semantik HS 9999.99.99 tidak ditemukan.
    • Verifikasi Database / Log: Tidak ada data item baru yang ter-persist di database dan transaksi di-rollback secara aman.
Bukti Response Verifikasi Staging (Diisi saat UAT) ​
json
{
  "status": "PENDING",
  "note": "Menunggu deployment ke environment Staging untuk eksekusi skenario uji QA."
}

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