Her emeklilik veri mühendisi eninde sonunda aynı duvara toslar. Rakamlar pazartesi tutar, salı bozulur, çarşamba yine tutar ve kimse nedenini açıklayamaz. SQL doğrudur. Join'ler yerindedir. İş kuralları her unit test'i geçer. Yine de devlet katkısı raporu, fon NAV raporundan 137,42 TL farklıdır ve denetçi bir cevap ister.
Cevap neredeyse her zaman aynıdır: sizin bir veri probleminiz değil, bir saat probleminiz var.
BES (Bireysel Emeklilik Sistemi) pipeline'ları en az dört bağımsız zamansal eksen üzerinde çalışır. Standart veri mimarisi — veri ambarı kurslarında öğretilen ve çoğu ETL çerçevesine gömülü olan yaklaşım — tek bir saat olduğunu varsayar; event time ile processing time'ı ayırt edecek kadar sofistikeyseniz belki iki. Emeklilik sistemleri dört tane gerektirir ve bunlar senkronize kalmayı reddeder.
Dört Saat
Bir BES pipeline'ındaki her kayıt aynı anda dört zaman çizgisinde var olur:
- Transaction time: işlemin kaynak sistemde fiziksel olarak kaydedildiği an. Satır, perşembe günü 14:32:07'de OLTP veritabanına düştü.
- Effective time: işlemin ekonomik etkisini gösterdiği kabul edilen an. Perşembe öğleden sonra ödenen bir katkı, cutoff kurallarına göre çarşamba veya pazartesi değerleme tarihi itibarıyla geçerli sayılabilir.
- Regulatory submission time: işlemin EGM, SPK veya Takasbank hattına raporlandığı an. Genellikle T+1 veya T+2'dir ve gönderildikten sonra dondurulur. Düzeltmeler, kendi zaman damgasıyla ayrı bir ters çevirme-ve-yeniden gönderme akışını gerektirir.
- Fund valuation time: işlemin belirli bir fon NAV'ı üzerinden fiyatlandırıldığı an. Bu, her fon ve iş günü için deterministiktir, ancak tek bir katkı farklı değerleme pencerelerine sahip birden çok fona bölünebilir.
Bu saatlerin her biri bağımsız işler. Her birinin kendi "dün" ve "şu an itibarıyla" kavramı vardır. Ve her biri, belirli bir aşağı akış tüketicisi için doğru saattir.
Çöküş Nerede Gerçekleşir
Çoğu veri ambarı bu problemi bir saat seçerek — genellikle transaction time, bazen effective time — ve diğer her şeyi türetilmiş öznitelik olarak ele alarak çözer. Bu, bir yere kadar işe yarar. HAYMER ve devlet katkısı pipeline'larından somut örnekler:
Geç cuma katkısı. Bir müşteri cuma 17:45'te öder. Transaction time cuma. Effective time pazartesi (cutoff sonrası). Regulatory submission time salı. Fund valuation time pazartesinin NAV'ı. Pipeline'ınız günlük agregasyon için transaction time'ı primary key olarak kullanıyorsa, cumartesi yapılan devlet katkısı hesabı henüz değerlenmemiş, fiyatlanmamış ve gönderilmemiş bir ödemeyi içerecektir. Rakam, dört tüketiciden üçü için yanlıştır.
Geriye dönük düzeltme. Bir operatör, ayın 15'inde yanlış kodlanmış bir katkıyı, 3'ü itibarıyla geçerli olacak şekilde düzeltir. Transaction time 15. Effective time 3. Regulatory submission 16'dır, ancak 4'teki orijinal gönderime bir ters işlem olarak referans vermek zorundadır. Fund valuation, 15'in değil 3'ün NAV'ına göre yeniden hesaplanmalıdır. Yalnızca tek bir zaman damgası saklayan bir pipeline bu olayı ifade edemez. Ya geçmişin üzerine yazacak (audit trail bozulur) ya da çift sayacaktır (bakiye bozulur).
Devlet katkısı cutoff'u. Devlet katkısı, effective-time pencerelerine göre hesaplanır ancak regulatory-submission-time pencerelerine göre ödenir. Aralık'ta effective, Ocak'ta gönderilen bir katkı, aynı anda iki farklı mali muameleye tabidir. Fact tablonuzu tek bir tarih sütunu etrafında kurduysanız, sonraki çeyreği finans ekibine sapmaları açıklayarak geçireceksiniz.
Değerleme gecikmesi sırasında fon değişimi. Bir müşteri perşembe fon değiştirir. Eski fonun çıkış NAV'ı perşembenin kapanışıdır. Yeni fonun giriş NAV'ı cumanın kapanışıdır (T+1 değerleme). Transaction time tek bir andır; fund valuation time ise aynı mantıksal olay için iki farklı fonda iki farklı gündür.
Neden Rastgele Bug'lar Gibi Görünüyor
Saat çöküşünün ürettiği mutabakat hataları yapısal olarak kaçınılmaz ancak istatistiksel olarak seyrektir. Herhangi bir günde, çoğu katkının transaction time, effective time ve valuation time'ı birbirine yeterince yakındır ve çöküş önemli olmaz. Bug'lar yalnızca dikişlerde ortaya çıkar — ay sonu, cutoff pencereleri, düzeltmeler, geriye dönük ayarlamalar, volatilite dönemindeki fon değişimleri.
Bu yüzden ekipler yanlış teşhis koyar. Bug "sadece bazen oluyor." Bug "test verisinde reprodüce edilemiyor." Bug "job'ı yeniden çalıştırınca geçti." Bunların hiçbiri doğru değildir. Bug deterministiktir. Bir kayıt, modelin temsil etmediği bir zamansal sınırı her geçtiğinde tetiklenir. Sadece modelin içinden sınırı göremediğiniz için rastgele görünür.
Gerçekten Ne İşe Yarar
Bu pipeline'ları yeterince yıl paralel çalıştırdıktan sonra birkaç yapısal karar tartışmaya kapalı hale geldi:
- Her fact satırında dört zaman damgasını da saklayın. Türetilmiş değil, okurken hesaplanmış değil — kalıcı, indekslenmiş ve değiştirilemez.
txn_ts,effective_dt,reg_submit_ts,valuation_dt. Depolama ucuzdur. Mutabakat toplantıları değildir. - Asla üzerine yazmayın. Validity interval'lar ile append edin. Bitemporal modelleme, emeklilik verisi için opsiyonel değildir. Her düzeltme, kendi transaction time'ı ile yeni bir satırdır ve effective time'da neyin yerine geçtiğine bir referans içerir.
- Tüketicinin saatini beyan etmesini sağlayın. Devlet katkısı raporları effective time üzerinden okur. Fon NAV raporları valuation time üzerinden okur. EGM gönderimleri regulatory time üzerinden okur. Operasyonel dashboard'lar transaction time üzerinden okur. Paylaşılan bir "gerçek" tablosu değil, ayrı view'lar kurun.
- Saatler içinde değil, saatler arasında mutabakat yapın. İlginç kontrol "bugünün toplamı, dünün toplamı artı bugünün katkıları ile eşleşiyor mu" değildir. "Kasım'daki effective_dt'ye sahip katkıların toplamı, bilinen ters işlemler için düzeltildiğinde Kasım gönderim batch'indeki reg_submit_ts toplamı ile eşleşiyor mu" sorusudur. Bu iki rakam uyuşmalıdır; uyuşmadıklarında delta size tam olarak hangi saatin kaydığını söyler.
- Cutoff kurallarını dokümantasyon değil, kod olarak ele alın. 17:45'lik bir ödemenin cuma-effective mi yoksa pazartesi-effective mi olduğunu belirleyen kural; üç kişinin farklı yorumladığı bir spesifikasyon dokümanındaki paragrafta değil, versiyonlanmış ve test edilmiş bir fonksiyonda yer almalıdır.
Daha Derin Nokta
Emeklilik sistemleri sıra dışı değildir. Sadece, her düzenlenmiş finansal pipeline'da var olan bir konuda dürüsttürler: zaman bir skaler değildir. Sigorta talepleri, menkul kıymet takası, vergi tahakkukları, IFRS 17 raporlaması — hepsi birden fazla saat üzerinde çalışır ve saatler çökertildiğinde hepsi aynı sınıf "rastgele" bug üretir.
BES pipeline'ları en net öğretici vakadır; çünkü dört saat de resmidir, hepsi denetlenebilir ve her biri, yanlış yaparsanız fark edecek farklı düzenleyiciler tarafından tüketilir. Saklanacak yer yoktur.
Çözüm daha fazla validation, daha fazla test veya daha fazla monitoring değildir. Çözüm, şema düzeyinde "şimdi"nin bir değer değil, bir vektör olduğunu kabul etmektir. Model bunu yansıttığında, bug'ların çoğu bug olmaktan çıkar. Zaten oldukları şeye dönüşürler: kimsenin sormayı düşünmediği soruların doğru cevaplarına.