Mimari
FinevoConnect YÖS, iki ayrı uygulama ile bir ortak veritabanından oluşur ve karşı tarafta bir banka/kurum (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/kurum. Her kutu bir görevi üstlenir; oklar da verinin hangi yönde aktığını gösterir. Public API ile Batch arasında veritabanının yanı sıra doğrudan bir senkron iç RPC hattı da vardır.
(tarayıcı / mobil)
apps/api · :8444
paylaşımlı DB
apps/batch · :8445
api-hhs · :8443
iç RPC (senkron) · rıza açma / iptal / callback / canlı okuma
İ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/kurumla 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 imzalı erişim token'ı) 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/kuruma sıfır bağlantı kurar
- Banka/Kurum 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/Kurumdaki onay tamamlanınca gelen geri dönüşü (callback — banka/kurum 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/Kurumla 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/Kuruma mTLS (iki tarafın da kimliğini sertifikayla kanıtladığı güvenli bağlantı) ve imzalı (JWS) istek atar
- Bankadan/Kurumdan 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/kurum 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/Kurumdan 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/kurum)
HHS, gerçek hayatta kullanıcının hesabının bulunduğu bankadır/kurumdur (standart adıyla ASPSP). Geliştirme ve testte gerçek bankaya/kuruma bağlanmak yerine api-hhs adlı bir simülatör kullanılır; bu simülatör tıpkı gerçek banka/kurum gibi davranır. Batch, bankaya/kuruma 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/kurum mesajın yolda değiştirilmediğinden emin olur. Banka/Kurum 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/kurumda verdiği onay (GKD — Güçlü Kimlik Doğrulama) tamamlanınca, banka/kurum bunu Public API'ye bir "callback" (geri arama) ile bildirir; yani "kullanıcı onayladı" haberini bize geri yollar.