Mimari
api-yos, iki ayrı uygulama ile bir ortak veritabanından oluşur ve karşı tarafta bir banka (HHS) ile konuşur. Kullanıcı bir şey isteyince (örneğin "bakiyem ne?") o istek birkaç durak arasında dolaşır. Aşağıda kim kiminle nasıl konuşuyor, adım adım ve sade dille anlatılıyor.
Kuşbakışı
Önce büyük resme bakalım. Soldan sağa doğru: kullanıcı, kullanıcının konuştuğu web servisi, ortak veritabanı, arka planda çalışan işçi ve en sağda banka. Her kutu bir görevi üstlenir; oklar da verinin hangi yönde aktığını gösterir.
(tarayıcı / mobil)
apps/api · :8444
paylaşımlı DB
apps/batch · :8445
api-hhs · :8443
İki uygulama, iki görev
Neden tek uygulama değil de iki tane? Çünkü iki iş çok farklı: biri kullanıcıya hızlı yanıt vermek zorunda, diğeri bankayla yavaş ve dikkatli konuşuyor. Bu ikisini ayırmak, birinin yavaşlığı diğerini yavaşlatmasın diye önemli. Aşağıda her uygulamanın ne yaptığı var.
Public API (apps/api)
Kullanıcının konuştuğu web servisi. Hızlı olması gerekir, o yüzden hep yakındaki veritabanından okur.
- Uygulama anahtarı (X-App-Key) + kullanıcı kimliği (userKey + customerNo) ile kaydeder, kullanıcıya bir JWT token (kimliği kanıtlayan dijital bilet) verir
- Hesap, kart, işlem ve ödeme uçlarını (endpoint) sunar — uygulamanın konuştuğu adresler
- Sadece MSSQL veritabanını okur-yazar; bankaya sıfır bağlantı kurar
- Banka işini Batch'e devreder: kimini "niyet kutusuna" (SyncIntent) not olarak yazar, kimini de Batch'e senkron iç çağrıyla (RPC) yaptırıp sonucu bekler
- Bankadaki onay tamamlanınca gelen geri dönüşü (callback — banka bize haber verir) karşılar; yetkilendirmeyi Batch'e senkron iç çağrıyla tamamlatır (token değişimi + hesap/kart çekimi aynı anda yapılır) ve ancak sonra kullanıcıya yanıt döner / onu yönlendirir
Batch İşçi (apps/batch)
Bankayla konuşan tek taraf. Arka planda çalışan bir işçi (Hangfire worker); kullanıcı onu doğrudan göremez.
- Dışarıya açık web servisi yoktur; yalnızca arka planda, kimseye görünmeden çalışır
- Niyet kutusundaki notları sırayla (ilk gelen ilk işlenir) alır ve yerine getirir
- Bankaya mTLS (iki tarafın da kimliğini sertifikayla kanıtladığı güvenli bağlantı) ve imzalı (JWS) istek atar
- Bankadan gelen hesap, bakiye, kart ve işlem verisini veritabanına yazar
- Belirli aralıklarla verileri otomatik tazeleyen periyodik işleri yürütür
Neden bu ayrım? (Clean Architecture)
Her uygulama, iç içe geçmiş katmanlara bölünmüştür. Bunu bir soğanın halkaları gibi düşünün: en dış halka HTTP isteğini veya işçinin tetiklendiği anı karşılar, en iç halka ise asıl iş kurallarını (para nasıl transfer edilir, rıza ne zaman geçerlidir) barındırır. Önemli kural şudur: içerideki katman dışarıyı bilmez. Yani iş kuralları, verinin hangi veritabanından geldiğini ya da hangi web çerçevesinin kullanıldığını umursamaz. Bunun faydası büyük: dış dünya değişse bile (veritabanı değişse, arayüz değişse) çekirdek kurallar aynı kalır ve kod rahatça test edilir.
| Katman | Proje | Ne yapar |
|---|---|---|
| Sunum | FinevoConnect.Yos.Api | Dış dünyanın kapısı: HTTP controller'ları, araya giren kontroller (middleware), giriş noktası |
| Uygulama | FinevoConnect.Yos.Application | İş akışları — her özellik için bir servis. Örneğin ödeme emri işleri PaymentOrderService içinde yaşar |
| Altyapı | FinevoConnect.Yos.Infrastructure | Dış dünyaya dokunan her şey: veritabanı erişimi, güvenlik, bağlantılar |
| Alan (Domain) | FinevoConnect.Yos.Shared.Domain | Varlıklar, iş kuralları ve sabitler — tüm gerçeğin tek kaynağı, en iç halka |
| Kalıcılık | FinevoConnect.Yos.Shared.Persistence | Veritabanı şeması (tabloların yapısı) — iki uygulama da aynı şemayı paylaşır |
Paylaşımlı köprüler
İki uygulama birbiriyle doğrudan telefonla konuşmaz; aralarındaki her mesajlaşma ortak veritabanı üzerinden olur. Aşağıdaki iki köprü, bu sessiz haberleşmenin nasıl güvenli ve güvenilir kaldığını anlatır.
SyncIntent (niyet kutusu)
API bir banka işi gerektiğinde, bu işi "niyet" olarak veritabanına yazar. Önemli olan, bu yazma işinin asıl veri değişikliğiyle aynı anda (aynı veritabanı işlemi/transaction içinde) olmasıdır — yani ya ikisi birden olur ya hiçbiri, arada kayıp yaşanmaz. Batch bu kutuyu gelme sırasına göre (FIFO — ilk giren ilk çıkar) okur, işi yapar ve "işlendi" diye işaretler. Her iş en az bir kez yapılır; aynı işin iki kez yapılması ise ayrıca engellenir. Örneğin ödeme emri iki kez işlenip para iki kez gitmez.
Paylaşımlı şifreleme anahtarı
Bankadan alınan erişim token'ları ve kullanıcının kişisel verileri (örneğin kimlik bilgisi) veritabanında açık değil, şifreli durur. Batch bu verileri yazarken şifreler, API okurken çözer. İkisinin de aynı kilidi açabilmesi için ortak bir anahtar halkasını ("yos-shared") paylaşırlar. Eğer iki taraf farklı isimde anahtar kullanırsa çözme işlemi bilerek başarısız olur — bu, veriyi yanlış elden korumak için konmuş bir güvenlik önlemidir.
Karşı taraf: HHS (banka)
HHS, gerçek hayatta kullanıcının hesabının bulunduğu bankadır (standart adıyla ASPSP). Geliştirme ve testte gerçek bankaya bağlanmak yerine api-hhs adlı bir simülatör kullanılır; bu simülatör tıpkı gerçek banka gibi davranır. Batch, bankaya mTLS (iki tarafın da sertifikayla kimliğini kanıtladığı bağlantı) ile bağlanır ve gönderdiği mesajların gövdesini JWS ile imzalar — böylece banka mesajın yolda değiştirilmediğinden emin olur. Banka da yanıtlarını aynı şekilde imzalar; imzasız ya da imzası doğrulanamayan bir yanıt gelirse Batch onu reddeder, çünkü sahte olabilir. Kullanıcının bankada verdiği onay (GKD — Güçlü Kimlik Doğrulama) tamamlanınca, banka bunu Public API'ye bir "callback" (geri arama) ile bildirir; yani "kullanıcı onayladı" haberini bize geri yollar.