Referans · dosya-dosya

Bağlantı Haritası

Kim kiminle nasıl konuşuyor: DI kayıtları, uçtan-uca çağrı zincirleri, api↔batch köprüleri, FinevoConnect YÖS↔api-hhs (cross-project) ve katman kuralları.

Bağımlılık enjeksiyonu (özet)

FinevoConnect YÖS (Program + DI)

  • AddApplication → servisler (scoped), ILiveRefreshCoordinator, ISyncIntentService, IErrorLocalizer (singleton)
  • AddInfrastructure → AppDbContext + repository'ler, IUnitOfWork, güvenlik (JWT, DataProtection), ILiveQueryClient (named HttpClient "batch-live-query")
  • JWT auth (HS256), Hangfire SqlServer (storage), Serilog HTTP sink, OpenTelemetry

batch (Program + DI)

  • AddBatchApplication → 19 ISyncIntentHandler (keyed), IConnectionSyncService, ILiveQueryService, IConsentActivationService
  • AddBatchInfrastructure → 8 Hangfire job, ÖHVPS slice client'lar + factory, DelegatingHandler zinciri (Auth→JWS→Log), named HttpClient "ohvps" (mTLS) + "jwks"
  • Paylaşımlı: IClock, IIdGenerator, ITokenProtector (aynı key-ring), IFeatureFlags

Çağrı zinciri: Rıza (yazma → outbox)

Kullanıcının "beni bu bankaya/kuruma bağla" demesinden ilk verilerin gelmesine kadar isteğin geçtiği duraklar:

İstek API'ye gelir, niyet yazılır
HhsConnectionsController.Create → HhsConnectionService.CreateAsync
API bankaya/kuruma gitmez. Bağlantı kaydını, izinleri ve "rıza oluştur" (ConsentCreate) niyetini tek transaction'da veritabanına (SyncIntents) yazar — ya hepsi kaydedilir ya hiçbiri.
Batch niyeti alır, bankada/kurumda rızayı açar
SyncIntentConsumerJob → ConsentCreateHandler → IOhvpsConsentClient
Hangfire anlık tetiklenir; işçi bankaya/kuruma mTLS+JWS ile bağlanıp rıza kaydını başlatır. Bankanın/Kurumun döndürdüğü onay ekranı adresini (authUrl) veritabanına geri yazar.
API kullanıcıyı onay ekranına yönlendirir
bounded-wait: authUrl hazır olana dek kısa süreli bekleme
API, batch'in yazdığı authUrl'i veritabanından yoklar; hazır olur olmaz kullanıcıyı bankanın/kurumun kendi onay ekranına gönderir.
Kullanıcı onaylar, banka/kurum geri döner
GET /api/v1/hhs-connections/callback → AuthorizationComplete niyeti
Onay bitince banka/kurum, kullanıcıyı elindeki yetki koduyla (yetKod) bizim callback adresimize yönlendirir. API bu kodu alır ve "yetkiyi tamamla" niyetini yazar — yine bankayla/kurumla kendisi konuşmaz.
Yetki kodu erişim belirtecine çevrilir
AuthorizationCompleteHandler → ConsentActivationService → IOhvpsTokenClient
Batch yetki kodunu bankada/kurumda erişim belirteciyle takas eder, bağlantıyı "Bağlandı" yapar ve ilk-veri-çekimi (InitialFetch) niyetini kuyruğa bırakır. Belirteç şifreli saklanır.
İlk veriler çekilir
InitialFetchHandler → ConnectionSyncService → IOhvpsAccountClient
Hesaplar, bakiyeler ve kartlar bankadan/kurumdan çekilip veritabanına yazılır. Kullanıcı artık her şeyi tek yerden görür.

