Konfirmasi Pembayaran — dari Langsung ke Event
❌ Alur LAMA
Pesan konfirmasi disusun dan dikirim langsung dari dalam BookingPaymentService.
Masalahnya
✅ Alur BARU
Tiga lapis terpisah: event → listener → notifier terpusat, plus sapuan rekonsiliasi sebagai jaring pengaman.
Perbandingan berdampingan
| Aspek | ❌ Lama | ✅ Baru |
|---|---|---|
| Tempat pesan disusun | Di dalam BookingPaymentService | BookingConfirmationNotifier — satu-satunya tempat |
| Jumlah template | 1 (lunas) | 4 (lunas+jadwal, lunas tanpa draft, lunas tapi gagal, kedaluwarsa) |
Dicatat ke whatsapp_messages | ❌ Tidak | ✅ Ya, setelah gerbang menerima |
| Muncul di Chat Rooms | ❌ Tidak | ✅ Ya |
| Masuk riwayat percakapan AI | ❌ Tidak | ✅ Ya |
| Nominal diambil dari | Draft | Payment — yang benar-benar ditagihkan |
| Penjagaan kegagalan | Tidak ada | Berlapis: notifier + listener + sapuan |
| Kalau listener gagal | Booking terlantar selamanya | Sapuan 5 menit memungutnya |
| Pemilihan akun pengirim | Akun aktif pertama | Akun percakapan asal, fallback akun aktif pertama |
Empat template baru
notifyManualFollowUp tidak menyebut jadwalJadwalnya belum ada — pembuatan Appointment gagal. Menyebut jadwal draft di situ sama dengan menjanjikan sesuatu yang belum berlaku.
Kenapa event dipancarkan setelah commit
Kenapa listener SINKRON, bukan queued
Ini pilihan sadar, bukan kelalaian.
Ketiganya harus dikerjakan bersamaan. Mengubah salah satunya saja menghasilkan kelas kegagalan baru.
Sapuan rekonsiliasi — jaring pengaman yang tidak ada di alur lama
Celah yang ditutupnya:
Draft yang baru diselamatkan harus dikabari di sapuan itu juga. Sapuan berjalan justru karena listener-nya tadi gagal — tidak ada pihak lain yang akan mengirim konfirmasi. Tanpa itu, hasilnya kelas kegagalan yang sama dengan yang hendak diperbaiki, hanya bergeser satu langkah: uang masuk, janji temu terbit, pasien tidak tahu apa-apa.
Tingkatan log yang berbeda-beda
Alur baru memperkenalkan disiplin tingkat log yang tidak boleh diseragamkan:
| Tingkat | Dipakai untuk | Contoh |
|---|---|---|
Log::info | Kejadian wajar yang tetap harus terlihat | "Callback lunas diulang untuk Payment yang sudah Success" |
Log::warning | Kegagalan yang tidak menyangkut uang yang sudah diterima | "Notifikasi kedaluwarsa gagal" |
Log::error | Uang sudah diterima tapi ada yang salah | "Gagal membuat Appointment dari booking berbayar" · "Booking diselamatkan sapuan tapi notifikasinya gagal" |
Log::error di jalur pembayaran adalah kenaikan tingkat yang disengaja untuk satu-satunya kelas kegagalan yang berarti uang sudah diterima tapi pasien tidak punya janji temu. Menurunkannya jadi warning membuat baris itu tenggelam di antara ribuan peringatan biasa.
Penjagaan berlapis di alur baru
Kenapa penjagaannya di pemanggil, bukan di notifier: hanya di sana konteks yang dibutuhkan log diketahui — outcome konfirmasinya, id draft, dan id janji temu yang terlibat. Kalau exception itu jatuh ke catch terluar, yang tercatat adalah "gagal mengonfirmasi booking" — dan itu bohong: konfirmasinya berhasil, hanya pesannya yang gagal. Ops akan mengejar hal yang salah.