3 puan yazan GN⁺ 4 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Parayı çekirdek durum olarak ele alan sistemler, veri üretmeme, veri kaybetmeme ve hiçbir şeye güvenmeme ilkeleri üzerine tasarlanmalıdır
  • Tutar gösteriminde floattan kaçınılmalı; BigDecimal, en küçük birim tamsayıları ve rasyonel sayılar sorumluluğa uygun şekilde birlikte kullanılmalıdır; JSON sayı serileştirmesi de IEEE-754 double sorununu yeniden üretebilir
  • Defter yapısı, çift taraflı muhasebe, değiştirilemez denetim izi, value time·booking time·settlement time ayrımı ve düzeltme·iptal kayıtları sayesinde bakiye ve raporların yeniden oluşturulabilmesini korumalıdır
  • Gerçek para akışı; rezervasyonlar, idempotency, yeniden başlatılabilir durum makineleri, harici API·webhook doğrulaması, outbox·CDC ve mutabakat (reconciliation) ile çift harcama ve eksik kayıtları önlemelidir
  • Erişim kontrolü, four-eyes onayı, SDLC değişiklik takibi, özellik tabanlı testler ve hata enjeksiyonu; iç operatörleri ve kod değişikliklerini bile güven sınırı içinde ele almayı sağlar

Fintech sistemlerinin temel ilkeleri

  • Paranın sistemin ana konusu olduğu yazılım mühendisliğinde, sıradan CRUD işlemlerinden çok izlenebilirlik, değiştirilemezlik ve doğrulanabilirlik önemlidir
  • Hedef okur kitlesi; fintech'e yeni katılanlar, hâlihazırda fintech'te çalışanlar ve para sistemlerinin genel sistemlerden nasıl farklı olduğunu fintech dışından anlamak isteyenlerdir
  • Tüm kalıplar, üç ilkeyi korumak için kullanılan araçlardır
    • No invented data: Para olmayan bir yerden üretilemeyeceği için mükerrer işlemeye ve keyfi bakiye değişikliklerine izin verilmez
    • No lost data: Parayla ilgili gerçekleşen her şey izlenmeli ve kalıcı olarak saklanmalıdır
    • No trust: Harici sağlayıcılara, dahili bileşenlere ve gerçek dünyaya güvenilmez; her şey doğrulanır

Parayı ifade etme biçimleri

  • Tutar gösterimi, finansal sistemlerdeki en temel kararlardan biridir; yanlış seçildiğinde tüm üst katmanlar hatayı miras alır
  • float/double, öngörülmesi zor hassasiyet kayıpları yaratabildiği için neredeyse hiçbir zaman iyi bir seçim değildir
    • Hızlı olması, belleği verimli kullanması ve ek kütüphane ya da veri yapısı gerektirmemesi gibi avantajları vardır
  • BigDecimal gibi keyfi hassasiyetli türler, hesaplama hassasiyetini ve yuvarlamanın uygulanacağı noktayı açıkça kontrol etmeyi sağlar
    • FX veya fiyat hesaplamaları gibi birden fazla işlemin art arda geldiği ara hesaplamalar için uygundur
  • En küçük birim tamsayısı ile saklama, çoğu itibari para biriminde merkez bankası sistemlerine benzer sabit hassasiyet kullanımına dayanır
    • €12.34, 1234 olarak saklanır
    • ISO 4217 basamak sayıları izlenmeli, her zaman 2 basamak olduğu varsayılmamalıdır
    • Kripto paralarda da satoshi, wei gibi en küçük birim tamsayıları kullanılır; ancak hassasiyet varlığa göre değişir ve ERC-20'deki decimals gibi değerler token tarafından tanımlanır
    • Kripto para tutarları 64 bit tamsayıyı aşabileceğinden keyfi genişlikte tamsayı gerekebilir
  • Rasyonel sayılar, hassasiyet kaybına izin verilemeyecek durumlarda en güçlü seçenektir; ancak yavaştır, başka biçimlere hassasiyet kaybetmeden dönüştürülmesi zordur ve genellikle özel türler ya da kütüphaneler gerektirir
  • Saklama biçimi ile hesaplama biçimi ayrı kararlardır; aynı sistem, tamsayı saklama ile BigDecimal ara hesaplamalarını birlikte kullanabilir
  • Tutarların serileştirilmesinde de sınırların doğru ele alınması önemlidir
    • Genel JSON sayıları, çoğu ayrıştırıcıda IEEE-754 double olduğundan, içeride temsile dikkat edilse bile sınırda float sorunları yeniden ortaya çıkar
    • Para, "12.34" gibi string olarak ya da en küçük birim tamsayısı şeklinde gönderilmelidir

Yuvarlama ve para birimi yönetimi

  • Yuvarlama; bölme, para birimi dönüşümü, komisyon, faiz, oran uygulaması ve hassasiyet kaydırmada kaçınılmazdır, bu yüzden örtük bırakılmamalıdır
  • Yuvarlama stratejisi bir iş kararıdır
    • Bazı durumlarda aşağı yuvarlamak daha temkinli olabilir; istatistiksel etki için half-even da kullanılabilir
    • Kalan küsuratı kimin alacağı, hukuki ve vergisel sonuçlar doğurabilir
  • Mümkün olduğunca uzun süre tam hassasiyet korunmalı, yuvarlama genellikle yalnızca saklama öncesi veya kullanıcıya gösterim gibi sınır noktalarında yapılmalıdır
  • Bir değeri parçalara bölüp sonra yuvarlamak, parçaların toplamının özgün değerden farklı olmasına yol açabilir
    • Duruma göre açık bir rounding account gerekebilir
  • Para yalnızca sayı ile ifade edilemez; her zaman para birimiyle birlikte ele alınmalıdır
    • Money gibi bir newtype, struct, class veya record içinde tutar ve para birimini birlikte taşımak hata olasılığını azaltır
    • Farklı para birimlerinin toplanması yasaklanmalı; dönüşüm, sıkı şekilde denetlenen döviz kurlarıyla açıkça yapılmalıdır
    • Keyfi para birimi kodları kabul edilmemeli; sistem sınırlarında denetlenen bir para birimi kümesine karşı doğrulanmalıdır
    • İtibari para kodları tanımlayıcı olarak kullanılabilir; ancak kripto paralarda (network, contract address) gibi daha karmaşık tanımlayıcılar gerekir
    • Pegged, bridged ve wrapped kripto paralar, dayanak varlıkla eşdeğer değildir

FX kurları

  • FX rate her zaman yön taşır
    • EUR/USD kuru, USD/EUR'nin basit tersi değildir
    • Borsada alış ve satış, bid/ask spread nedeniyle farklı fiyatlardan verilen emirlerdir
  • Kurun ait olduğu zaman noktası da sonucu değiştirir
    • Güncel kur, mevcut varlıkların ya da sanki şu anda gerçekleşmiş işlemlerin değerini hesaplamak için kullanılır
    • Value-date kuru, değer değişimi ya da vergi hesaplamalarında kullanılır
  • Dönüşümde iki tür kur önemlidir
    • Transactional rate, gerçek dönüşümün gerçekleştiği kurdur; başlangıç tutarı ile sonuç tutarından türetilir
    • Reference rate, varlık değerlemesi veya vergi kıstası gibi değerlendirme ve eşdeğerlik kararlarında kullanılır; gerçek işlem fiyatı değildir
  • Standart tek bir kur yoktur
    • Kurlar piyasadan çıkar ve işlem yapılan yere ya da hesaplama yöntemine göre değişir
    • Merkez bankası kurları standarda en yakın seçenektir ancak yalnızca reference rate olarak kullanılabilir; alternatif kaynaklar da geçerli olabilir
  • Sonradan doğrulama yapılabilmesi için tutarla birlikte reference rate kaynağı da saklanmalıdır

