Lig yönetiminde skor takibi, saha koşulları veya ağ kesintileri nedeniyle sık sık veri kaybına ve tutarsızlıklara yol açabilir. Bu rehber, "offline-first" prensibiyle tasarlanmış, kesintiye dayanıklı bir skor uygulamasını adım adım kurmanızı sağlar. Hem mobil hem web ortamlarında çalışacak şekilde mimari, senkronizasyon mekanizmaları, çatışma çözümü ve acil durum protokollerini uzman gözüyle ele alıyoruz.
Giriş: Neden offline-first?
Liglerde skorlar hızlı ve güvenilir kaydedilmelidir. İnternetin olmadığı ya da zayıf olduğu stadyum, salon veya saha ortamlarında geleneksel online-only sistemler başarısız olur. Offline-first yaklaşımı: önce yerelde güvenli bir şekilde veri yakalar, işlem güvenliğini sağlar, sonra arka planda güvenli bir şekilde sunucu ile eşler. Bu, kullanıcı deneyimini korur ve veri bütünlüğünü korumaya yardımcı olur.
Mimari bileşenler — yüksek seviyede yapı
Başlangıç olarak sistem dört ana bileşenden oluşmalıdır:
- Yerel veri katmanı: Hızlı, kalıcı ve senkronize edilebilir bir yerel DB (mobilde SQLite/Realm, webde IndexedDB veya PouchDB).
- Senkronizasyon motoru: Operasyon günlüğü (oplog), geri alma/redo destekli, idempotent batch upload mekanizması.
- Sunucu API ve veri deposu: Atomik kabul, idempotent işlem işleme, değişiklik akışının saklandığı bir kaynak-of-truth (Postgres + logical replication, veya DynamoDB+Streams).
- Yönetim ve acil protokoller: Çatışma çözme UI, manuel düzeltme, audit log ve runbook'lar.
Örnek akış
Maç sırasında hakem skoru güncellediğinde uygulama önce yerelde:
- Değişikliği transaction içinde yerel DB'ye yazar (oplog'a bir operasyon ekler).
- UI anında güncellenir; ops geri alınabilir şekilde tutulur.
- Arka planda sync motoru, ağ var ise op'ları paketleyip sunucuya gönderir; sunucu başarılıysa local op'u confirmed olarak işaretler.
Yerel veri modeli ve operation-log (oplog) tasarımı
Puan güncellemeleri genellikle küçük, sık ve genellikle dönüşlüdür (ör: gol, faul, düzeltme). Bu yüzden operasyon bazlı kayıt (append-only oplog) tercih edin. Her operasyon şu alanları içermelidir:
- operation_id (UUID)
- entity_id (maç veya skor kaydı id)
- operation_type (increment, set, correction)
- payload (eski vs yeni değerler veya delta)
- client_id ve device_instance_id
- lamport_timestamp veya vector_clock
- signed_hmac (isteğe bağlı, offline güvenlik için)
Bu yapı hem replay edilebilirlik hem de idempotency sağlar. Sunucu aynı operation_id ile gelen tekrarları reddeder veya idempotent şekilde işler.
Senkronizasyon stratejileri
Senkronizasyonu üç seviyede ele alın:
1) Anlık (real-time) sync
Websocket veya WebRTC ile açık bağlantı varsa op'lar hemen gönderilir. Ancak bağlantı koptuğunda op'lar kuyruğa alınmalı ve kaybolmamalıdır.
2) Arka plan ve periyodik batch sync
Mobil: OS arka plan sınırlamalarına göre WorkManager (Android) veya BGTasks (iOS) kullanın. Web: Service Worker + Background Sync API ile periyodik yüklemeler yapılır.
3) Manual/On-demand sync
Yöneticinin 'Senkr.' tuşuna basmasıyla veya maç sonrası toplu yükleme için kullanılacak. Büyük batch'lerde chunking ve resumable upload (ör. chunk ID + offset) uygulayın.
Çatışma tespiti ve çözümü — pratik yaklaşımlar
Çatışma kaçınılmazdır. Önemli olan uygun stratejiyi seçmektir:
- CRDT'ler: Eğer skor sadece artış (increment) şeklindeyse PN-Counter gibi CRDT'ler ideal; partition sonrası otomatik birleşim sağlar.
- Operation-based merge: Oplog'u sırayla uygulamak (tek bir kaynak-of-truth üzerinden) genelde tutarlıdır.
- Last-Write-Wins (LWW): Basit ama tehlikeli. Skor gibi kritik finansal olmayan ama kritik doğruluk gerektiren verilerde tavsiye edilmez tek başına.
- Deterministik business rules: Örneğin, manuel düzeltme yalnızca yetkili kullanıcı tarafından yapılabilir; otomatik birleşmede en yüksek güvenilir cihaz önceliği verilebilir.
Pratik örnek: İki hakem aynı maçta farklı cihazdan skor girerse, op'ları sıralamak için vector clock + server-side validation kullanın. Çatışma yüksekse otomatik olarak admin review kuyruğuna düşsün.
Güvenlik ve bütünlük
- Taşıma katmanı: Tüm iletişim TLS ile korunmalı.
- Offline veri şifreleme: Mobilde SQLCipher, webde IndexedDB verilerini istemci tarafında şifreleme önerilir.
- İmzalı operasyonlar: Özellikle kritik maçlarda ops'lara HMAC imzası ekleyerek sonradan manipülasyon tespit edilebilir.
- Yetkilendirme: Kısa ömürlü refreshable token'lar; offline kullanım için minimal scope'lu offline token stratejisi uygulayın ve kullanım limitleri koyun.
Acil durum protokolleri ve runbook
Bir ağ bölünmesi, sunucu çökmesi veya şüpheli veri durumunda uygulanacak net adımlar oluşturun:
- Olay tespiti: Monitoring (sync failure rate, queue depth, conflict rate) ile otomatik alarm.
- Geçici önlem: Uygulamayı read-only moda al; yeni skor girişlerini yerelde kabul etmeye devam et ama sunucuya post etmeyi içeren bir bayrakla işaretle.
- Manuel müdahale: Admin UI üzerinden conflicted ops'ları inceleyip onaylama veya redetme.
- Rekonsiliasyon: Freeze window (ör. maç sonrası 24 saat) tanımlayın; bu sürede düzeltmeler admin onayı gerektirsin.
- Aksiyon sonrası rapor: Tüm adımlar audit log'a yazılmalı ve post-mortem hazırlanmalı.
Uygulamada otomatik çözümler çatışmaları azaltır, ancak insan-onaylı süreçler kritik doğruluk için vazgeçilmezdir.
Monitoring, metrikler ve test planı
Ölçülecek kritik metrikler:
- Sync latency (ortalama, p95)
- Ops queue depth (cihaz başına ve toplam)
- Conflict rate (ops başına düşen çatışma yüzdesi)
- Resubmission rate ve idempotency başarısızlıkları
Test senaryoları:
- Network partition testleri (kaotik zayıf ağ koşulları)
- Clock skew simülasyonları
- Concurrent ops testleri (iki cihaz aynı anda farklı ops üretmesi)
- Penetration testleri ve offline veri ele geçirilmesi testleri
Adım adım uygulama checklist (hızlı)
- Yerel DB seçimi: mobil için SQLite/Realm, web için IndexedDB/PouchDB.
- Oplog formatını tanımla (UUID, client_id, vector clock, payload).
- Sync engine implementasyonu: batch, chunking, resumable uploads.
- Sunucu API: idempotent endpoint'ler, validation ve audit log.
- Çatışma politikası: CRDT mi, op-replay mi, yoksa admin incelemesi mi?
- Güvenlik: TLS, at-rest encryption, token yönetimi.
- Monitoring ve runbook hazırla.
- Kaos testleri ve saha pilotu uygula.
Sonuç
Kesintiye dayanıklı offline-first skor uygulaması kurmak, doğru mimari seçimleri, sağlam bir oplog ve akıllı senkronizasyon stratejileri gerektirir. CRDT'ler veya operation-based replay ile otomatik birleşim sağlanabilir; ancak operasyonel süreçler, monitoring ve manuel düzelme mekanizmalarıyla desteklenmelidir. Lig yöneticileri için en önemli hedef: sahada skor kaybı yaşamamak, sonrasında güvenilir ve doğrulanabilir bir birleşme süreciyle veriyi sunucuya taşımaktır.
Uygulamanızı kurarken pratik ipucu: İlk pilotu küçük bir turnuvada çalıştırın, conflict-rate ve sync-latency metriklerini gözlemleyin, sonrasında geniş ölçekli yayına geçin.