Bug yang hanya memerlukan perubahan satu baris namun butuh tiga hari untuk ditemukan biasanya disebabkan oleh prosedur pengecekan dan observabilitas yang belum terpusat. Jawaban langsungnya: dokumentasikan proses reproduksi di awal dan tambahkan lint rule atau custom check yang menangkap pola penyebab, lalu lengkapi dengan observabilitas serta checklist release agar regresi tidak terjadi lagi.

Proses Reproduksi untuk Memahami Perilaku Bug

Langkah pertama yang membuat perbaikan cepat bisa dipercaya adalah menjelaskan secara eksplisit bagaimana bug muncul. Contoh studi kasus: fitur pagination API tiba-tiba menampilkan halaman kosong karena sebuah filter baru tidak ikut memperbarui payload.

Proses reproduksi yang baik mencakup:

  • Input request lengkap: metode, header otentikasi, query parameter, dan body yang digunakan.
  • State aplikasi: data awal di database dan konfigurasi cache sebelum permintaan dijalankan.
  • Langkah-langkah: urutan endpoint yang dipanggil beserta data respons.
  • Hasil yang diharapkan vs aktual: contoh respons sukses dibandingkan respons bug.

Contoh singkat:

{
  "method": "GET",
  "path": "/orders?page=2&status=pending",
  "headers": {"Authorization": "Bearer ..."},
  "expected": "List order status pending dengan 20 item",
  "actual": "[]"
}

Tambahkan juga catatan log/stack trace yang muncul. Dokumentasi reproduksi ini menjadi acuan untuk membuat lint rule dan observabilitas.

Kembangkan Lint Rule atau Custom Check yang Menangkap Perubahan Kecil

Setelah mengetahui pola penyebab, baru dibuat lint atau pemeriksaan otomatis yang dijalankan di pre-commit atau pipeline CI. Fokusnya adalah mendeteksi perubahan minimal (satu baris) yang merusak kontrak kode.

Misalnya bug terjadi karena field query filter baru tidak ditambahkan ke serialisasi DTO. Kita bisa membuat lint rule yang memastikan setiap field DTO yang digunakan di controller juga tercantum di validator/pemroses:

function lintDtoFieldSync(file) {
  const dtoFields = extractFields(file, "src/domain/orders/dto");
  const controllerUses = extractFilters("src/controllers/orderController.js");
  const missing = controllerUses.filter(f => !dtoFields.includes(f));
  if (missing.length) {
    return {
      file,
      message: `Field ${missing.join(", ")} tidak tercantum di DTO filter.`
    };
  }
}

Kunci lint rule yang efektif:

  • Type check: pastikan tipe data request/response konsisten dengan kontrak service (misalnya menggunakan schema validation dari zod atau pydantic).
  • Pattern matching: deteksi pola nama yang harus berpasangan (seperti filter dan schema). Tools seperti eslint-plugin-custom atau ruff bisa memperluas rule.
  • Contract enforcement: bandingkan definisi DTO/graphQL schema dengan controller yang menggunakannya.

Lint rule tersebut dijalankan di pre-commit untuk mencegah pengiriman kode rusak, serta di pipeline CI untuk menangkap perubahan di branch lain. Pastikan rule mengeluarkan pesan yang menjelaskan direktori/file dan tindakan korektif.

Integrasi Observabilitas dan Rerun Debugging

Lint rule membantu mencegah bug baru, tetapi untuk bug yang sudah terjadi, observabilitas mempersingkat waktu pencarian akar masalah. Kombinasikan:

  • Logging struktural: tambahkan trace_id pada log request yang bermasalah sehingga rerun dapat memetakan alur kode.
  • OpenTelemetry atau service tracing: untuk melihat apakah filter diproses sampai unit service terakhir.
  • Metric comparison: bandingkan rata-rata durasi request dengan filter lama vs baru untuk mendeteksi perubahan perilaku.

Ketika bug terdeteksi, gunakan rerun debugging yang terotomasi:

  1. Ambil replay data dari tracing/metric untuk metode yang sama.
  2. Jalankan test atau end-to-end yang sama dengan data reproduksi.
  3. Gunakan breakpoints/log tambahan ketika filter di-parsing untuk melihat nilai tepat satu baris.

Observabilitas memberi konteks tambahan, sementara lint rule menangkap pola statis. Keduanya saling melengkapi untuk menyelesaikan bug satu baris dengan cepat.

Checklist Release Flow untuk Meminimalkan Regresi

Perbaikan satu baris harus melewati proses yang memastikan regresi lain tidak muncul. Berikut checklist release flow:

  1. Verifikasi lint: jalankan lint pre-commit dan CI. Pastikan rule baru dieksekusi di branch release.
  2. Regression test target: jalankan test yang mereproduksi bug lama plus test suite terkait (misalnya end-to-end pagination).
  3. Observability smoke test: pastikan trace baru/tampilan metric yang diproyeksikan muncul di staging.
  4. Code review khusus lint/orchestrator check: reviewer memeriksa apakah perubahan lint sesuai dengan root cause.
  5. Release note singkat: catat lint rule baru dan area yang dicek, sehingga tim QA/pemilik produk tahu apa yang berubah.
  6. Post-release monitoring: konfirmasi metric/trace kembali normal setelah deploy.

Checklist ini menjaga agar perbaikan satu baris tidak memicu masalah lain, karena setiap langkah meninjau otomasi lint dan observabilitas.