Defter ve çift taraflı muhasebe

  • Para hareketleri, denetlenebilir ve yıllar sonra bile yeniden oluşturulabilir şekilde kaydedilmelidir
  • Çift taraflı muhasebe, finansal işlemleri (credit account, debit account, amount) biçimindeki entry listeleri olarak saklayan yaygın bir yöntemdir
    • Klasik gösterimde her hareket için debit satırı ile credit satırı ayrı tutulur
    • Tüm entry'ler aynı tutarı bir hesaptan diğerine taşıdığı için defter her zaman dengede kalır
  • Paranın her zaman bir kaynağı ve bir hedefi vardır
    • Sisteme giren ve çıkan paranın izlenebilmesi için harici sağlayıcıların da özel hesapları olmalıdır
  • Bakiye saklanmaz; para hareketlerinden türetilir
  • Hesapların asset, liability, equity gibi türleri vardır
    • accounting equation assets = liabilities + equity korunur
    • Pratikte komisyon gelirini ya da write-off zararını kaydetmek için revenue ve expense hesapları da gerekir
    • Genişletilmiş denklem assets = liabilities + equity + revenue - expenses şeklindedir
  • Tek bir işlem genellikle birden fazla hareket üretir
    • Net tutar hareketi ile komisyon hareketi ayrı ayrı oluşabilir
  • Posted entry'ler teamül gereği değiştirilemezdir; düzeltmeler, orijinal kaydı dengeleyen yeni entry'ler eklenerek yapılır

Zaman modeli: value, booking, settlement

  • İşlemlerde genellikle iki, bazen de üç zaman damgası bulunur
    • Value time: İşlemin fiilen gerçekleştiği an
    • Booking time: Sisteme kaydedildiği an
    • Settlement time: Paranın gerçekten transfer edildiği ya da somutlaştığı an
  • Settlement time her işlemde bulunmaz ve genellikle T+X biçiminde ifade edilir
    • T+2, settlement'ın value date'ten 2 gün sonra gerçekleştiği anlamına gelir
  • Value time ile booking time neredeyse her zaman farklıdır
    • booking > value ise backdated'dir; özellikle raporlama dönemleri değiştiğinde önemlidir
    • booking < value ise forward-dated'dir; rezervasyonlu ödemelerde ya da gelecekte tarihli ödemelerde görülür
  • Kartlı ödeme örneğinde akış; ödemenin T1'de gerçekleşmesi, sistemin bunu T2'de kaydetmesi ve ödeme sağlayıcısının parayı hesaba T3'te aktarması şeklindedir
  • İş raporları çoğunlukla value time veya settlement time'a bakar; booking time ise izlenebilirlik için faydalıdır
  • Birden fazla zaman noktasını tek bir created_at alanında birleştirmek, sonradan yeniden oluşturulamayacak bilgilerin kaybına yol açar

Denetim izi, event sourcing, değiştirilemezlik

  • Finansal sistemler düzenleyici denetime tabidir; kullanıcı fonlarıyla şirket fonlarının karışıp karışmadığını, gelirin açıklanabilir olup olmadığını, dışarıya verilen bilgilerin gerçekle uyumlu olup olmadığını ve fonların korunma durumunu kanıtlamaları gerekebilir
  • audit trail, yalnızca mevcut durum değil, o durumun nasıl oluştuğunun da tam geçmişidir
    • ne oldu
    • ne zaman oldu
    • bunu kim ya da ne tetikledi
    • neden oldu
  • Yalnızca para hareketleri değil, manuel müdahaleler, fee schedule, rate source, limit gibi yapılandırma değişiklikleri ve yetki değişiklikleri de denetim izi gerektirir
  • compliance check veya risk score gibi kararlar için yalnızca sonucu saklamak yeterli olmayabilir
    • DMN, Drools, Decisions4s gibi bir decision table veya rules engine içindeyse, hangi kuralın hangi girdilerle çalıştırıldığı ve hangi sonucun üretildiği yeniden oynatılabilir bir yapıya dönüşür
  • Event sourcing, audit trail oluşturmak için sistematik bir yaklaşımdır
    • mevcut durum ve logu ayrı ayrı saklamak yerine yalnızca olaylar saklanır, durum ise bunlardan türetilir
    • çift taraflı kayıt tutan bir ledger, balance saklamak yerine bunu entry'lerden hesapladığı için bu desenin bir örneğidir
  • Event sourcing'in pratikte ciddi kısıtları da vardır
    • her yerde gerekli değildir; ledger para tarafını zaten kapsıyorsa çevresindeki domain'ler için sıradan model ve güvenilir bir change log yeterli olabilir
    • performans için balance ve projection'lar cache'lenebilir veya snapshot alınabilir
    • olay kaynağı üzerinde verimli sorgu yapmak zor olabilir, bu da projection işlerini artırabilir
    • olaylar yıllarca kaldığı için bugünün kodunun çok eski olayları da okuyabilmesi gerekir
  • Denetim izi değiştirilebiliyorsa kanıt niteliği taşımaz; bu yüzden append-only olmalıdır
    • append-only table, DB yetkilerinden UPDATE ve DELETE kaldırılması, uygulama katmanında mutating operation'ların engellenmesi ve checksum ya da hash chain ile kurcalama kanıtı sağlanması kullanılabilecek araçlardır
  • Gerçek sistemlerde hatalar nedeniyle event log veya audit trail'i düzeltmek gerekebilir
    • genelde veri dışarıya raporlandıktan sonra sabitlenmelidir; raporlama öncesindeyse sorun bulunup sistem dışına çıkmadan önce yerinde düzeltme mümkün olabilir

İptal ve düzeltme

  • Hatalı tutar posting'i veya yanlış hesaba posting gibi hatalar olur
  • Değiştirilemezlik, düzeltmenin ileriye dönük yapılmasını gerektirir
    • yeni bir compensating entry posting edilir ve orijinal record ile iki yönlü bağ kurulur
  • Reversal, orijinal işlemi ekonomik olarak hiç olmamış gibi tamamen dengeler, ancak hem orijinal hem reversal geçmişte kalır
  • Correction veya adjustment, gerçek kayıt ile doğru değer arasındaki farkı booking etmek ya da önce ters çevirip ardından doğru değerle yeniden posting yapmak anlamına gelir
  • Düzeltme, orijinal işlemden farklı bir raporlama dönemine girebilir
    • raporların düzeltmeleri doğru şekilde ilişkilendirebilmesi ve gerçek faaliyeti cleanup'tan ayırabilmesi için bağlantı bilgisi olmalıdır
  • Kapalı raporlama dönemlerine backdate'e genelde izin verilmediğinden, düzeltmede geçmiş bir value time verilip verilmeyeceği raporlama takvimine bağlıdır

