Arka Plan İşleri (Batch)
Batch, bankayla/kurumla 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/kurum 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/kurumla 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/kurumun kendi uygulamasından ya da SMS ile verilir; bu durumda banka/kurum 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/kurumla eşitler.
UndeliveredEventsPollJob
Banka/Kurum 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/kuruma sorup toparlar — bir tür yedek güvence.
EventSubscriptionEnsureJob
Bankadan/Kurumdan 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/kuruma 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/kurumdan 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/Kurum 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/Kurumdaki 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/kurumdan öğ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/kuruma iletir; talimatın sıradaki taksidini çalıştırır. |
undelivered-events-pollUndeliveredEventsPollJob.PollAsync | */10 * * * * | 10 dakika | Bize ulaşamamış olay bildirimlerini bankadan/kurumdan sorup toplar. Anlık kanal koparsa devreye giren yedek güvence. |
?fresh=true ile E (anlık, kotasız); banka/kurum 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/kurumdaki 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/kuruma 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/kuruma o an gidilir. Kullanıcı tetiklediğinden PSU=E sayılır ve kotaya takılmaz. Biraz daha yavaş, ama en güncel.
Banka/Kurum ile güvenli konuşma
mTLS
Batch, bankaya/kuruma 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/Kurum 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/Kuruma (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). FinevoConnect YÖS (public API) bu tipleri hiç taşımaz; bankaya/kuruma yalnız batch bağlanır.