Skip to content

[REFACTOR-DEPRECATE-POST-STATUS-SERVICE-MIGRATION] Refaktorisasi Arsitektur Status Layanan Pengangkut: Migrasi ke Unified Status Service V2, Deprecasi Controller Legacy, dan Sentralisasi Master Enum Status ​

Modul: Pengangkut | Tipe: Refactoring | Stage Saat Ini: STAGING | Tanggal Dokumen: 2026-09-04


1. Informasi Tugas & Referensi Bisnis ​

  • Task ID / Nomor Referensi: REFACTOR-DEPRECATE-POST-STATUS-SERVICE-MIGRATION

  • Sumber Instruksi: Git Branch refactor/post-status-helper

  • Dokumen Referensi / Lampiran: Tidak ada

  • Task / Dependensi Terkait (Cross-Service): MAINT-SUPERSET-SUMMARY-SHIP-SYNC-SECURITY

  • Modul Terkait: Pengangkut

  • Service / Repository: pengangkut-backend

  • PIC Pengembang: Hermansyah Efendi

  • Latar Belakang & Ringkasan Kebutuhan: Refaktorisasi arsitektur pengelolaan status tahapan layanan pengangkut untuk mengeliminasi ketergantungan pada fungsi legacy berbasis positional array yang rawan kesalahan urutan parameter dan minim type-safety. Perubahan ini secara resmi menandai fungsi postStatus dan postStatusAsync pada app/controllers/superset_summary_controller.js sebagai @deprecated, memigrasikan logika bisnis pembaruan status ke service layer terpadu (summaryStatusService.updateStatus), menyediakan controller HTTP V2 berbasis asyncHandler (app/controllers/v2/summary.controller.js), serta membakukan kamus master status ke dalam konstanta enum terpusat (STATUSES, SERVICE_TYPES, SUBMISSION_TYPES).

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

    • [x] Sub-Pekerjaan 1 — Pembentukan Master Enum Status: Sentralisasi seluruh status kode layanan (iw, ow, rksp, cop, phqc, wkk, wkb) ke app/constant/statuses.constant.js serta konstanta tipe layanan dan pengajuan
    • [x] Sub-Pekerjaan 2 — Deprecasi Fungsi Legacy: Pemberian anotasi JSDoc @deprecated pada postStatus dan postStatusAsync di app/controllers/superset_summary_controller.js
    • [x] Sub-Pekerjaan 3 — Implementasi Unified Status Service: Pembuatan method summaryStatusService.updateStatus pada app/services/summary-status.service.js dengan dukungan input structured DTO objek dan multi-payload (array)
    • [x] Sub-Pekerjaan 4 — Implementasi Controller HTTP V2: Pembuatan controller modern app/controllers/v2/summary.controller.js yang terintegrasi dengan middleware parseWithZod dan asyncHandler
    • [x] Sub-Pekerjaan 5 — Pembaruan Routing API: Pengalihan rute endpoint POST /summary/status pada app/routers/superset_summary_route.js dari controller legacy ke controller V2
    • [x] Sub-Pekerjaan 6 — Refaktorisasi Konsumsi Internal: Migrasi pemanggilan update status pada app/controllers/kedatangan_inward_controller.js dari format array [service_number, 'iw', 31, '', 'm'] ke pemanggilan terstruktur summaryStatusService.updateStatus

2. Deployment Lifecycle ​

#EnvironmentTanggal & WaktuPICStatusCatatan
1Development2026-07-07 15:25Hermansyah EfendiDEPLOYEDBranch: development (Merged via 6a68363d from refactor/post-status-helper)
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-09-04DevelopmentInitial log created from backend context blockHermansyah Efendi