Para akışını yürütme: değişmez koşullar ve fon rezervasyonu

  • Invariant, sistemde her zaman doğru olması gereken özelliktir
    • accounting equation bunun bir örneğidir; iş paydaşları başka koşullar da tanımlayabilir
  • Invariant'ları zorunlu kılma yöntemleri birbirini tamamlar
    • oluşturma aşamasında yalnızca geçerli nesnelerin yaratılacağı şekilde tasarlanır
    • çalışma anında assertion, test ve property-based testing ile doğrulanır
    • saklanan veriler reconciliation job veya nightly check ile sonradan analiz edilir
  • Dış dünya ile etkileşen işlemler race condition'dan kaçınmalıdır
    • dış çağrı yapıldıktan sonra yetersiz bakiye fark edilmesi ya da aynı paranın iki kez harcanması engellenmelidir
  • Funds reservation veya hold-and-release, dış etkileşimden önce belirli bir işlem için fon ayırma desenidir
    • başarılı olursa reservation settle edilir ve işleme devam edilir
    • başarısız olursa release edilerek available balance'a geri döner
  • Bu desen, total balance ile available balance'ı ayırır
    • available = total - reserved
    • bakiye kontrolü ve yeni reservation, available balance üzerinden yapılır
  • Nihai tutar, önceden yapılan tahminden farklı olabilir
    • ücretler veya kur değişirse tahmini tutar rezerve edilir, gerçek tutar settle edildikten sonra kalan kısım release edilir
  • Reservation mutlaka settle veya release edilmelidir
    • sahipsiz reservation'lar kullanıcı fonlarını kilitler ama para kaybettirmez veya yaratmaz
    • expiry ya da timeout bir güvenlik ağı olabilir ama zorunlu değildir
  • Bakiye kontrolü ile reservation kaydı linearizable olmalıdır
    • stale read durumunda iki işlem de kontrolden geçip aynı fonu dayanak alabilir

Overdraft ve idempotency

  • Overdraft, hesap bakiyesinin negatife düşmesi durumudur
  • Kasıtlı overdraft, limiti ve faizi olan bir kredi ürünüdür ve genelde ayrı bir overdraft hesabı olarak modellenir
  • İstenmeyen overdraft, politika gereği yasak olsa da ortaya çıkabilir
    • settlement, reservation tahmininden daha büyük gelebilir veya reversal, fonlar çoktan çıktıktan sonra gelebilir
    • funds reservation bu pencereyi daraltır ama tamamen ortadan kaldıramaz
  • “Yasak” ile “ifade edilemez” aynı şey değildir
    • negatif bakiyeyi unsigned integer veya CHECK (balance >= 0) ile ifade edilemez hale getirmek, gerçekte negatif bakiye kabul etmek gerektiğinde crash, sıfıra zorlama veya hatalı işleme yol açabilir
    • negatif bakiyeyi 0'a zorlamak para yaratır
  • Overdraft tespit edildiğinde bu bir inceleme sinyali olarak görülmeli; future deposit ve netting, geri ödeme talebi veya expense/loss hesabına write-off gibi yöntemlerle açıkça tahsil edilmeli ya da işlenmelidir
  • Dağıtık sistemlerde exactly-once delivery garanti edilemez; bu yüzden retry gerekir ve retry mükerrer teslimata yol açabilir
  • Idempotency, aynı mesaj iki kez gelse bile işlemenin yalnızca bir kez etkili olmasını sağlayan özelliktir
    • açık bir idempotency key, payload tabanlı deduplication'a göre genelde daha basit ve güvenlidir
    • key belirli bir operation ve client kapsamıyla sınırlandırılmalıdır
    • hatanın yeniden oynatılıp oynatılmayacağına yoksa yeniden işlenip işlenmeyeceğine karar verilmelidir; kalıcı hatalarda olduğu gibi yeniden oynatmak çoğu zaman daha basittir
    • mükerrer çağrının payload'ının orijinaliyle aynı olup olmadığını doğrulamak iyi bir pratiktir, ancak uygulama karmaşıklığı ve esneklik maliyeti getirir
    • büyük ölçekte milyarlarca isteğin deduplication'ı ve eşzamanlı erişimde atomic barrier gerekir
    • 24 saat gibi bir idempotency window uygulamayı basitleştirir ama doğruluk açısından bedeli yüksektir
    • retry testleri ve sıra dışı gelen retry'ların ele alınması da gerekir

Yeniden başlatılabilir akışlar

  • Para akışları birden çok adıma yayılır; adımların arasında herhangi bir yerde sürecin durabileceği varsayılmalıdır
  • Full resumability, yarım kalmış bir akışın her zaman kurtarılabilir bir durumda olmasını sağlayan tasarımdır
  • İlerleme durumu bellekte değil, kalıcı depoda tutulmalıdır
    • akış açık bir state machine olarak modellenmeli ve her adımın tamamlanması, bir sonraki adım başlamadan önce commit edilmelidir
  • Yarım kalmış akışları yeniden iten bağımsız bir driver gerekir
    • scheduler, worker veya poller, orchestrator crash ettikten sonra da incomplete flow'ları işlemeye devam etmelidir
  • Devam ettirme sırasında kısmen gerçekleşmiş adımlar yeniden çalıştırılabileceği için her adım idempotent olmalıdır
  • Dış etkiler rollback edilemez
    • dış dünya çağrıldıktan sonra hiç çağrılmamış duruma geri dönülemez
    • tamamlanana kadar ileri doğru ilerlenmeli ya da sonraki adım kalıcı olarak başarısız olursa saga pattern'de olduğu gibi compensating action posting edilmelidir
  • Temporal, Camunda, Workflows4s, AWS Step Functions gibi durable-execution engine'ler kullanılabilir veya özel bir persistent state machine oluşturulabilir

Harici API tüketimi

  • Ödeme sağlayıcısı, custodian, blockchain node, KYC vendor gibi harici API’ler; kodlarını, kalitelerini ve çalışma sürelerini kontrol edemediğiniz için savunmacı şekilde ele alınmalıdır
  • Şemaya güvenilmemelidir
    • Alanlar eksik olabilir, tipler değişebilir, beklenmedik null değerleri ortaya çıkabilir
    • Kritik kısımlar sınırda doğrulanmalı ve beklenmedik veri durumunda belirgin biçimde başarısız olunmalıdır
    • Gerekli olmayan kısımları da doğrulamak, üçüncü tarafın sözleşme ihlali yüzünden gereksiz kesintilere yol açabilir
  • Harici API’lerde URL içinde token taşınması, hassasiyet kaybı, anlamıyla uyuşmayan HTTP code’ları, 200 içindeki hata gövdesi, tutarsız pagination ve özel tarih formatları gibi durumlar fazlasıyla görülebilir
  • Her çağrı başarısız olabilir; bu yüzden timeout ve retry gereklidir
  • Circuit breaker çoğunlukla aşırı yüklü sunuculara karşı bir nezakettir ve istemci karmaşıklığını artırır
    • Ancak latency, thread ve connection gibi sınırlı kaynakları korumak için gerekli olabilir
  • Rate limit ve quota için, beklenen çağrı hacmi ile sağlayıcının limitleri önceden hesaplanarak karşılaştırılmalıdır
  • Tüm request ve response’lar yapılandırılmış ve sorgulanabilir biçimde saklanırsa; inceleme, audit trail, sağlayıcı davranışıyla ilgili anlaşmazlıklarda kanıt ve hata sonrası yeniden işleme verisi sağlar
  • Kritik alanlarda sağlayıcı yedekliliği değerlendirilebilir
    • Örneğin iki blockchain node ile veri doğrulama, yedek banka partneri, crypto custodian veya KYC vendor kullanımı mümkündür
    • Geliştirme, ücret ve karmaşıklık maliyeti çok yüksektir
  • Sandbox production’dan ciddi biçimde farklı olabilir; bu nedenle production testleri için canary release veya etkisi düşük kontrollü kullanım hazırlanmalıdır

