Arka Plan İşleri (Batch)
Batch, bankayla konuşan tek uygulamadır. Hangfire adlı zamanlayıcıyla çalışır: kimi işleri düzenli aralıklarla, kimilerini de bir şey olduğu anda yapar. Dışarıya açık bir web servisi yoktur; bütün görevi niyet kutusundaki işleri yürütmek ve verileri güncel tutmaktır. Her işin bir hız sınırı ve yeniden deneme kuralı vardır — banka yorulmaz, iş kaybolmaz.
SyncIntentConsumerJob
Sistemin kalbi burası. API tarafı "şu iş yapılacak" diye niyet kutusuna ne bıraktıysa, bu iş onları sırayla ele alır: ilk verileri çekmek, durumu bankayla eşitlemek, rızayı iptal etmek. Kutuyu düzenli aralıklarla kontrol eder; ama yeni bir niyet düştüğünde beklemez, hemen işe koyulur. (Rıza açma ve yetkilendirme tamamlama ise ağırlıklı olarak senkron iç RPC ile yürür; niyet kutusu bunlarda yalnızca yedek yoldur.)
PeriodicResourceRefreshJob
Bağlı hesapların bakiyesini, işlem geçmişini ve kart bilgilerini kimse istemeden, arka planda kendi kendine tazeler. Amaç şu: kullanıcı uygulamayı açtığında veri zaten güncel olsun. Üç görevi (bakiye, kart, işlem) üç ayrı takvimle çalışır.
DecoupledGkdPollJob
Bazı onaylar bankanın kendi uygulamasından ya da SMS ile verilir; bu durumda banka bizi geri yönlendirmez. Bu iş, onay bekleyen bağlantıları ara ara yoklar; kullanıcı onayı verir vermez rızayı tamamlar.
ConsentTimeoutSweepJob
Kullanıcı onay ekranına gitti ama hiç onaylamadıysa o rıza yarım kalır. Bu iş, süresi geçen rızaları bulup kapatır; askıda kalmış onayları da fark edip durumu bankayla eşitler.
UndeliveredEventsPollJob
Banka normalde olan biteni bize anında bildirir. Ama bu kanal bir ara koparsa haberler kaçabilir. Bu iş, kaçan bildirimleri belli aralıklarla bankaya sorup toparlar — bir tür yedek güvence.
EventSubscriptionEnsureJob
Bankadan anlık bildirim alabilmek için önce "bana haber ver" aboneliğinin kurulu olması gerekir. Bu iş her saat başı kontrol eder: abonelik var mı, güncel mi? Yoksa kurar, bozulmuşsa düzeltir.
RecurringPaymentExecutionJob
Düzenli ödeme talimatlarını takip eder; günü gelen taksidi bankaya iletir. Böylece kullanıcının her ay elle ödeme yapması gerekmez.
ForwardDatedPaymentStatusSyncJob
İleri tarihli ödemeler için "günü geldi mi, gerçekleşti mi?" sorusunun cevabını bankadan alır ve kayıtları buna göre günceller.
Zamanlanmış işler (Hangfire recurring)
Hangfire panosunda (:8445/hangfire) görünen 10 kayıt. Cron ifadeleri UTC.PeriodicResourceRefreshJob üç ayrı metotla üç takvimde çalışır.
| İş | Cron | Sıklık | Görevi |
|---|---|---|---|
sync-intent-consumerSyncIntentConsumerJob.DrainDueAsync | */10 * * * * * | 10 saniye | API'nin niyet kutusuna bıraktığı işleri (rızayı iptal et, ilk verileri çek, durumu eşitle...) sırayla alır ve her birini ilgili işleyiciye dağıtır. Batch'i API'ye bağlayan ana köprü budur. Not: rıza oluşturma ve yetkilendirme tamamlama artık ağırlıklı olarak senkron iç RPC ile yürür; AuthorizationComplete niyet türü hâlâ vardır ama yalnızca senkron çağrı başarısız olursa devreye giren yedek yoldur. |
decoupled-gkd-pollDecoupledGkdPollJob.PollDueAsync | */30 * * * * * | 30 saniye | Banka uygulamasından ya da SMS ile verilen onayları yoklar; kullanıcı onaylamışsa akışı tamamlar. Bu yolda geri yönlendirme olmadığı için sormak bize düşer. |
consent-timeout-sweepConsentTimeoutSweepJob.SweepAsync | */5 * * * * | 5 dakika | Onay süresi dolmuş, yarım kalmış rızaları bulur ve "süresi doldu" olarak kapatır. Ortalıkta askıda rıza kalmaz. |
event-subscription-ensureEventSubscriptionEnsureJob.EnsureAsync | 0 * * * * | Saatlik | Bankadaki olay aboneliğimiz duruyor mu diye bakar; yoksa yeniden kurar. Abonelik olmazsa anlık bildirimler gelmez. |
forward-dated-status-syncForwardDatedPaymentStatusSyncJob.ExecuteDueAsync | 0 * * * * | Saatlik | İleri tarihli ödemelerin sonucunu (gerçekleşti mi, başarısız mı) bankadan öğrenip kayıtları günceller. |
periodic-balance-refreshPeriodicResourceRefreshJob.RefreshBalancesAsync | 0 * * * * | Saatlik | Bağlı hesapların bakiyelerini kendiliğinden tazeler. Sistem tetiklediği için PSU=H sayılır ve kotaya tabidir. |
periodic-card-refreshPeriodicResourceRefreshJob.RefreshCardsAsync | */45 * * * * | 45 dakika | Kart bilgilerini (limit, borç, işlemler) kendiliğinden tazeler (PSU=H). |
periodic-transaction-refreshPeriodicResourceRefreshJob.RefreshTransactionsAsync | 0 */6 * * * | 6 saatte bir | Hesapların işlem geçmişini kendiliğinden tazeler (PSU=H). |
recurring-payment-executionRecurringPaymentExecutionJob.ExecuteDueAsync | 0 * * * * | Saatlik | Günü gelen düzenli ödemeleri bankaya iletir; talimatın sıradaki taksidini çalıştırır. |
undelivered-events-pollUndeliveredEventsPollJob.PollAsync | */10 * * * * | 10 dakika | Bize ulaşamamış olay bildirimlerini bankadan sorup toplar. Anlık kanal koparsa devreye giren yedek güvence. |
?fresh=true ile E (anlık, kotasız); banka olay bildirimi tetiklerse O.Saati beklemeyen görev: canlı okuma (?fresh=true)
Buraya kadar anlatılanların hepsi bir takvime bağlıydı. Ama batch'in bir de saati beklemeyen görevi var. Kullanıcı "bana şu an bankadaki en güncel hâli göster" dediğinde — yani isteğe ?fresh=true eklendiğinde — API periyodik tazelemeyi beklemez: batch'e doğrudan, senkron bir iç çağrı yapar (/internal/live-query). Batch o an bankaya gider, taze veriyi çeker, veritabanına yazar ve cevabı hemen geri verir. Kullanıcı birkaç saniye bekler ama karşılığında dakikalar önceki değil, o anki veriyi görür.
Normal okuma
Veri doğrudan veritabanından gelir; çok hızlıdır. Arka plandaki periyodik işler veriyi zaten düzenli tazelediği için çoğu ekrana bu yeter.
Canlı okuma (fresh)
Kullanıcı istediği için yapılır; bankaya o an gidilir. Kullanıcı tetiklediğinden PSU=E sayılır ve kotaya takılmaz. Biraz daha yavaş, ama en güncel.
Banka ile güvenli konuşma
mTLS
Batch, bankaya kendi istemci sertifikasını sunar; iki taraf da birbirini doğrular. Sertifikalar sadece batch'te durur; artık batch imajının içine gömülüdür (Dockerfile COPY certs/…) — eski Dokploy bind mount kaldırıldığı için dışarıdan bağlanmaz.
İmzalı gövde (JWS)
Giden isteklerin gövdesi PS256 ile imzalanır (detached JWS). Banka yanıtları da doğrulanır; imzasız yanıt reddedilir.
Oran sınırı (kota)
Bağlantı + sorgu tipi başına sayaç (HhsQueryQuota). Anlık ve periyodik çekimler aynı sayacı paylaşır — çift sayım olmaz.
BKM'ye giden alanlar (Wire DTO)
Bankaya (HHS) gönderilen/gelen JSON gövdelerinin Türkçe alan adları (rizaNo,hesaplar, bakiye, yetKod...) ayrı wire DTOsınıflarında yaşar. Bu sınıflar [JsonPropertyName] ile Türkçe wire adını taşır; AutoMapper profilleri bunları İngilizce iç modele çevirir.
apps/batch/src/FinevoConnect.Yos.Batch.Infrastructure.Integration/Ohvps/Models/ — 8 aile, ~69 DTO dosyası. Serileştirme: aynı klasörün Json/ altındaki source-gen context'ler. Wire yol sabitleri ayrı: Domain/Constants/Api/OhvpsPaths.cs.| Aile (klasör) | İçerik (örnek wire alanları) |
|---|---|
Models/Account | hesap + bakiye (hesaplar, bakiye, iban, hspBlg...) |
Models/Card | kart + detay + taksit + puan (kartBilgileri, ekstre...) |
Models/Consent | rıza (rizaNo, rizaDrm, izinBilgisi, hspBlg...) |
Models/Payment | ödeme emri (emrBlg, tutar, alc, gon, odmStm...) |
Models/Transaction | işlem geçmişi (islemBilgileri, brcAlc, ttr...) |
Models/Event | olay bildirim/abonelik (olaylar, abonelikTipleri...) |
Models/Token | erişim belirteci (erisimBelirteci, yetKod...) |
Models/Common | ortak bloklar (katilimciBlg, kmlk, gkd, hata...) |
FinevoConnect.Yos.Domain/FinevoConnect.Yos.Application/FinevoConnect.Yos.Shared içine ASLA sızmaz (mimari test — NetArchTest — bunu zorlar). api-yos (public API) bu tipleri hiç taşımaz; bankaya yalnız batch bağlanır.