Allmine API

Domain split — outbox billing pilot

~5 dkOpsBackendKararlı

Outbox ve billing domain ayrımı pilot implementasyon notları

Domain Split + Outbox (Billing Pilot) Uygulama Dokümanı

Mühendislik notu

Bu sayfa entegratör yol haritasından çok ekip içi operasyon/backlog içeriği taşır. Entegrasyon için API Reference ve ilgili ürün rehberlerini kullanın.

1) Amaç

Bu çalışma, billing tick akışındaki dış yan etkileri (socket emit, warning, kick) ana iş akışından ayırıp outbox üzerinden yürütmek için yapıldı. Hedef:

  • Transaction içindeki domain state değişikliklerini güvenli tutmak
  • Dış sistem etkilerini (socket/notification) asenkron ve tekrar denenebilir hale getirmek
  • Geçişi feature flag ile kontrollü yapmak

2) Neden satır değişimi büyük görünüyor?

LiveStreamBillingService içindeki büyük bloklar domain bazlı alt servislere taşındı. Bu yüzden:

  • Tek dosyada satır azalması oluştu
  • Aynı davranışlar yeni dosyalara dağıtıldı
  • Farkın önemli kısmı "silme" değil "taşıma/refactor"

Özetle büyük diff, fonksiyonların kaybolmasından değil monolit dosyanın parçalanmasından kaynaklanıyor.

3) Yapılan değişiklikler

3.1 Outbox Foundation

Eklendi:

  • src/outbox/schemas/outbox-event.schema.ts
  • src/outbox/schemas/processed-event.schema.ts
  • src/outbox/contracts/*
  • src/outbox/services/outbox-writer.service.ts
  • src/outbox/services/domain-event-publisher.service.ts
  • src/outbox/services/outbox-feature-flags.service.ts
  • src/outbox/outbox.module.ts

Neden:

  • Outbox eventlerini kalıcı saklamak
  • Consumer idempotency için (consumerName,eventId) tekilliği sağlamak
  • İç katmanda publish/yazma sorumluluğunu ayrıştırmak

3.2 Queue + Relay

Eklendi:

  • src/queues/services/domain-outbox-queue.service.ts
  • src/queues/consumers/domain-outbox.consumer.ts
  • src/queues/services/domain-outbox-relay.service.ts
  • src/queues/services/billing-outbox-side-effect.handler.ts

QueuesModule güncellendi:

  • Yeni queue: domain-outbox
  • Relay ve handler provider kayıtları

Neden:

  • PENDING -> PROCESSING -> PUBLISHED/FAILED state machine ile güvenli teslimat
  • Retry/backoff desteği
  • Side-effect çağrılarını domain işleminden izole etmek

3.3 Billing Pilot (Dual-Run + Flag)

Güncellendi:

  • src/queues/consumers/live-stream-billing.consumer.ts

Eklenen davranış:

  • Pilot açıkken billing olaylarını outbox'a yazar
  • Side effects active olduğunda legacy direkt socket çağrılarını kapatır
  • Pilot açık ama active kapalıyken dual-run/dry-run ilerler

Kullanılan event tipleri:

  • billing.charge.applied.v1
  • billing.balance.change.v1
  • billing.charge.insufficient_balance.v1
  • billing.balance.low_warning.v1

3.4 Domain Bazlı Ayrıştırma (Billing Servis)

Güncellendi:

  • src/live-stream/services/live-stream-billing.service.ts

Eklendi:

  • src/live-stream/services/billing/billing-charge.service.ts
  • src/live-stream/services/billing/billing-revenue-distributor.service.ts
  • src/live-stream/services/billing/billing-duoself-settlement.service.ts
  • src/live-stream/services/billing/billing-duocrowd-settlement.service.ts
  • src/live-stream/services/billing/billing-lock-cache.service.ts
  • src/live-stream/services/billing/billing.constants.ts
  • src/live-stream/services/billing/billing.deps.ts
  • src/live-stream/services/billing/billing.types.ts

Neden:

  • Tek dosyada toplanmış büyük iş kurallarını domain fonksiyonlarına bölmek
  • Bakım maliyeti ve regresyon riskini düşürmek
  • Outbox ve feature-flag geçişini daha kontrollü yapmak

4) Canlıya etkisi

Değişmeyenler

  • HTTP/WebSocket public contract değişmedi
  • Mevcut billing akışının ana davranışı korunuyor

Feature Flag davranışı

  • OUTBOX_ENABLED=false (default): outbox kapalı, legacy davranış devam eder
  • OUTBOX_ENABLED=true + OUTBOX_BILLING_PILOT_ENABLED=true + OUTBOX_BILLING_SIDE_EFFECTS_ACTIVE=false: dual-run/dry-run
  • OUTBOX_BILLING_SIDE_EFFECTS_ACTIVE=true: billing minute-charge side-effectleri outbox consumer üzerinden yürür

Bu nedenle flag'ler kontrollü açıldığında canlıda kesintisiz geçiş hedeflenir.

5) Neden bu tasarım seçildi?

  • Transaction içindeki veri bütünlüğünü korurken dış etkileri tekrar denenebilir yapmak için outbox deseni uygundur.
  • "At-least-once + idempotent consumer" yaklaşımı ağ/worker kesintilerine daha dayanıklıdır.
  • Dual-run yaklaşımı, cutover öncesi event parity ölçümü ve güvenli geçiş sağlar.

6) Doğrulama

Çalıştırılan kontroller:

  • npm run build
  • npm run test -- src/queues/services/domain-outbox-relay.service.spec.ts --runInBand
  • npm run test -- src/queues/consumers/live-stream-billing.consumer.spec.ts --runInBand
  • npm run test -- src/live-stream/use-cases/create-live-stream.usecase.spec.ts --runInBand
  • npm run test -- src/live-stream/gateways/live-stream.gateway.spec.ts --runInBand
  • npm run test -- --runInBand

Sonuç: Tüm suite/testler geçti (140/140 suite, 651/651 test).

7) Rollout Önerisi (Canlı)

  1. Prod'da tüm OUTBOX_* flagleri kapalı deploy et.
  2. OUTBOX_ENABLED=true, OUTBOX_BILLING_PILOT_ENABLED=true, side-effect active false ile dual-run başlat.
  3. Legacy ve outbox event sayımlarını 48 saat karşılaştır.
  4. Parite stabilse OUTBOX_BILLING_SIDE_EFFECTS_ACTIVE=true aç.
  5. 7 gün failed/retry oranlarını izle.

8) Rollback Planı

Sorun halınde:

  • OUTBOX_BILLING_SIDE_EFFECTS_ACTIVE=false yap (legacy direct side-effect anında geri devreye girer)
  • Gerekirse OUTBOX_BILLING_PILOT_ENABLED=false veya OUTBOX_ENABLED=false ile pilotu tamamen kapat

Kod rollback yapmadan flag rollback ile hızlı geri dönüş mümkündür.

9) Bilinen not

Deploy öncesi yeni dosyaların tamamı commit'e dahil edilmelidir. Özellikle:

  • src/outbox/*
  • src/live-stream/services/billing/*
  • src/queues/services/domain-outbox-*
  • src/queues/consumers/domain-outbox.consumer.ts

On this page