Referans · metot-metot

apps/batch — Hangfire İşçi

Bankayla konuşan tek uygulama. Her tip → görev + metot metot ne yaptığı + bağlantılar. Türkçe wire DTO'ları yalnız Integration/Ohvps altında (anti-corruption).

Worker (host + iç uçlar)

Program.csFinevoConnect.Yos.Batch.Worker

Worker host; Serilog+Hangfire+DI; 10 recurring job kaydı (8 job sınıfı; PeriodicResourceRefreshJob balance/transaction/card için 3×); JWS/mTLS bayrak boot-gate (fail-closed).

RecurringJob.AddOrUpdate ×10sync-intent-consumer, periodic-{balance,transaction,card}-refresh, decoupled-gkd-poll, recurring-payment-execution, forward-dated-status-sync, consent-timeout-sweep, event-subscription-ensure, undelivered-events-poll — cron config sabitlerinden.
Bağlı: Hangfire, tüm job'lar
OhvpsEventsControllerFinevoConnect.Yos.Batch.Worker/Controllers

ÖHVPS olay webhook'u (POST /api/v1/ohvps/events).

Receive()JWS imza filtresinden geçer → IOhvpsEventParser.Parse → IOhvpsEventService.HandleEventAsync → 202. Gövde tampon + idempotency olay servisinde.
Bağlı: IOhvpsEventParser, IOhvpsEventService, OhvpsEventSignatureFilter
LiveQueryControllerFinevoConnect.Yos.Batch.Worker/Controllers

İç senkron canlı-sorgu ucu (POST /internal/live-query).

Execute(req)X-Internal-Secret'i config secret ile FixedTimeEquals doğrular (yoksa/uymazsa 401); SetFromIntent(PsuInitiator.UserPresent) ile PSU=E bağlamı; ILiveQueryService.ExecuteAsync → LiveQueryResponse.
Bağlı: ILiveQueryService, BatchOhvpsRequestContext

Uygulama servisleri

ConnectionSyncServiceFinevoConnect.Yos.Batch.Application/Sync

Bir bağlantı için hesap/işlem/kart senkronu + kota + token yenileme.

RunInitialFetchAsync(id, reason)Bağlantıyı çözer (token süresi dolduysa RefreshAsync); kota rezerve (AccountList/Balance); GetAccountsAsync → UpsertAccounts; SyncTransactions + SyncCards.
RefreshBalanceAsync(id, reason)TryReserveAsync(Balance); GetAccountsAsync (bakiye içerir) → UpsertAccounts; kota dolduysa QuotaExhausted döner.
RefreshTransactionsAsync(id, reason, accountRef?)TryReserveAsync(Transaction); hesap(lar) için işlem çeker (sayfalı) → upsert.
RefreshCardsAsync(id, reason)Kart izni kontrolü; kota; kart başlık + ekstre-tipi + detay + işlem tek geçişte upsert.
TryReserveAsync(conn, kind, reason)reason UserRequested VEYA EventTriggered ise (E/O) → (true,null) KOTASIZ. Autonomous(H) ise pencere bul/oluştur + TryConsumeSlot (atomik ExecuteUpdate); dolu ise (false,null).
Bağlı: IOhvpsAccountClientFactory, IOhvpsTokenClient, IHhsQueryQuotaRepository
LiveQueryServiceFinevoConnect.Yos.Batch.Application/LiveQuery

Senkron canlı-sorgu; kind → ConnectionSyncService (RefreshReason.UserRequested → E, kotasız).

ExecuteAsync(req)Bağlantı yoksa/Connected değilse not_connected. SetGroupId(connection.GroupId). Kind eşleme: Accounts→RefreshBalance, AccountTransactions→RefreshTransactions(accountRef), Cards/CardDetail/CardTransactions→RefreshCards, ConnectionStatus→ConsentStatus handler'ı inline çalıştır. OhvpsIntegrationException→hhs_error. Outcome+AsOf döner.
Bağlı: IConnectionSyncService, ConsentStatusSyncHandler
ConsentActivationServiceFinevoConnect.Yos.Batch.Application/Consent

Rıza aktivasyonu (yetKod→token→Connected).

