Skip to content

[FEAT-RUNTIME-ENV-VALIDATION] Standardisasi Tata Kelola Konfigurasi Runtime & Pencegahan Insiden Missing Environment ​

Modul: Single Billing | Tipe: Feature | Stage Saat Ini: PRODUCTION | Tanggal Dokumen: 2026-09-07

PRODUCTION RELEASED

Dokumen ini telah berada dalam tahap PRODUCTION. Perubahan logika backend, migrasi skema/konfigurasi, dan rilis v1.9.2 telah diterapkan secara penuh di lingkungan Production via MR !232.

LIFECYCLE GUIDE — UPDATE BERTAHAP:

  1. Buat file ini saat selesai development. Isi semua section kecuali Staging & Production.
    • Tanggal Dokumen (Header) & Riwayat Update Log: Gunakan tanggal hari ini (pembuatan dokumen).
    • Baris Development (Lifecycle): Gunakan tanggal & jam commit terakhir terkait di branch development.
  2. Update baris Staging saat naik ke UAT. Ubah "Stage Saat Ini" di header menjadi STAGING.
  3. Update baris Production saat naik ke Prod. Ubah "Stage Saat Ini" di header menjadi PRODUCTION.
  4. Update entry di README.md setiap kali status berubah. -->

1. Informasi Tugas & Referensi Bisnis ​

  • Task ID / Nomor Referensi: FEAT-RUNTIME-ENV-VALIDATION

  • Sumber Instruksi: Standardisasi Tata Kelola Konfigurasi Runtime & Pencegahan Insiden Missing Environment

  • Dokumen Referensi / Lampiran: Tidak ada

  • Task / Dependensi Terkait (Cross-Service):

  • Modul Terkait: Single Billing

  • Service / Repository: single-billing-BE

  • PIC Pengembang: Muhamad Firly Ramadan & Hermansyah Efendi

  • Latar Belakang & Ringkasan Kebutuhan: Sebelumnya, backend single-billing-BE membaca variabel lingkungan (process.env) secara langsung di berbagai file layanan tanpa mekanisme validasi terpusat saat server melakukan bootstrap. Apabila terdapat variabel wajib yang terlewat atau tidak terdefinisi di container environment produksi, aplikasi tetap menyala (false healthy) namun berujung pada kegagalan fatal (unhandled rejection/crash) di tengah pemrosesan transaksi pengguna jasa. Task ini mengimplementasikan utilitas validator runtime app/utils/env-validator.js yang dieksekusi di urutan paling awal pada server.js. Validator ini menerapkan prinsip fail-fast: memvalidasi 42 variabel konfigurasi esensial (koneksi PostgreSQL, gateway SIMPONI, Inaportnet, Sinkarkes, Bank Mandiri, SSO, dan cluster cache), langsung menghentikan proses boot aplikasi (process.exit(1)) jika ada variabel wajib yang kosong, serta mendeteksi variabel tidak terdaftar melalui log peringatan. Skema validator ini juga telah diselaraskan dengan menghapus variabel legacy Simponi (yang telah dimigrasikan menjadi konstanta) dan menghapus REDIS_PORT (karena cluster cache telah mengadopsi format multi-node REDIS_NODES).

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

    • [x] Pembuatan modul validator lingkungan runtime terpusat pada app/utils/env-validator.js dengan kamus ENV_SCHEMA
    • [x] Injeksi pemanggilan validator di baris paling awal server.js sebelum Express, koneksi database, dan rute di-load
    • [x] Penerapan mekanisme Fail-Fast (process.exit(1)) jika variabel wajib bernilai undefined, null, atau string kosong
    • [x] Deteksi otomatis variabel yang ada di environment namun tidak terdaftar di skema (unregistered keys warning)
    • [x] Penyelarasan skema validator: eliminasi variabel legacy Simponi billing methods (SIMPONI_BILLING_METHOD_V1..V3) yang telah didefinisikan sebagai konstanta
    • [x] Penyelarasan skema validator: eliminasi REDIS_PORT dari skema wajib untuk mendukung konfigurasi node fleksibel REDIS_NODES

2. Deployment Lifecycle ​

