Gelen veri baştan beri sağlıklıydı. Yazılmasını engelleyen şey, korumanın bir gün önceki kendi çıktısıydı.
Belirti tek cümleydi: “bugün İstanbul’daki hiçbir eczane kaydı yok.” Nöbet saatlerinde. Ölçüldüğünde 21 il boştu — İstanbul, Ankara, İzmir, Antalya ve Bursa dahil. Kullanıcı “Kayıt bulunamadı” görüyordu.
İlk eleme kolaydı: kalan 61 il normaldi. Sağlayıcı çökseydi hepsi boş olurdu. Yani sorun bizim tarafımızdaydı.
Veri il eczacı odalarının listelerinden günlük çekimle geliyor ve sağlayıcı bazen yarım liste döndürüyor. Yarım listeyi yazmak, gerçekte nöbetçi olan bir eczaneyi listeden düşürmek demek — bu yüzden bir koruma var: gelen kayıt sayısı referansın yarısının altındaysa o gün için yazma atlanıyor.
Referans olarak “son gün” alınıyordu. Sorun oradaydı.
Bir gün önce 30 Ağustos Zafer Bayramıydı ve iki şey üst üste geldi:
Sonuç: İstanbul’un o günkü kayıt sayısı 130 yerine 285 oldu. Ertesi gün gelen normal 131 kayıt bu şişmiş referansın %50 eşiğinin altında kaldı, “yarıya düştü” sanıldı ve atlandı.
İstanbul’un son beş günü şöyleydi: 130 · 130 · 130 · 131 · 129. Yani gelen veri baştan beri sağlıklıydı.
Koruma bozuk veriyi engellemedi. Kendi geçmişindeki tek günlük bir anomaliye takıldı ve doğru veriyi engelledi.
Tek örneğe dayanan her eşik, er ya da geç gerçeğe karşı korumaya başlar.
Kod düzeltmesi beklemeden önce canlı düzelmeliydi. 30 Ağustos’un sabah partisi (691 satır / 21 il) yedek tabloya alındı, silindi, çekim damgası temizlendi ve çekim zorlandı.
Sonuç: 1332 kayıt / 82 il, atlanan yok. Canlı API’den doğrulandı — İstanbul 131, Ankara 49, İzmir 72, Antalya 39, Bursa 34.
const recentDays = await prisma.dutyEntry.groupBy({
by: ['dutyDate'],
where: { provinceCode: code, dutyDate: { lt: dutyDate } },
_count: { _all: true },
orderBy: { dutyDate: 'desc' },
take: 5,
});
const counts = recentDays.map((d) => d._count._all).sort((a, b) => a - b);
const lastCount = counts.length > 0 ? counts[Math.floor(counts.length / 2)] : 0;
Medyan tek günlük anomaliyi tamamen yutuyor: çift çekim, sağlayıcı hıçkırığı, bayram rotasyonu. Ortalama ise şişmeyi beşte bir oranında taşımaya devam ederdi — yani problemi küçültür ama çözmezdi.
Koruma hâlâ çalışıyor: gerçekten yarım gelen bir liste, beş günün medyanına göre de düşük kalır.
Doğrulama için silinen parti yedekten geri kuruldu ve olay birebir yeniden üretildi:
| İl | Gelen | Eski referans | Yeni referans | Eski kural | Yeni kural |
|---|---|---|---|---|---|
| 34 | 131 | 285 | 130 | atlanırdı | geçer |
| 35 | 72 | 147 | 71 | atlanırdı | geçer |
| 06 | 49 | 104 | 51 | atlanırdı | geçer |
Worker “atlandı” diye log yazıp başarıyla bitiyor. Hata alarmı çalmıyor, izleme yeşil kalıyor, ölçümler normal görünüyor. Teşhis tamamen birinin uygulamayı açıp fark etmesine kaldı.
Doğru izleme noktası şu: büyük illerde (34/06/35) kayıt sayısı sıfırsa uyar. “İş başarıyla bitti” ile “iş doğru şeyi yaptı” aynı şey değil.