3. Analisis Teknis & Rincian Perubahan ​

  • Alur Logika & Bisnis:

    mermaid
    flowchart TD
        subgraph Legacy Architecture [Legacy Flow - DEPRECATED]
            A1[Caller / Client] -->|Positional Array [service_number, 'iw', 31, '', 'm']| B1[postStatusAsync / postStatus]
            B1 --> C1[Direct DB Query & Inconsistent Error]
        end
    
        subgraph Modern Architecture [V2 Flow - ACTIVE]
            A2[HTTP Client POST /summary/status] -->|Zod Validation| B2[v2/summary.controller.js]
            A3[Internal Service / Controller] -->|Structured DTO Object| C2[summaryStatusService.updateStatus]
            B2 --> C2
            C2 -->|Validate via STATUSES Constant| D2[Database Transaction & Log Sync]
        end
    1. Eliminasi Positional Array Hazard:
      • Pola legacy menggunakan array tanpa penamaan field: [service_number, service_type, status_id, status_info, type]. Hal ini sangat rawan bug jika terjadi kesalahan urutan indeks argumen.
      • Pola baru mewajibkan DTO berbasis objek:
        javascript
        {
          service_number: string,
          service_type: string,
          status_id: number,
          status_info: string,
          type: string
        }
    2. Deprecasi Bertahap (Backward Compatibility):
      • Fungsi postStatus dan postStatusAsync di superset_summary_controller.js tidak langsung dihapus guna mencegah breaking changes pada modul-modul yang belum sempat dimigrasikan (seperti cop_controller.js, scheduler.js, dan barantin.service.js).
      • Kedua fungsi tersebut ditandai dengan JSDoc @deprecated sebagai sinyal teknis bagi pengembang untuk beralih ke summaryStatusService.updateStatus.
    3. Penyelarasan Input Controller V2:
      • postStatus pada app/controllers/v2/summary.controller.js memanfaatkan asyncHandler dan memvalidasi req.body menggunakan SummaryPostStatusValidationSchema.
      • Mendukung opsi query param showAll=true untuk langsung mengembalikan rekapitulasi status seluruh layanan permohonan setelah pembaruan status berhasil dilakukan.
  • Daftar File yang Berubah:

    • Controller / API Route:
      • app/controllers/superset_summary_controller.js (Menambahkan JSDoc @deprecated pada postStatus dan postStatusAsync)
      • app/controllers/v2/summary.controller.js (File Baru: Controller HTTP V2 postStatus)
      • app/controllers/kedatangan_inward_controller.js (Refactor pemanggilan postStatusAsync ke summaryStatusService.updateStatus)
      • app/routers/superset_summary_route.js (Re-routing POST /summary/status ke V2)
    • Service & Constants:
      • app/services/summary-status.service.js (File Baru: Core business logic pembaruan status dan sinkronisasi log)
      • app/constant/statuses.constant.js (File Baru: Master kamus status kode per domain layanan)
      • app/constant/service-type.constant.js (File Baru: Enum nama layanan pengangkut)
      • app/constant/submission-type.constant.js (File Baru: Enum tipe permohonan kedatangan/keberangkatan)
  • Perubahan Database (DDL / DML):

    Tidak ada perubahan skema database (DDL) atau file migrasi SQL pada task refaktorisasi ini.

  • Kontrak API & Response Payload:

    POST /summary/status ​

    • Deskripsi: Endpoint HTTP V2 untuk mencatat dan memperbarui status tahapan proses permohonan pengangkut
    • Controller: app/controllers/v2/summary.controller.js (postStatus)
    • Autentikasi / Guard: Bearer Token (doIntrospection)
    • Request Header / Query / Params:
      • Header: Authorization: Bearer <token>, Content-Type: application/json
      • Query:
        • showAll (opsional, boolean): Mengembalikan objek lengkap seluruh ringkasan layanan (showAll=true)
        • type (opsional, string): Tipe filter status
    • Request Body (Structured JSON):
      json
      {
        "service_number": "101026070001",
        "service_type": "iw",
        "status_id": 31,
        "status_info": "Persiapan Kirim Data Manifest Inward"
      }
    • Request Body (Batch Array via Service Layer):
      json
      [
        "101026070001",
        "iw",
        31,
        "Persiapan Kirim Data Manifest Inward"
      ]
    • Response Payload (200 OK):
      json
      {
        "status": "Success",
        "code": 200,
        "message": "Status berhasil diperbarui",
        "data": {
          "serviceNumber": "101026070001",
          "serviceType": "iw",
          "statusId": 31,
          "statusInfo": "Persiapan Kirim Data Manifest Inward",
          "createdAt": "2026-07-07 15:25:43"
        }
      }
    • Response Error (400 Bad Request / 422 Unprocessable Entity):
      json
      {
        "status": "Failed",
        "code": 400,
        "message": "Validation Error",
        "errors": [
          {
            "path": "service_number",
            "message": "service_number is required"
          }
        ]
      }

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

Daftar Commit Terkait (Multi-Commit Trail) ​

Commit IDBranchAuthorTanggal & JamRingkasan Perubahan
dc9883dd70ffb6b906b3b6d6459bb3eac80d9159refactor/post-status-helperHermansyah Efendi2026-07-07 15:25refactor(summary): migrate status update logic to service layer and v2 controller
cdb0b3e9867cc40da5d6f9c2150acc34ebd3daccrefactor/post-status-helperHermansyah Efendi2026-07-07 15:11feat(constant): add service, status, and submission type constants

Cuplikan Kode / Implementasi Inti ​

