[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:
- 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.
- Update baris Staging saat naik ke UAT. Ubah "Stage Saat Ini" di header menjadi STAGING.
- Update baris Production saat naik ke Prod. Ubah "Stage Saat Ini" di header menjadi PRODUCTION.
- Update entry di README.md setiap kali status berubah. -->
1. Informasi Tugas & Referensi Bisnis
Task ID / Nomor Referensi:
FEAT-RUNTIME-ENV-VALIDATIONSumber Instruksi: Standardisasi Tata Kelola Konfigurasi Runtime & Pencegahan Insiden Missing Environment
Dokumen Referensi / Lampiran: Tidak ada
Task / Dependensi Terkait (Cross-Service):
Modul Terkait:
Single BillingService / Repository:
single-billing-BEPIC Pengembang: Muhamad Firly Ramadan & Hermansyah Efendi
Latar Belakang & Ringkasan Kebutuhan: Sebelumnya, backend
single-billing-BEmembaca 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 runtimeapp/utils/env-validator.jsyang dieksekusi di urutan paling awal padaserver.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 menghapusREDIS_PORT(karena cluster cache telah mengadopsi format multi-nodeREDIS_NODES).Ruang Lingkup & Rincian Sub-Pekerjaan (Technical Scope & Milestones):
- [x] Pembuatan modul validator lingkungan runtime terpusat pada
app/utils/env-validator.jsdengan kamusENV_SCHEMA - [x] Injeksi pemanggilan validator di baris paling awal
server.jssebelum Express, koneksi database, dan rute di-load - [x] Penerapan mekanisme Fail-Fast (
process.exit(1)) jika variabel wajib bernilaiundefined,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_PORTdari skema wajib untuk mendukung konfigurasi node fleksibelREDIS_NODES
- [x] Pembuatan modul validator lingkungan runtime terpusat pada
2. Deployment Lifecycle
| # | Environment | Tanggal & Waktu | PIC | Status | Catatan |
|---|---|---|---|---|---|
| 1 | Development | 2026-09-02 12:46 | Muhamad Firly Ramadan & Hermansyah Efendi | DEPLOYED | Branch: development (Merged from feat/env-validation) |
| 2 | Staging (UAT) | 2026-10-14 13:00 | Hermansyah Efendi / QA | DEPLOYED | Release 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] |
| 3 | Production | 2026-10-14 20:06 | achmad fauzi | DEPLOYED | Branch: 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
| Tanggal | Environment | Perubahan | PIC |
|---|---|---|---|
| 2026-10-14 | Production | Status diupdate ke PRODUCTION (DEPLOYED, CLOSED), rilis Release v1.9.2 via MR !232 | Hermansyah Efendi |
| 2026-09-07 | Development | Inisialisasi draft audit log dari context block backend (commit a9861c2) | Muhamad Firly Ramadan & Hermansyah Efendi |
3. Analisis Teknis & Rincian Perubahan
Alur Logika & Bisnis:
- Prinsip Fail-Fast saat Server Bootstrap:
- Ketika
server.jsmulai dieksekusi,validateEnv()langsung berjalan sebelum modul Express, koneksi database, atau routing dimuat. - Fungsi ini mengiterasi setiap key pada
ENV_SCHEMA. Jika terdapat variabel denganrequired: trueyang nilainya tidak ada atau hanya berupa whitespace, variabel tersebut dicatat ke arraymissingRequired. - 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 viaprocess.exit(1).
- Ketika
- Audit Variabel Tidak Terdaftar (Warning):
- Variabel yang didefinisikan pada file environment aktif namun tidak tercatat di
ENV_SCHEMAakan 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.
- Variabel yang didefinisikan pada file environment aktif namun tidak tercatat di
- Pembersihan Skema Konfigurasi:
- Menghapus key
SIMPONI_BILLINGdanSIMPONI_BILLING_METHODdari skema karena metode billing V1, V2, dan V3 telah distandarisasi sebagai konstanta internal diapp/helpers/simponi.js. - Menghapus
REDIS_PORTdari skema wajib karena konfigurasi Redis menggunakan parserresolveHost(process.env.REDIS_NODES)yang sudah mencakup parsing port secara otomatis per node cluster.
- Menghapus key
- 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)
- Prinsip Fail-Fast saat Server Bootstrap:
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 ID | Branch | Author | Tanggal & Jam | Ringkasan Perubahan |
|---|---|---|---|---|
ac82ae6 | feat/env-validation | Muhamad Firly Ramadan | 2026-08-31 12:16 | feat(env-validator): add env validator feature |
37a0183 | development | Hermansyah Efendi | 2026-09-02 11:39 | Merge branch 'feat/env-validation' into development |
163c471 | development | Hermansyah Efendi | 2026-09-02 11:42 | refactor(env-validator): remove unused simponi billing keys from schema |
a9861c2 | development | Muhamad Firly Ramadan | 2026-09-02 12:46 | feat(env-validator): remove REDIS_PORT from mandatory env schemas |
Cuplikan Kode / Implementasi Inti
// server.js (Injeksi pada baris paling pertama)
import "./app/utils/env-validator.js";
import express from "express";
import dotenv from "dotenv";// 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
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)
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 devataunode -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.
- Pre-kondisi: Sengaja kosongkan salah satu variabel wajib (misal
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.
- Pre-kondisi: Tambahkan variabel sembarang pada environment (misal
Skenario 3 — Happy Path: Seluruh Variabel Valid:
- Pre-kondisi: Seluruh 42 variabel mandatory pada
ENV_SCHEMAterisi 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.
- Pre-kondisi: Seluruh 42 variabel mandatory pada
Bukti Response Verifikasi Staging (Diisi saat UAT)
{
"status": "PASSED",
"note": "Pengujian verifikasi UAT dan validasi integrasi berhasil lolos, rilis production v1.9.2 telah live."
}