Çağrı zinciri: E canlı-okuma (senkron, outbox'suz)

Kullanıcı ?fresh=true ile "bana o anki hâli göster" dediğinde niyet kutusuna uğranmaz; API batch'i doğrudan çağırır:

Taze veri istenir
hesap/kart/işlem/bağlantı servisleri (fresh=true) → ILiveRefreshCoordinator
İlgili servis normal veritabanı okuması yerine canlı-okuma koordinatörüne gider. Tüm ?fresh=true yolları bu tek noktadan geçer.
API batch'e iç çağrı yapar
POST /internal/live-query · X-Internal-Secret başlığı
Senkron, container'lar arası bir iç istektir; dışarıya kapalıdır ve paylaşılan gizli anahtarla doğrulanır.
Batch bankadan/kurumdan çeker, veritabanına yazar
LiveQueryController → ILiveQueryService → ConnectionSyncService.Refresh*
Kullanıcı tetiklediği için PSU=E sayılır ve kotaya takılmaz. Bankadan/Kurumdan gelen taze veri veritabanına işlenir (upsert).
API taze veriyi döner
DB'den yeniden oku → Freshness=Live
Yanıt "canlı" etiketiyle döner. Banka/Kurum o an cevap veremezse eldeki son veri "bayat" (Stale) etiketiyle döner ve arka planda otomatik bir tazeleme tetiklenir — kullanıcı boş ekranla kalmaz.

Çağrı zinciri: Ödeme

Ödeme, rıza akışının aynısını izler — fark: her ödeme kendi rızasını kendi taşır ve istekte Idempotency-Key zorunludur:

Ödeme emri oluşturulur
PaymentOrdersController.Create · Idempotency-Key zorunlu
Tek (Serializable) transaction'da üç şey yazılır: ödeme rızası bağlantısı, emrin kendisi ve "ödemeyi ilet" (PaymentOrderSubmit) niyeti. Aynı istek yanlışlıkla iki kez gelse bile ödeme bir kez işlenir.
Batch bankada/kurumda ödeme rızasını açar
PaymentOrderSubmitHandler → IOhvpsPaymentClient.CreatePaymentConsent
İşçi niyeti alır, bankaya/kuruma ödeme rıza talebini iletir; kullanıcıyı onaya götürecek adres döner.
Kullanıcı ödemeyi onaylar
GET /api/v1/payment-orders/callback
Kullanıcı bankanın/kurumun ekranında ödemeyi onaylar; banka/kurum bizim callback adresimize geri döner.
Ödeme bankaya/kuruma yerleştirilir
PaymentOrderAuthorizationCompleteHandler → PaymentInstructionCompletionFlow
Yetki kodu belirtece çevrilir, ödeme emri bankaya/kuruma yerleştirilir ve durum "Gönderildi" olur. Ödemenin gerçekleşip gerçekleşmediğini artık ödeme sistemi (banka/kurum) belirler; sonuç durum sorgusuyla takip edilir.

api ↔ batch köprüleri

KöprüYazan → OkuyanNe
SyncIntents (outbox)FinevoConnect YÖS (tx-içi)batch SyncIntentConsumerJobYazma banka/kurum işleri (rıza/ödeme). FIFO, at-least-once, OutboxConsumed idempotency.
HhsQueryQuotabatch (atomik ExecuteUpdate)batchBağlantı+kind başına kota sayacı. Yalnız Autonomous(H) sayar; E/O muaf.
DataProtection key-ringbatch (şifreler)FinevoConnect YÖS (çözer)Paylaşımlı volume + SetApplicationName('yos-shared'). Token/PII at-rest. İsim uyuşmazlığı → CryptographicException.
/internal/live-query RPCFinevoConnect YÖS (senkron POST)batch LiveQueryControllerE canlı-okuma. X-Internal-Secret fixed-time. Niyet yok, anlık.
Paylaşımlı MSSQLiki appiki appTek DB. Migration sahibi FinevoConnect YÖS (boot'ta uygular); batch bekler. Hangfire tabloları da burada.

Cross-project: FinevoConnect YÖS ↔ api-hhs (banka/kurum)

Giden (yalnız batch)

mTLS istemci sertifikası + PS256 detached JWS ile: rıza, token, hesap/bakiye/işlem/kart, ödeme, olay-abonelik. host.docker.internal:8443 (ob-shared, cert-SAN geçerli).

Gelen

GKD callback (FinevoConnect YÖS alır: /api/v1/*/callback) + olay-bildirim (batch: /api/v1/ohvps/events, JWS-verify). JWKS ("jwks" client) yanıt imzası doğrulama.

Katman kuralları (NetArchTest zorlar)

FinevoConnect YÖS Ohvps* outbound çağıramaz (BLOCKER)Türkçe wire DTO Domain/Application/Shared'a sızamazApplication → Infrastructure yokWire tipleri yalnız batch Integration/Ohvps

Not: E canlı-okumada FinevoConnect YÖS batch'i çağırır (iç HTTP) — bu Ohvps* değildir, kural korunur. Sertifikalar yalnız batch'te.

Config/env → bileşen

EnvBesler
JWT_SIGNING_KEYapi JWT auth (HS256) + JwtTokenGenerator
OHVPS_YOS_KODbatch JWS issuer + katılımcı bloğu (yosKod)
OHVPS_CALLBACK_BASE_URLGKD callback URL'leri (api alır)
OHVPS_CONSUMER_{CONSENT,PAYMENT}_{SUCCESS,ERROR}_URLGKD callback 302 dönüş adresleri — YALNIZ fallback: create isteği consumerSuccessUrl/consumerErrorUrl vermediyse kullanılır ({kind} şablonu yalnız ödeme fallback'inde)
OHVPS_DEFAULT_HHS_BASE_URLbatch HHS istemci base. (JWKS için düz env yoktur; her banka/kurum için DB'deki Bank.JwksUrl kayıt değeri kullanılır.)
BATCH_LIVE_QUERY_BASE_URLapi → batch iç RPC adresi (http://batch-api:8080)
BATCH_LIVE_QUERY_SECRETiki app: X-Internal-Secret (fixed-time compare)
DataProtection:VolumePathiki app: paylaşımlı anahtar halkası volume
Ohvps__Cert__* (RootCa/Client crt+key)yalnız batch: mTLS istemci sertifikası
MSSQL_TRUST_CERTDB TLS: prod=false (doğrular), dev=true (self-signed)