1. Anotasi Deprecation pada Controller Legacy ​
javascript
// app/controllers/superset_summary_controller.js

/**
 * @deprecated Use postStatus from v2/summary.controller.js instead.
 */
const postStatus = async (req, res) => {
    // ... legacy implementation
};

/**
 * @deprecated Use postStatusAsync from v2/summary.controller.js instead.
 */
const postStatusAsync = async (data) => {
    const [service_number, service_type, status_id, status_info, type] = data;
    // ... legacy implementation
};
2. Implementasi Controller HTTP V2 ​
javascript
// app/controllers/v2/summary.controller.js
import asyncHandler from "../../helpers/async-handler.js";
import { summaryStatusService } from "../../services/summary-status.service.js";
import { SummaryPostStatusValidationSchema } from "../../validations/summary.validation.js";
import { parseWithZod } from "../../validations/validate.js";
import { getAllSummaryByServiceNumber } from "../superset_summary_controller.js";

export const postStatus = asyncHandler(async (req, res) => {
  await parseWithZod(SummaryPostStatusValidationSchema, req.body);

  const { service_number, service_type, status_id, status_info } = req.body;
  const { showAll, type } = req.query;

  const data = await summaryStatusService.updateStatus({
    service_number,
    service_type,
    status_id,
    status_info,
    type,
  });

  if (showAll === 'true') {
    req.query.serviceNumber = service_number;
    return getAllSummaryByServiceNumber(req, res);
  }

  res.sendJson(summaryStatusService.humanizeResult(data));
});
3. Migrasi Konsumsi Internal pada kedatangan_inward_controller.js ​
javascript
// app/controllers/kedatangan_inward_controller.js

// [SEBELUMNYA - LEGACY]
// let postStatusPersiapan = [service_number, 'iw', 31, '', 'm']
// await postStatusAsync(postStatusPersiapan);

// [SETELAH REFAKTOR - MODERN]
await summaryStatusService.updateStatus({
  service_number,
  service_type: SERVICE_TYPES.INWARD_MANIFEST,
  status_id: STATUSES.iw.PERSIAPAN_KIRIM_DATA,
  status_info: '',
  type: SUBMISSION_TYPES.KEDATANGAN
});

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

A. Verifikasi Unit Test (Development Stage) ​

(Opsional: Dilampirkan jika task mencakup penambahan/perubahan unit test)

  • Test Suite File: Tidak ada file unit test baru disertakan pada commit refaktorisasi ini
  • Status Eksekusi CLI: SKIPPED
text
// Tidak ada file unit test baru disertakan pada commit pemeliharaan ini.
// Pengujian difokuskan pada integrasi manual via Postman dan QA Playbook.

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 & Full E2E (UI + Backend)
  • Kebutuhan Akses / Role Akun: Token sesi aktif dan nomor layanan permohonan kapal valid.
  • Hasil Pengujian UAT: PENDING
  • Catatan QA: —
Skenario Pengujian QA (Test Scenarios) ​
  1. Skenario 1 — Pembaruan Status Layanan via Controller V2 (Single Payload):

    • Trigger / Request: POST /summary/status dengan payload:
      json
      {
        "service_number": "101026070001",
        "service_type": "iw",
        "status_id": 31,
        "status_info": "Persiapan Kirim Data"
      }
    • Ekspektasi Response: HTTP 200 OK, pesan "Status berhasil diperbarui", dan data mencakup atribut status yang telah diformat.
    • Verifikasi Database / Log: Record status pada tabel tracking detail summary terisi dengan status_id = 31.
  2. Skenario 2 — Pembaruan Status Layanan dengan Flag showAll=true:

    • Trigger / Request: POST /summary/status?showAll=true dengan payload status valid.
    • Ekspektasi Response: HTTP 200 OK, respon mengembalikan full payload summary dari seluruh instansi (Bea Cukai, Kemenkes, Imigrasi, Karantina).
  3. Skenario 3 — Negative Test Validasi Input Zod:

    • Trigger / Request: POST /summary/status tanpa menyertakan atribut service_number.
    • Ekspektasi Response: HTTP 400 Bad Request / 422 Unprocessable Entity dengan rincian error validasi Zod.
  4. Skenario 4 — Verifikasi Eksekusi Alur Kedatangan Inward:

    • Trigger: Jalankan alur pengiriman dokumen kedatangan manifest inward (call_xml_bc).
    • Ekspektasi: Status permohonan berpindah secara sekuensial dari status 31 (Persiapan Kirim Data) ke status 32 (Data Selesai Dikirim) menggunakan pemanggilan terstruktur summaryStatusService.updateStatus.
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