Webhook işleme

  • Webhook’lar harici sistem sinyallerini almanın yaygın bir yoludur, ancak güvenli şekilde işlemek kolay değildir
  • Sıralamaya güvenilmemelidir
    • Mesajlar out-of-order gelebilir veya stale data içerebilir
    • Az önce gelen webhook’un en güncel gerçek olduğunu varsayıp durumu onunla ezmemek gerekir
  • Geçerliliğe güvenilmemelidir
    • Webhook’lar issuer’ın başka alt sistemlerinden gelir ve stale ya da hatalı dönüştürülmüş veri içerebilir
    • Webhook gövdesini yalnızca bir trigger olarak kullanıp authoritative state’i API üzerinden sorgulamak daha iyi bir yaklaşımdır
    • API de eventually consistent olabilir; bu yüzden hemen sorgulandığında önceki durumu döndürebilir ve retry gerekebilir
  • Teslimata güvenilmemelidir
    • Issuer güçlü bir redelivery policy vaat etse bile webhook’lar er ya da geç kaybolur
    • Reconciliation gibi bağımsız süreçler veri bütünlüğünü tamamlamalıdır
  • Tek teslimata da güvenilmemelidir
    • Aynı webhook birden fazla kez gönderilir ve işleme idempotent olmalıdır
  • Hızla acknowledge edilmeli ve asenkron işlenmelidir
    • Raw event durable store’a kaydedildikten sonra hemen 2xx döndürülür, gerçek iş ise asenkron yapılır
  • Raw payload olduğu gibi saklanmalıdır
    • Güvenilir işleme, audit trail ve hata sonrası yeniden işleme için gereklidir
  • Çağıran taraf doğrulanmalıdır
    • Genellikle issuer payload signature ekler; alıcı da shared secret ile HMAC ya da public key tabanlı asimetrik imzayla doğrulama yapar
    • İmza doğrulaması, yeniden serileştirilmiş payload üzerinde değil, alınan raw bytes üzerinde yapılmalıdır
  • Webhook’lar, ne olduğunun gerçeği değil, bir şey olduğuna dair bir hint olarak görülmelidir

Güvenilir bildirimler: Outbox ve CDC

  • Sistem değişiklikleri Kafka event’i, webhook çağrısı gibi harici kanallarla güvenilir biçimde bildirilecekse transactionality bir sorun haline gelir
  • Publish başarılı olmuşken ağ sorunu nedeniyle yanıt alınamayıp sistem durumu rollback edilebilir ya da state change commit edilmişken publish başarısız olabilir
  • Ders kitabı cevabı 2-phase commit veya distributed transaction’dır; ancak karmaşıklık ve yeniden kullanım için standardizasyon zorluğu nedeniyle nadiren kullanılır
  • Pratikte birden fazla seçenek vardır
    • Outbox pattern: Durum değişikliğiyle birlikte publishing intent, özel bir store’a transactionally yazılır ve daha sonra başarılı olana kadar işlenir
    • Change Data Capture: Veritabanının write-ahead ya da replication log’u okunarak commit edilmiş değişiklikler bir event stream’e dönüştürülür
    • Debezium ve AWS DMS, CDC sağlar
    • CDC, table row biçiminde raw event yaydığı için iç schema’nın sızmasını önlemek adına sonradan işleme gerekebilir
    • Listen-to-yourself yaklaşımında önce event publish edilir, sonra sistem kendi durumunu bu event’ten yeniden kurar
    • Event sourcing’de event log zaten DB’dedir; bu yüzden publish işlemi oradan yapılabilir
  • Hangi mekanizma seçilirse seçilsin, teslimat at-least-once olur
    • Relay veya connector, publish sonrasında ama kayıt öncesinde crash ederse yeniden başlatıldığında aynı veriyi tekrar gönderebilir
    • Consumer, kararlı bir event id ile deduplicate etmeli ve idempotent çalışmalıdır

Reconciliation

  • Harici veriye bağımlı sistemler, iki sistemin durumunun birbirinden sapmasına yol açan data drift sorununa açıktır
    • Webhook kaçırılabilir ya da ledger’da bir transaction posting edilmişken external provider sistemine yansımamış olabilir
  • Reconciliation, iki sistemi birbirine uydurma sürecidir
    • Pratikte ledger, payment processor ve banka gibi üçten fazla sistem de olabilir
  • Cadence; bağlama ve kısıtlara göre saatlik, günlük, aylık veya yıllık olabilir
  • Drift yalnızca eksik veri olmayabilir; aynı transaction için tutarın farklı olması gibi daha karmaşık farklar da görülebilir
  • Zamanlama da önemlidir
    • Settlement T+3 ise, kayıt 3 gün boyunca unreconciled durumda kalabilir; gereksiz alert’leri önlemek için bu durum sürece yansıtılmalıdır
  • Matching algorithm temel zorluktur
    • Genellikle external provider id’nin içeride saklanması eşleştirmeyi basitleştirir
    • Yoksa amount ve time temelli heuristic gerekebilir
  • One-to-many reconciliation da gerekebilir
    • Tek bir settlement transfer birden fazla transaction’ı kapsayabilir
  • Farklılıklar, reconciliation tutsun diye basitçe overwrite edilmemelidir
    • Nedenin anlaşılması ve düzeltilmesi için correction record, webhook verisinin yeniden işlenmesi gibi birinci sınıf destekler gerekir

Kontrol ve erişim

  • Para sistemlerinde yalnızca verinin değil, kimin hangi eylemi yapabildiğinin de kontrol edilmesi ve sonradan prosedürlere uyulduğunun kanıtlanabilmesi gerekir
  • Segregation of duties, tek bir kişinin tüm süreci sahiplenmesini engelleyen bir kontroldür
  • Four-eyes, maker-checker ve dual control; belirli bir action uygulanmadan önce ikinci bir kişinin onay vermesini gerektiren yaklaşımlardır
  • Bunlar; büyük hacimli veya manuel withdrawal, manuel ledger düzeltmesi, treasury ve cold-wallet transferleri, fee schedule ya da limit değişiklikleri gibi fonları hareket ettirebilen veya yanlış gösterebilen eylemlere uygulanır
  • Aynı kontroller mühendislik için de geçerlidir
    • Code merge, production deploy ve infrastructure change; para sistemlerinde hassas action’lar olduğu için review ve approval gerektirir
  • Approval’ın kendisi de trail’in parçasıdır
    • Kontrolün kanıtlanabilmesi için kimin talep ettiği, kimin onay verdiği ve bu iki kişinin farklı olup olmadığı kaydedilmelidir
  • Acil durumlar için açıkça tanımlanmış ve güçlü biçimde denetlenen bir break-glass yolu gerekir
  • Access control, sistem durumunun bir parçasıdır ve zaman içinde değişir
    • Hem insanlara hem de servislere least privilege verilmelidir
    • Kişi bazlı grant yerine RBAC tercih edilirse gözden geçirme kolaylaşır
    • Capability grant ve revoke işlemleri de hassas event’lerdir; neyin, kim tarafından ve neden değiştirildiği kaydedilmelidir
    • Zamanlanmış access review ile eskiyen veya hatalı hale gelen permission drift yakalanmalıdır