#EnvironmentTanggal & WaktuPICStatusCatatan
1Development2026-09-02 12:46Muhamad Firly Ramadan & Hermansyah EfendiDEPLOYEDBranch: development (Merged from feat/env-validation)
2Staging (UAT)2026-10-14 13:00Hermansyah Efendi / QADEPLOYEDRelease Candidate via MR Staging !230. Co-deployed: [FEAT-SIMPONI-V3-ISOLATION, TASK-SET-EXPIRED-BILLING-V3, FEAT-BILLING-REKAP-EXPIRED-DATE-PAYLOAD, REFACTOR-TAGIHAN-CONTROLLER-DEDUPLICATION, FIX-PAYMENT-WEBHOOK-RACE-CONDITION, FIX-TAGIHAN-PREVENT-PAID-INVOICE-REORDER, FEAT-REQUEST-LOGGER-POSTMAN, TEST-DRAGONFLY-VITEST-SUITE, FEAT-RUNTIME-ENV-VALIDATION, TASK-NON-BLOCKING-BILLING-DISPATCH-AND-RETRY-CONFIG]
3Production2026-10-14 20:06achmad fauziDEPLOYEDBranch: prod via MR !232 (Release v1.9.2). Co-deployed: [FEAT-SIMPONI-V3-ISOLATION, TASK-SET-EXPIRED-BILLING-V3, FEAT-BILLING-REKAP-EXPIRED-DATE-PAYLOAD, REFACTOR-TAGIHAN-CONTROLLER-DEDUPLICATION, FIX-PAYMENT-WEBHOOK-RACE-CONDITION, FIX-TAGIHAN-PREVENT-PAID-INVOICE-REORDER, FEAT-REQUEST-LOGGER-POSTMAN, TEST-DRAGONFLY-VITEST-SUITE, FEAT-RUNTIME-ENV-VALIDATION, TASK-NON-BLOCKING-BILLING-DISPATCH-AND-RETRY-CONFIG]

Riwayat Update Log ​

TanggalEnvironmentPerubahanPIC
2026-10-14ProductionStatus diupdate ke PRODUCTION (DEPLOYED, CLOSED), rilis Release v1.9.2 via MR !232Hermansyah Efendi
2026-09-07DevelopmentInisialisasi draft audit log dari context block backend (commit a9861c2)Muhamad Firly Ramadan & Hermansyah Efendi

3. Analisis Teknis & Rincian Perubahan ​

  • Alur Logika & Bisnis:

    1. Prinsip Fail-Fast saat Server Bootstrap:
      • Ketika server.js mulai dieksekusi, validateEnv() langsung berjalan sebelum modul Express, koneksi database, atau routing dimuat.
      • Fungsi ini mengiterasi setiap key pada ENV_SCHEMA. Jika terdapat variabel dengan required: true yang nilainya tidak ada atau hanya berupa whitespace, variabel tersebut dicatat ke array missingRequired.
      • Jika missingRequired.length > 0, sistem mencatat error log: "Environment validation failed: required variables are not set or empty: [list]. Application boot aborted." dan segera menghentikan proses aplikasi via process.exit(1).
    2. Audit Variabel Tidak Terdaftar (Warning):
      • Variabel yang didefinisikan pada file environment aktif namun tidak tercatat di ENV_SCHEMA akan memicu log peringatan: "Environment variables present in env file but not registered in ENV_SCHEMA: [keys]". Hal ini berguna untuk mendeteksi konfigurasi usang atau typo.
    3. Pembersihan Skema Konfigurasi:
      • Menghapus key SIMPONI_BILLING dan SIMPONI_BILLING_METHOD dari skema karena metode billing V1, V2, dan V3 telah distandarisasi sebagai konstanta internal di app/helpers/simponi.js.
      • Menghapus REDIS_PORT dari skema wajib karena konfigurasi Redis menggunakan parser resolveHost(process.env.REDIS_NODES) yang sudah mencakup parsing port secara otomatis per node cluster.
    4. Klasifikasi File yang Berubah:
      • app/utils/env-validator.js (Util NEW — validator skema konfigurasi lingkungan dan fail-fast abort)
      • server.js (Bootstrap — import env-validator pada baris pertama)
      • package-lock.json (Chore)
  • Perubahan Database (DDL / DML):

    sql
    -- Tidak ada migration file yang terdeteksi (tata kelola konfigurasi runtime server backend).
  • Kontrak API & Response Payload:Tidak ada penambahan atau perubahan kontrak API.


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

  • Repository: single-billing-BE
  • Branch Utama: development
  • Merge Request / PR: !232 (Release v1.9.2 — Merged to prod) | Staging: !230

Daftar Commit Terkait (Multi-Commit Trail) ​

Commit IDBranchAuthorTanggal & JamRingkasan Perubahan
ac82ae6feat/env-validationMuhamad Firly Ramadan2026-08-31 12:16feat(env-validator): add env validator feature
37a0183developmentHermansyah Efendi2026-09-02 11:39Merge branch 'feat/env-validation' into development
163c471developmentHermansyah Efendi2026-09-02 11:42refactor(env-validator): remove unused simponi billing keys from schema
a9861c2developmentMuhamad Firly Ramadan2026-09-02 12:46feat(env-validator): remove REDIS_PORT from mandatory env schemas