CompleteAuthorizationAsync(id, authCode?)Connected/Pending değilse no-op. SetGroupId. authCode verildiyse (redirect) → MarkAuthorized + doğrudan ExchangeAuthorizationCode; yoksa (decoupled) → GetAuthorizationCode poll. Token'ı şifreleyip MarkConnected; TrySaveChanges (dup-key sessiz).
Bağlı: IOhvpsTokenClient, ITokenProtector, IHhsConnectionRepository
OhvpsEventServiceFinevoConnect.Yos.Batch.Application/Events

Gelen ÖHVPS olayı; YÖS-kod + idempotency + dispatch.

HandleEventAsync / HandleUndeliveredEventsAsyncYÖS kod eşleşmezse düşer; her olay için yaş penceresi + BuildEventId idempotency (InboundEventStore).
dispatch (HandleOneAsync)AyrikGkdBasarili→ActivateAsync, AyrikGkdBasarisiz→MarkFailedAsync, KaynakGuncellendi→HandleResourceUpdatedAsync, diğer→no-op.
HandleResourceUpdatedAsynckaynakTip: HesapBilgisiRizasi→ConsentStatusSync niyeti, Bakiye→BalanceRefresh(EventTriggered), KartBilgileri→CardRefresh(EventTriggered), diğer→no-op.
⚠ ActivateAsyncConsentType'a BAKMAZ — CompleteAuthorization + InitialFetch (hesap) yapar. Ödeme rızası ayrık-GKD olayında yanlış (bilinen açık).
Bağlı: IInboundEventStore, IConsentActivationService, ISyncIntentService

Niyet işleyicileri

SyncIntentConsumerJob, niyet Kind'ine göre bunlardan birine dispatch eder.

ConsentCreateHandlerSync/Handlers

Yeni hesap-bilgisi rızası.

HandleAsync(intent)Payload çöz; idempotency (zaten oluşturulduysa çık); kimliği çöz; CreateAccountConsentAsync → MarkConsentCreated. Kalıcı red (4xx)→MarkFailed; geçici (5xx)→fırlat (retry).
Bağlı: IOhvpsConsentClient
AuthorizationCompleteHandler / InitialFetchHandlerSync/Handlers

Aktivasyon + ilk veri zinciri.

AuthorizationComplete.HandleAsyncpayload.AuthorizationCode ile ConsentActivationService.CompleteAuthorizationAsync; bağlanınca InitialFetch niyeti zincirler.
InitialFetch.HandleAsyncConnectionSyncService.RunInitialFetchAsync (hesap+işlem+kart).
Bağlı: IConsentActivationService, IConnectionSyncService
BalanceRefresh / TransactionRefresh / CardRefreshHandlerSync/Handlers

Kaynak yenileme.

HandleAsyncİlgili Refresh*Async'i payload.Reason ile çağırır; QuotaExhausted dönerse SyncIntentRescheduleSignal fırlatır (kota penceresi sonuna ertelenir).
Bağlı: IConnectionSyncService
ConsentStatusSyncHandlerSync/Handlers

Rıza durum senkronu.

HandleAsyncGetConsentStatusAsync → duruma göre MarkCancelled/MarkExpired/MarkFailed + izin reconcile; yetki-zaman-aşımı kontrolü.
Bağlı: IOhvpsConsentClient
PaymentOrderSubmit / *AuthorizationCompleteHandler + PaymentInstructionCompletionFlowSync/Handlers

Ödeme aileleri.

Submit.HandleAsyncCreatePaymentConsentAsync → order+connection MarkConsentCreated.
AuthorizationComplete.HandleAsyncPaymentInstructionCompletionFlow.RunAsync.
CompletionFlow.RunAsyncredirect'te callback-yetKod / decoupled'da GetAuthorizationCode poll → ExchangeAuthorizationCode → placeInstruction (odeme-emri) → attachInstruction(ref+token) → TrySaveChanges → commit'te triggerAsync.
Bağlı: IOhvpsPaymentClient, IOhvpsTokenClient

Hangfire job'ları

SyncIntentConsumerJobInfrastructure/Jobs

Niyet kuyruğunun kalbi.