SDLC değişiklik takibi

  • Regülasyona tabi ortamlarda kodun production'a ulaşma süreci denetlenebilir olmalıdır
  • source control, değişikliklerin kaydıdır
    • commit history, tüm değişiklikleri yazara atfeder ve review ile bağlı ticket üzerinden gerekçeyle ilişkilendirir
    • signed commit, protected branch ve paylaşılan geçmişte force-push yasağı ile korunmalıdır
  • review ve pipeline zorunlu olmalıdır
    • required review, status check ve main branch'e doğrudan push yasağı önemlidir
  • deployment izlenebilir olmalıdır
    • Hangi version'ın çalıştığı, kimin ne zaman release ettiği yeniden oluşturulabilmelidir; böylece incident, buna neden olan değişiklikle ilişkilendirilebilir

Test stratejisi

  • Para sistemlerinde operation sequence alanı büyüktür ve ilginç hatalar kombinasyonlardan çıktığı için test özellikle önemlidir
  • Property-based testing, belirli bir çıktıdan ziyade herhangi bir girdide doğru olması gereken bir property'yi doğrular
    • invariant'lar ve money math için çok uygundur
  • Operation sequence üretirken yalnızca sonda değil, her adımın ardından invariant'lar kontrol edilmelidir
    • Bunu elle büyük ölçekte yapmak zor olduğundan, assertion'ları otomatik enjekte eden bir testing harness gerekir
  • Generative idempotency testing, dış dünyaya dokunan her operation'ın ikinci çağrıda etkisiz kaldığını doğrular
  • Crash and resume injection, uzun bir akışın herhangi iki adım arasında çökse bile toparlanabildiğini doğrular
  • Round-trip testing, encode/decode, serialize/deserialize, convert/convert back sonrasında başlangıç noktasına dönülüp dönülmediğini ya da bilinen tolerance içinde kalınıp kalınmadığını kontrol eder
    • Money ve currency type sınırlarındaki hassasiyet kaybını ve serialization bug'larını yakalamanın hızlı bir yoludur
  • Golden testing, fee breakdown, statement ve report gibi hesaplama sonuçlarını kaydedilmiş beklenen sonuçlarla karşılaştırarak istenmeyen diff'leri ortaya çıkarır
  • Backward-compatibility testing, eski gerçek formatlı payload corpus'unu korur ve mevcut kodun hâlâ deserialize ve project işlemlerini doğru yapıp yapmadığını doğrular
  • Production testing, sandbox production'dan çok farklı olduğunda gerekli olabilir
    • canary release, blast radius'u küçük controlled rollout ve küçük gerçek tutarların sürekli akıtıldığı synthetic transaction bunun örnekleridir
    • production test, gerçek para hareket ettirdiği için ledger, reconciliation ve audit trail süreçlerinden aynı şekilde geçmeli; normal correction/reversal yollarıyla temizlenmelidir

Alan terimleri ve referanslar

  • Fintech'e girişte bazen koddan çok vocabulary ve concept'ler daha zor olabilir; bu yüzden temel terimler ayrı olarak derlenmiştir
  • Muhasebe ve ledger alanında ledger, general ledger ve sub-ledger, debit/credit, posting, chart of accounts, receivable/payable, IOU, accrual vs cash basis, trial balance, suspense/clearing account, write-off, commingling, reconciliation break yer alır
  • Money ve FX alanında Money type, minor units, basis point, notional, fiat vs crypto, stablecoin, pegged/wrapped/bridged, bid/ask/spread, mid-market rate, reference rate, mark-to-market yer alır
  • İşlem ve settlement alanında value date, booking date, settlement date, T+X, clearing vs settlement, cut-off time, float, netting, backdating, reversal/correction yer alır
  • Payments, cards, markets, crypto ve compliance terimleri de ayrıca derlenmiştir
    • PSP, omnibus account, FBO account, chargeback, issuer/acquirer, authorization vs capture
    • order book, market vs limit order, maker/taker, slippage, liquidity, derivative, futures, perpetual, liquidation
    • custody, hot/cold wallet, private key, multisig, MPC, gas, confirmation/finality, reorg, UTXO vs account model
    • KYC, AML/CFT, sanctions screening, PEP, SoF/SoW, Travel Rule, VASP, MiCA, least privilege, RBAC, audit trail
  • Referanslar muhasebe ve ledger, payments ve cards, markets ve trading, crypto, engineering, KYC ve AML olarak ayrılmıştır

Üç end-to-end örnek

  • Kripto çekimi

    • Kullanıcının 0,5 ETH’yi harici bir adrese çektiği akıştır
    • İstek, yinelenen gönderimlerin yalnızca tek bir çekim oluşturmasını sağlayan bir idempotency key içerir
    • 0,5 ETH ve beklenen network fee, available balance üzerinden rezerve edilir
    • Compliance gate; yaptırımları, AML’yi ve hedef adresi kontrol eder; harici çağrılar ve manuel inceleme nedeniyle günlerce beklemede kalabilir
    • On-chain broadcast idempotent olmalıdır; çökme sonrası ikinci bir broadcast yapmak yerine chain yeniden kontrol edilmelidir
    • Yeterli confirmation sonrasında ledger’a user account debit, external on-chain account credit, network fee expense ve service fee revenue için posting yapılır
    • Nightly job, ledger ile chain’deki gerçek durumu reconcile eder
  • Kartla para yatırma

    • PSP üzerinden kartla yükleme akışıdır
    • Kullanıcı tutarı ve kart bilgilerini gönderir, ardından PSP’de idempotency key ile bir deposit transaction açılır
    • Authorization yalnızca bir hold oluşturur; para henüz şirketin olmadığı için user balance credit edilmez
    • captured webhook’u raw bytes signature doğrulaması yapar, raw payload’u kaydeder, hızlı bir 2xx yanıtı verir ve ardından asenkron olarak işlenir
    • Webhook yalnızca bir trigger’dır; bu yüzden authoritative state, PSP API üzerinden sorgulanır
    • Captured but not settled durumu, clearing account üzerinden posting yapılarak işlenir; settlement ise T+X sonrasında batch halinde gelebilir
    • Chargeback, orijinali değiştirmek yerine bağlı bir compensating entry ile işlenir
  • Cashback’li uygulama içi dönüşüm

    • 1.000 EUR’nun USDC’ye çevrildiği ve promosyon amaçlı cashback verildiği akıştır
    • EUR→USDC quote, USDC→EUR’nun tersi değildir; yönsel bir kurdur
    • EUR ve USDC birbirine eklenmez; USDC, (network, contract address) ile tanımlanır ve pegged fiat ile aynı şey değildir
    • Hesaplama, tam hassasiyeti korur ve yalnızca sınırda, açıkça tanımlanmış stratejiyle bir kez yuvarlanır
    • Spread, revenue account’a açıkça booking edilmelidir; rounding residual içinde kaybolmamalıdır
    • Cashback, balance’a ücretsiz bir artış değildir; company promotional/expense account’tan user balance’a aktarılan gerçek paradır
    • Sonucun publish edilmesi, outbox, CDC, event log gibi mekanizmalarla reliable delivery sağlar; downstream consumer ise stable event id ile dedupe yapar