Cuplikan Kode / Implementasi Inti ​

javascript
// server.js (Injeksi pada baris paling pertama)
import "./app/utils/env-validator.js";
import express from "express";
import dotenv from "dotenv";
javascript
// app/utils/env-validator.js (Fail-Fast Logic)
function validateEnv() {
  const schemaKeys = Object.keys(ENV_SCHEMA);
  const missingRequired = [];
  const emptyOptional = [];

  const activeKeys = loadedEnv.parsed ? Object.keys(loadedEnv.parsed) : [];
  const unregisteredKeys = activeKeys.filter((key) => !schemaKeys.includes(key));

  if (unregisteredKeys.length > 0) {
    logger.warn(
      `Environment variables present in env file but not registered in ENV_SCHEMA: ${unregisteredKeys.join(", ")}`
    );
  }

  for (const key of schemaKeys) {
    const spec = ENV_SCHEMA[key];
    const val = process.env[key];
    const isEmpty = val === undefined || val === null || val.trim() === "";

    if (!isEmpty) continue;

    if (spec.required) {
      missingRequired.push(key);
    } else if (spec.default !== undefined) {
      process.env[key] = spec.default;
    } else {
      emptyOptional.push(key);
    }
  }

  if (missingRequired.length > 0) {
    logger.error(
      `Environment validation failed: required variables are not set or empty: ${missingRequired.join(", ")}. Application boot aborted.`
    );
    process.exit(1);
  }

  logger.info("Environment validation completed successfully.");
}

validateEnv();

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

A. Verifikasi Unit Test (Development Stage) ​

  • Test Suite File: tests/** (36 test suites)
  • Status Eksekusi CLI: PASSED
text
 RUN  v4.1.11 D:/WORK/LNSW/single-billing-BE

 Test Files  36 passed (36)
      Tests  524 passed (524)
   Start at  13:18:39
   Duration  2.62s (transform 3.19s, setup 3.14s, import 5.03s, tests 1.18s, environment 9ms)

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: Worker / DB / Cron Only & Bootstrap Verification
  • Kebutuhan Akses / Role Akun: Terminal akses aplikasi backend single-billing-BE
  • Hasil Pengujian UAT: PASSED
  • Catatan QA: Validasi runtime fail-fast dan skema environment berhasil lolos pengujian UAT.
Skenario Pengujian QA (Test Scenarios) ​
  1. Skenario 1 — Negative Test: Fail-Fast saat Variabel Wajib Hilang:

    • Pre-kondisi: Sengaja kosongkan salah satu variabel wajib (misal CLIENT_ID_SSO="").
    • Trigger / Request: Jalankan npm run dev atau node -r esm server.js.
    • Ekspektasi Response: Server langsung berhenti (process exit 1), mencetak pesan error Environment validation failed: required variables are not set or empty: CLIENT_ID_SSO. Application boot aborted. dan server TIDAK membuka port HTTP.
    • Verifikasi Database / Log: Log error tercatat di terminal/output konsol.
  2. Skenario 2 — Warning Test: Deteksi Unregistered Environment Variables:

    • Pre-kondisi: Tambahkan variabel sembarang pada environment (misal CUSTOM_DUMMY_KEY=true).
    • Trigger / Request: Jalankan npm run dev.
    • Ekspektasi Response: Server mencetak log peringatan Environment variables present in env file but not registered in ENV_SCHEMA: CUSTOM_DUMMY_KEY, namun server tetap melanjutkan bootstrap karena seluruh variabel mandatory terpenuhi.
    • Verifikasi Database / Log: Log warning tercatat pada stream logger.
  3. Skenario 3 — Happy Path: Seluruh Variabel Valid:

    • Pre-kondisi: Seluruh 42 variabel mandatory pada ENV_SCHEMA terisi nilai valid.
    • Trigger / Request: Jalankan npm run dev.
    • Ekspektasi Response: Server mencetak log Environment validation completed successfully. dan HTTP server sukses menyala pada port yang ditentukan.
    • Verifikasi Database / Log: Aplikasi siap menerima koneksi HTTP.
Bukti Response Verifikasi Staging (Diisi saat UAT) ​
json
{
  "status": "PASSED",
  "note": "Pengujian verifikasi UAT dan validasi integrasi berhasil lolos, rilis production v1.9.2 telah live."
}

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