DrainDueAsyncListDueAsync(now) → her niyet için ProcessOneCoreAsync.
ProcessOneCoreAsyncMarkDispatched; InboundEventStore.TryMarkConsumed (at-least-once guard); SetFromIntent(GroupId, ResolvePsuInitiator, requestId=intent.Id); handlersByKind[Kind].HandleAsync; MarkConsumed + FireChainedTriggers.
ResolvePsuInitiator / MapReasonRefresh niyetlerinde payload.Reason → PSU: UserRequested→UserPresent(E), EventTriggered→HhsInitiated(O), Autonomous→Autonomous(H).
hata yollarıSyncIntentRescheduleSignal→MarkRetryScheduled; dup-key→consumed; diğer→exponential backoff, max deneme→MarkDead.
Bağlı: handlersByKind, IInboundEventStore, ChainedSyncIntentAccessor, IBackgroundJobClient
PeriodicResourceRefreshJobInfrastructure/Jobs

Otonom (H) periyodik yenileme.

RefreshBalances/Transactions/Cards → RunCoreAsyncSetFromIntent(Autonomous); ListConnectedPageAsync (keyset); süresi geçmemiş bağlı bağlantılara ConnectionSyncService.Refresh* (kota sayılır).
Bağlı: IConnectionSyncService
ConsentTimeoutSweepJob / DecoupledGkdPollJobInfrastructure/Jobs

Süpürme + ayrık yoklama.

SweepAsyncTakılı onay pencerelerine ConsentStatusSync niyeti; süresi geçmiş rızalara MarkExpired.
PollDueAsyncBekleyen ayrık bağlantılara DecoupledGkdPoller.TryAdvanceAsync (⚠ ConsentType ayırmaz — ödeme için de InitialFetch).
Bağlı: IHhsConnectionRepository, DecoupledGkdPoller
EventSubscriptionEnsureJob / UndeliveredEventsPollJobInfrastructure/Jobs

Olay aboneliği + yedek çekme.

EnsureAsyncHer etkin banka için abonelik yoksa Create, varsa Get/Update (auto-subscribe).
PollAsyncAbone bankalardan ulaşamamış olayları çeker → HandleUndeliveredEventsAsync (anlık kanal koparsa kurtarır).
Bağlı: IOhvpsEventClient, IOhvpsEventService
RecurringPaymentExecutionJob / ForwardDatedPaymentStatusSyncJobInfrastructure/Jobs

Ödeme yürütme/durum.

ExecuteDueAsync (recurring)Vadesi gelen düzenli ödemeleri yürütür (SyncInstructionAsync).
ExecuteDueAsync (forward-dated)Planlı ileri tarihli ödemelerin durumunu senkronlar.
Bağlı: RecurringPlanSyncService, ForwardDatedStatusSyncService

ÖHVPS entegrasyonu (DelegatingHandler zinciri: Auth→JWS→Log)

OhvpsAuthHandlerIntegration/Ohvps/Plumbing

Giden başlık üretimi (DelegatingHandler).

SendAsyncX-ASPSP/X-TPP-Code; X-Request-ID (pinned ise ScopeToOperation=MD5(flowId|method|path) → retry-stabil + operasyon-tekil, yoksa yeni GUID); X-Group-ID (explicit||pinned); PSU-Initiated (E/H/O) + E'de PSU-Fraud-Check; Authorization Bearer + X-Access-Token.
Bağlı: IOhvpsRequestContext, IIdGenerator, IPsuFraudCheckTokenProvider
JwsSigningHandlerIntegration/Ohvps/Plumbing

İmza (DelegatingHandler).

SendAsyncEnableJws ise POST/PUT/PATCH/DELETE gövdesini PS256 detached JWS imzalar (X-JWS-Signature); yanıtta imza yoksa/geçersizse HttpRequestException (downgrade reddi).
Bağlı: IJwsSigner, IJwsVerifier, IFeatureFlags
OhvpsConsentClient / PaymentClient / TokenClient / EventClient (+Factory)Integration/Ohvps/*

Slice client'lar; Türkçe wire DTO → domain (AutoMapper).

Consent: CreateAccountConsent / Cancel / GetConsentStatushesap-bilgisi-rizasi CRUD.
Payment: CreatePaymentConsent / CreatePaymentOrder / Recurring / ForwardDatedödeme aileleri rıza+emir.
Token: GetAuthorizationCode / ExchangeAuthorizationCode / RefreshyetKod poll + token değişim/yenileme.
Event: Create/Get/Update Subscription / GetUndeliveredEventsolay-abonelik + olay-dinleme (çekme).
Bağlı: OhvpsHttpClientProvider ('ohvps' mTLS client), JSON source-gen context'ler