1 yorum

 
GN⁺ 4 시간 전
Hacker News yorumları
  • Göz attım; bu el kitabının yüzeysel olduğunu ve bazı alanlarda kötü tavsiyeye yaklaştığını düşünüyorum.
    Örneğin tutarların tamsayı olmayan bir biçimde saklandığını görsem çığlık atarak kaçarım. Rust’ın decimal türünün JSON kayan noktalı sayı olarak ifade edilmesi gibi durumlardan dolayı. Çok güçlü bir neden yoksa her zaman tamsayı olmalı; dışa aktarılan görünüm ise ister tuhaf bir bit kodlama formatı olsun, ne olursa olsun olabilir.
    Döviz kurları da tek bir zaman noktasındaki kurla çözülebilecek bir mesele değil. Alıcıya göre zaman noktasındaki kur, satıcıya göre zaman noktasındaki kur, mutabakat, mutabakat toleransı, üzerinde uzlaşılmış kesin zaman damgası gibi şeylerin hepsi etkili olur.
    Değişmezlik nedeniyle parayla ilgilenilen her yerde event sourcing kullanmak istersiniz. Nihai olarak düzenlenmiş akış A -> B -> E gibi görünebilir; ama gerçek akış A0 -> Edit(A0, A) -> B -> C -> D -> Rollback(B) -> E olabilir.
    Sonuçta Fintech de tek tip Fintech değil. Bazı yerlerde para yük gibi ele alınıyordu; bazı yerlerde ise para her şeyin merkezindeydi.

    • Tamsayı/kayan noktalı sayı meselesiyle tam olarak neyi kastettiğinizi anlamadım. Yazıda pratik kural olarak kayan noktalı sayı kullanmayın deniyor; bunun neredeyse her zaman iyi bir fikir olmadığı ve öngörülemez hassasiyet kayıplarına yol açtığı açıklanıyor; birçok yerde de tamsayı veya BigDecimal türleri öneriliyor. Rasyonel sayılara kadar mı uzanıyorsunuz, merak ettim.
      Döviz konusunda da el kitabındaki “canonical rate diye bir şey yoktur” ifadesini güçlendiriyor gibi görünüyor. Üstelik yazı kesinleşme sonrasındaki kayıtlarla ilgileniyor; sizin bahsettiğiniz şey ise kesinleşmenin nasıl yapılacağı gibi duruyor. Ayrı bir hedef için geçerli bir nüans olabilir, ama eksik ya da yanlış olduğuna dair kanıt gibi görünmüyor.
      Değişmezlik kısmında da yazı aynı noktayı söylüyor gibi. Farkın ne olduğunu anlamadım.
    • Bu, sorunu fazla abartmak. Finansın birçok alanı double ile gayet iyi çalışır.
      Faiz oranı yolları üzerinde Monte Carlo opsiyon fiyatlaması hesaplıyor ve duration, convexity, vega gibi risk metrikleriyle ilgileniyorsanız yuvarlama kuralının ne olduğunu kimse umursamaz. double yeterlidir. exp(-rt)cashflow ya da normal kümülatif dağılım fonksiyonunu nasıl tamsayıya zorlayacaksınız?
      Tamsayının doğru olduğu alanlar da var. Ama bu evrensel bir ilke değil; doğru mühendislik tercihini yapmak gerekir.
    • Benim de ilk gözüme çarpan kısım buydu ve tüm wiki’den şüphe etmeme neden oldu. Parayı saklamanın tek doğru yolu, söylendiği gibi tamsayıdır[1]; bunun açıkça belirtilmesi gerekirdi.
      Kullandığınız ortam destekliyorsa sabit noktalı sayı da kullanabilirsiniz, ama teknik olarak bu hâlâ tamsayıdır.
    • Gereken her şeyi yalnızca tamsayılarla yapamazsınız. Sentten daha küçük değerleri göstermeniz veya hesaplamanız gereken zamanlar olur; bazı yerlerde çoğu durumda kayan nokta hatalarına karşı güvenli BigDecimal gibi bir şeye ihtiyaç duyulur.
      Gösterim için decimal değer döndürmek güvenlidir.
    • JSON’da kayan noktalı sayı değil, sayı vardır. Ayrıştırıldıktan sonra nasıl kullanıldığı spesifikasyonun parçası değildir.
      Tutarları tamsayı olarak saklayan bir sistemden kaçmak istemeniz iyi. O zaman muhtemelen aynı sistemde çalışmayız. Günümüzde ben de çoğu zaman tutarları tamsayı olarak ele alan sistemlerden kaçmak istiyorum. Yalnızca deneyimli finans programcılarının dokunduğu ideal bir kod tabanıysa iyi işleyebilir; ama bu tür sistemler genellikle aşırı dışlayıcı ya da kırılgan hâle gelme riski taşır.
  • Para tutarlarını ifade ederken minor-unit precision stratejisini düşünenlere tavsiyem: yapmayın. En azından değişim/API veri biçimi olarak kullanmayın.
    Hızlı tamsayı işlemleri, toplama ve çıkarmada yuvarlama sorunu olmaması gibi nedenlerle akıllıca görünebilir; ancak belirli bir para birimi için örtük olarak varsaydığınız basamak sayısı farklı olan bir partnerle çalıştığınız anda çok fena ısırabilir. Özellikle stablecoin’lerde, temsil ettikleri itibari paradan farklı örtük ondalık basamak sayısı olması sık görüldüğü için bu daha da önemli.
    JSON tabanlı API’lerde tutarları string türüyle ifade etmeyi de değerlendirmeye değer. JSON ondalık hassasiyeti belirtmediğinden, sizin ve tüm kullanıcılarınızın/tedarikçilerinizin parser/serializer’larının içeride kayan nokta üzerinden geçip hassasiyet kaybetmediğini her zaman doğrulamanız gerekir. Bu hızla çirkinleşebilir ve string’ler kavramsal olarak daha az temiz görünebilir; ama bu sorunu tamamen baypas eder. Bazıları buna antipattern [1] diyebilir; ancak kullanıcıların ya da hissedarların omuzlarında ideolojik saflık uğruna bu kavgaya girmek istemem.
    [1] https://blog.json-everything.net/posts/numbers-are-numbers-n...

    • Burada gerçekten tek doğru çözüm, mantis ve üssü iki ayrı tamsayı olarak göndermektir. İstediğiniz hesaplamaya göre üsler arasında dönüşüm yapmak önemsizdir, istediğiniz kadar kesin hale getirilebilir ve belirsiz değildir.
      Yüksek frekanslı işlem alanında, belirli bir {slice} için önceden tutarlı bir üs sabitleyebiliyorsanız aktarım alanından tasarruf edebilirsiniz. Örneğin ürün/tick size/varlık sınıfı/borsa/feed/sunucu gibi bir kapsamda yalnızca mantisi gönderip istemcinin hardcoded üssü kullanması gibi.
      Ama benzer alanlarda bile iletilen veriye fazladan bir uint32 üssü koymaya çoğu zaman değer. Böylece daha sonra değiştirebilirsiniz ve “şimdilik sadece cent gerekiyor” gibi erken tasarım kararları sizi kilitlemez. Örneğin bir anda bitcoin fiyatını tam hassasiyetle desteklemeniz gerekebilir. Sabit üssü ayarlamak istediğinizde kırıcı bir değişikliği koordine etmek zorunda kalmazsanız kullanıcılarınız minnettar olur.
    • C++ ile yüksek frekanslı/düşük gecikmeli işlem sistemleri geliştirip buna tarayıcı tabanlı, yani JavaScript yönetim frontend’i bağlamış biri olarak söylüyorum: her yerde tamsayı cent kullanın, yeter. Fiilen sektör standardı bu ve iyi çalışıyor. Diğer seçeneklerin hepsi daha kötü tavizler.
    • Bunun neden sorun olduğunu anlamıyorum. Karşı API ile etkileşirken değerleri dönüştürürsünüz, olur biter.
    • O yazının vardığı sonuç “parser’ları düzeltmek gerekir. JSON sayılarından istediğiniz herhangi bir sayı türünü, herhangi bir hassasiyetle çıkarabilmelisiniz” ise, bunun en iyi ihtimalle aşırı ve gerçekçi olmadığına tamamen katılıyorum.
      “Herhangi bir” ölçütü makul değil. Pratikte kanıtlanabilir bir değer sunmadan sınırsız mühendislik bütçesi talep edebilecek, ulaşılamaz bir standart.
      Standart eksikliğini saptamak, gerçek parser’ların nasıl davrandığını anlatmak, boşlukları ve karşılanmamış kullanım senaryolarını tartışmak iyi. Daha makul bir standarda ihtiyaç olduğunu önermek de iyi. Ama kimsenin gerçekte ihtiyaç duymadığı, anlamı belirsiz ve pratikte ulaşılması mümkün olmayan “tüm olasılıkları” herkesin desteklemesini istemek iyi bir fikir değil.
    • Bunun yerine ne önerdiğini merak ediyorum. Standart kayan nokta float/double, minor unit’in binde biri ya da daha küçük birimlerde sabit nokta aritmetiği, keyfi hassasiyetli ondalık sayılar, yoksa bambaşka bir yaklaşım mı?
  • Bir programcı olarak Fintech programcılarının farklı deneyim ve bakış açılarından konuştuklarını görünce, iyi programlama denen şeyin aslında ne olduğunu merak ediyorum.
    xlii’nin para tutarlarını kayan nokta olarak saklamayın demesi klasik IEEE 754 sorunu. Finansal izleme için değişmez loglar ya da olay tabanlı kayıtlar doğru yaklaşım; ama çevredeki tüm servisleri event sourcing ile yapmak gerektiğini düşünmüyorum. Defter, mutabakat, emir, gerçekleşen işlem gibi çekirdek mantığa uygulamak bile yeterli bence. xlii’nin yazısına bakınca bu, ancak modelleme başarılı olduğunda hayata geçirilebilecek bir teknik gibi görünüyor.
    lxgr’nin söylediği şey minor-unit sorununa değiniyor. JSON sayıları dil ya da parser tarafından kayan nokta olarak parse edilirse hassasiyet kaybı olabilir. Genelde değerle birlikte ayrı bir ondalık basamak alanı gönderilir. Ancak yüksek frekanslı işlemlerde bu overhead’in kendisinin bile çok pahalı olduğu için böyle yapılmadığını duydum.
    antonymoose’un söylediği şey birçok kitapta anlatılanlarla örtüşüyor. Bu yüzden döviz ya da API bağlamlarında bu tür tasarım yaygın. Biraz protokol tasarımı gibi de hissettiriyor.
    Toparlarsak herkes kendi alanı içinde haklı. xlii gibi birinin kıdemli programcı olmasını isterdim diye düşünüyorum; ama aynı zamanda ben böyle karmaşık bir sistemi tasarlayamazdım gibi de geliyor. Bu anlamda herkesin söylediği geçerli ve görüşlerin alana göre ayrışması ilginç. Acaba uzmanlık denen şey bu mu diye düşünüyorum.
    Böyle şeyleri görünce bir programcının hangi deneyimlerden geldiğini kabaca çıkarabiliyorsunuz. Bazen programlama doğru cevabı bulmak değil, bir dünya görüşü seçmek gibi geliyor.
    HN’de programcıların kendi alanlarını nasıl modellediğini görmek her zaman ilginç. Bazen profillerine tıklıyorum ve bir gün işime yarayabilir diye alan bilgilerini kişisel wikime ekliyorum.

    • O wiki hakkında daha fazlasını duymak isterim.
  • Güzel. Bu kitapta başka yerlerde de bulunabilecek çok sayıda iyi bilgi zaten var; ama bunların bir araya getirilmiş olması bile epey pratik. Kleppmann’ın Designing Data-Intensive Applications kitabını şiddetle öneririm. 1. baskı da çok iyiydi, yakın zamanda 2. baskı çıktı.
    FinTech’te CTO olarak çalışıp tüm yazılım yığınını sıfırdan kurduğum oldu; kitaptaki dersler genel olarak doğru. “Genel olarak” diyorum çünkü her zaman olduğu gibi belirli projelerde “duruma bağlı” birçok şeyi hesaba katmak gerekir. Örneğin ben tüm durum hesaplama probleminden kaçınmak için event sourcing kullanmadım. Standart append-only denetim izi de yeterli olabilir.
    Tam olarak bir kez teslim garantisi veremezsiniz; ancak fiilen bir kez işleme kurabilirsiniz ve gerçekte istediğiniz şey de budur.
    Tüm istek ve yanıtları saklayın denmesi kesinlikle doğru. Sadece API tüketirken değil, dış dünyadan herhangi bir bilgi toplarken de böyle yapılmalı; mümkünse sınırlarınız içindeki tüm ara dönüşüm adımları da kaydedilmeli. İçerik adreslemeli bucket’lar ile ilişkisel tabloların birleşimi iyi çalışır.
    Ayrıca metin veri kökeni hakkında hiçbir şey söylemiyor. Bir tedarikçi gün ortasında bazı verileri güncellediyse ve bunu mutlaka bilmeniz gerekiyorsa ne yapacaksınız? Eski değerleri kullanan hesaplamayı tekrar çalıştırdığınızda aynı sonucu verecek şekilde, bu değişimi açıklayabilmeniz gerekir. Çözmesi özellikle zor bir problem değil; ama üzerinde düşünmek gerekir.

  • “Kötü tavsiye” demek epey nazik bir ifade. Açıkçası bu “el kitabının” büyük kısmını LLM yazmış gibi görünüyor
    Örneğin değişmezlik bölümünde şöyle bir cümle var: “PII’yi finansal veriden ayırmak, saklamanız gereken finansal geçmişi kaybetmeden silme hakkına saygı göstermenizi sağlar”
    Finans kuruluşlarında bunlar, bariz KYC/AML nedenleriyle birlikte hareket eder
    İlgili süre dolmadan önce müşteri adını, adresini vb. talep üzerine hemen silip yalnızca finansal veriyi bırakırsanız, yasal bir kurum suç takibi için verileri istemeye geldiğinde tüm kuruluş çok kötü bir gün geçirir
    Fintech’te çalışmak isteyen biri, bilinmeyen bir yargı alanındaki bilinmeyen bir kişinin yazdığı rastgele bir “el kitabına” güvenmemeli
    Fintech’te çalışan biri yalnızca işvereninin iç el kitabına/kılavuzlarına vb. göre çalışmalı. Bu tür belgeler, işverenin faaliyet gösterdiği yargı alanındaki yasalara ve raporlama gerekliliklerine uyması için şirket avukatları ve uyum sorumluları tarafından birlikte hazırlanmış olur

    • Yazının ilgili süre dolmadan önce müşteri adını ve adresini vb. talep üzerine hemen silmeyi nerede önerdiğini bilmiyorum
      Benim gördüğüm kadarıyla, sonunda silinmesi gereken PII ile muhasebe denklemine/değişmezlerine girdiği için fiilen kalıcı olarak saklamak isteyeceğiniz verileri ayırmayı öneriyor. Böylece ilgili kayıt saklama süresi geçtikten sonra ilkini silebilirsiniz
      Bilinmeyen bir yargı alanındaki bilinmeyen birinin yazdığı bir “el kitabına” güvenmemek gerektiği doğru. Ama oradaki fikirleri ve uygulamaları körü körüne yok saymak ya da kendi kuruluşunuzun dışına bakmamak da doğru değil. İdeal olarak onu gördükten sonra kendi bilginiz ve yerel düzenlemelerinizle karşılaştırıp uyarlamanız gerekir
      Yalnızca kusursuz ve hatasız kuruluşların olduğu bir dünyada, işverenin iç yönergelerini takip etme yaklaşımı makul görünür. Ama böyle konuşmalar olmadan o seviyeye nasıl ulaşılabilir?
  • Bu içeriğin çoğunun yalnızca Fintech’e değil, genel olarak yazılım mühendisliğine de uygulanabileceğini düşünüyorum
    Örneğin yeniden denemeler, idempotency, olay sırası gibi konuları ele alan kısımlar, para doğrudan işin içinde olmasa bile belirli bir doğruluk gerektiren her sisteme uygulanır. “İstediğin zaman yeniden deneyebilirsin” varsayımıyla yapılmış çok fazla sistem gördüm; oysa yeniden denemenin mümkün olması için en başta temiz biçimde başarısız olmak gerekir ve alt sistemin, benim düşündüğüm düzeyde idempotency sağlaması gerekir. Bu noktalar çoğu zaman gerçekten doğrulanmıyor

    • Katılıyorum. Defter işleme ve yuvarlama kısımlarını çıkarırsak, burada özel olarak yalnızca Fintech’e uygulanan neredeyse hiçbir şey yok; onlar da oldukça yüzeysel
      Bunun yerine hesap başına veritabanı gibi daha radikal bir yaklaşımı savunan bir yazı okumak isterdim. Fintech içinde kendine özgü ödünleşimleri olan şeylerden bahsediyorum
      Fintech mühendislerine veya kurucularına vermeyi en çok istediğim tavsiye, risk ve uyumu ilk günden ciddiye almalarıdır
      Finans sistemleri güven üzerine kuruludur. Riski kanıtlanabilir biçimde azaltamazsanız güveni kaybedersiniz; sonunda tüm işi kaybedersiniz
  • Kayan noktadan kaçının sözü doğru değil. Fintech’te 20 yıl çalıştım ve çoğunlukla double kullandık. Excel de double kullanır, frontend de double kullanacaktır ve tüm veritabanları double destekler. Standart kütüphaneler double ayrıştırmayı bilir, JSON da teoride olmasa bile pratikte double kullanır. Birçok ERP sistemi de double kullanır
    double ile para birimi ele alırken kilit nokta, toplam 15 basamak hassasiyet taşıyabildiğini akılda tutmaktır. Sayı 123456789.01 veya 123.456789 gibi bundan daha fazla basamak kullanmadığı sürece, finansal hesaplamalarda kusursuz ondalık hassasiyet elde edebilirsiniz. Her hesaplamadan sonra ve her karşılaştırmadan önce sonucu her zaman 15 basamak hassasiyet içine yuvarlamanız yeterli. Excel bunu yapar
    double’ın en büyük avantajı yaygın desteklenmesi ve sistem içinde farklı hassasiyetleri karıştırabilmenizdir. Uluslararası finans veya gelişmiş finansal ürünlerle uğraşırsanız bu olur. Bazı muhasebe işlemleri binde bir hassasiyet gerektirir, bazıları ise 0,25’in katlarına yuvarlanmalıdır. Sonunda temel aritmetiği kullanmayıp özel bir muhasebe matematiği kütüphanesi kullanacaksınız; o kütüphane de backend olarak kayan noktayı gayet iyi kullanabilir

  • Plaid bakiye kontrolü, yakında göndereceğiniz ACH çekiminin başarılı olacağını garanti etmez
    Bakiyenin bir milyon dolar olması fark etmez. ACH işlenmeden önce tüm para (a) havale ile çıkabilir, (b) dünkü ACH’ler, yani faturalar, otomatik ödemeler vb. ve çeklerle tahsil edilebilir, ya da (c) banka kartı/ATM’de harcanabilir
    Bazı Fintech’lerin bunu neden ele almadığını nasıl bildiğimi muhtemelen söylemesem daha iyi

    • İyi bir göstergedir ama kesinlikle garanti değildir. Bu kavramı anlamayan proje yöneticilerine bunu açıklamak zorunda kalmıştım
  • Sırf idempotency key bölümü bile okumaya değer. Çoğu geliştirici bu dersi zor yoldan öğrenir

    • Keşke finans sektörü, hâlâ kullanılan 60’lar ve 70’lerden kalma temel bankacılık sistemleri ile finansal iletişim protokolleri oluşturulurken bunu biliyor olsaydı
      Bunların çoğu idempotency bilgisinin yaygınlaşmasından önceye ait olduğu için, çoğu zaman küresel olarak benzersizmiş gibi görünen birkaç alanı birbirine ekleyerek zorla idempotency key üretirler. Sorun şu ki bu asla tamamen benzersiz değildir. Bazen perdenin arkasını görebiliyorsunuz; örneğin bir bankanın aynı tarihte aynı tutarı aynı alıcı hesaba transfer etmeye izin vermemesi buna bir örnektir
    • %100 katılıyorum. Daha ayrıntılı ele alınmayı da hak ediyor
      Idempotency’nin nasıl çalışması gerektiğini ve neden önemli olduğunu açıklamak için çok zaman harcadım. Çoğu ekip ihtiyacı anlıyor, ama çok az ekip bunu en baştan düşünmüş oluyor
    • Denetim izi için de aynı şey geçerli. İyi bir denetim izi acil durumda şirketi ve sizi kurtarabilir. Hata ayıklamada da faydalıdır ve son çare uyum veri kaynağı olarak da kullanılabilir
  • “Fintech” çok geniş bir alan ve Fintech denen şeylerin çoğu aslında iletişimdir. Şirketler arası, trader’lar arası, sistemler arası, defterler arası iletişimdir. Tüm sektöre uygulanabilecek “doğru” bir programlama biçimi yoktur. Çünkü eninde sonunda doğru biçim, iletişim kurduğunuz karşı tarafın anlayabildiği biçimdir
    Karşı taraf para birimini cent düzeyinde izliyorsa, siz daha yüksek hassasiyetle izlediğinizde yuvarlama uyuşmazlıkları doğar. Tersi durumda, siz cent düzeyindeyken karşı taraf 0,1 cent düzeyinde çalışıyorsa da aynı şey olur. Bu belgedeki diğer tavsiyelerin hepsine de böyle bakmak gerekir