# Dönem savaşları

## 1. Takvim ve katılım

Günlük, haftalık ve aylık savaşlar bütün katılımcı sitelerin ortak sıralamasını kullanır. Her oyuncu her döneme bir kez katılabilir. Kimlik, sitenin değişmeyen `externalId` değeriyle oluşturulan kalıcı hesaptır. Başka cihaz, yeni oturum veya tekrar gönderilen istek ikinci satın alma oluşturmaz. Aynı kişinin farklı sitelerdeki hesapları ayrı hesaplardır; sistem bu kişilerin gerçek dünyada aynı kişi olduğunu varsaymaz.

Dönemler İstanbul saatine göre açılır: günlük 00:00, haftalık pazartesi 00:00, aylık ayın ilk günü 00:00. Varsayılan olarak katılım yeni dönemden 60 dakika önce kapanır: günlük katılım 23:00’te kapanır, yeni oyun 00:00’te açılır. Haftalık ve aylık dönemlerde bu aralık son gün uygulanır. Kapanış anı yeni katılıma dahil değildir. Sunucu kapalıyken kaçırılan dönemler için geriye dönük oyun veya satın alma oluşturulmaz.

## 2. Admin ayarları ve oyun seçimi

Sağlayıcı konsolunda Dönem savaşları sayfasını aç. Ana anahtar ve günlük, haftalık, aylık anahtarlar ayrıdır. Her dönem için katılım bedeli, oyun/sağlayıcı havuzu, bonus türü, kesinti, ilk üç ödül oranı ve katılım kapanış aralığı belirlenir. `entryCloseMinutes` 1–720 dakika aralığındadır; varsayılanı 60’tır. Bu ayar da dönem açılışında sabitlenir. Başlangıç oranı %50 / %30 / %20, havuz kaynağı bonus kazançlarıdır. Oranların toplamı %100 olmalıdır.

Dönem açılırken uygun havuzdan bir oyun seçilir. Oyun, bonus türü, tutar, havuz modeli ve dağıtım oranları dönem boyunca sabit kalır. Ayar değişiklikleri sonraki döneme uygulanır. Ana veya dönem anahtarını kapatmak yeni katılımı durdurur; başlamış turları ve kazanılmış ödeme haklarını iptal etmez.

Açıkça seçilen oyun, belirlenen tutarı ve bonus türünü desteklemelidir. Sağlayıcı havuzundan yalnız bu koşulları destekleyen oyunlar seçilir. Oyuncunun kendi sitesindeki oyun ve tutar kısıtları ayrıca uygulanır. Platform üst limiti, sağlayıcının gerçek satın alma veya demo kredi sınırını yükseltmez.

## 3. Skor, havuz ve ödeme

Katılımda ücret mevcut cüzdan rezervasyon akışıyla bir kez ayrılır. Oyuncunun bonus turu mevcut oyun adaptöründe başlar; doğrulanmış bonus kazancı sıralama skorudur. Bonus kazancı tur biter bitmez kişiye ayrıca ödenmez. Rezervasyon dönem sonuçlanıncaya kadar kilitli kalır.

Havuz için iki seçenek vardır:

- Bonus kazançları: geçerli, tamamlanmış turların doğrulanmış bonus kazançlarının toplamı.
- Katılım bedelleri: geçerli, tamamlanmış katılımların ücretleri toplamı. Bonus kazançları yalnız sıralamayı belirler; ayrıca kişiye ödenmez veya havuza eklenmez.

Seçilen havuzdan bu modüle özel kesinti düşülür. Net havuz ilk üç sıraya dağıtılır. Üçten az katılım varsa mevcut sıraların ağırlıkları %100'e normalize edilir. Eşit skorlar kapladıkları sıraların ödüllerini eşit paylaşır; üçüncülük sınırını aşan beraberlik de buna dahildir. Bölünemeyen kuruşlar kararlı katılım kimliği sırasıyla dağıtılır; toplam korunur. Hiç geçerli katılım yoksa ödeme sıfırdır.

Katılım kapanış saati geldiğinde yeni satın alma durur. Son turlar kesinleşince dağıtım başlar; gece yarısını beklemek gerekmez. Devam eden, incelemedeki veya cüzdan rezervasyonu uzlaşma bekleyen tur varsa dönem doğrulanıyor durumunda bekler. Son tur gece yarısını aşarsa eski dönem sonucu beklenir; yeni dönem bağımsız olarak açılır. Tahmini skor veya otomatik ikinci satın alma üretilmez. İptal edilip iade edilen katılım havuz ve sıralamadan çıkar; aynı dönem tekrar katılım hakkı açılmaz.

Ödüller kalıcı ödeme kuyruğuna yazılır ve mevcut site cüzdanı mutabakatından geçer. Zaman aşımı yeni ödeme değildir; aynı işlem kimliği tekrar kullanılır. Cüzdan olayındaki `battle.competition`, dönem kimliğini, türünü, durumunu, katılım kapanışını (`entryClosesAt`), yeni dönem sınırını (`endAt`), havuz modelini, sırayı ve ödülü taşır. Dağıtım kesinleşmeden sonuç `pending`; ödül alan için `win`, almayan için `loss`, iptal/iade için `refund` olur. İletim onayı bekleyen ödeme arayüzde ayrıca belirtilir.

## 4. Iframe ve modül bağlantısı

Mevcut kimlik ve cüzdan entegrasyonu kullanılır; yeni bir oyuncu hesabı açılmaz. Backend üzerinden normal açılış bileti üretirken aşağıdaki rota kullanılabilir:

```json
{
  "externalId": "member-123",
  "origin": "https://operator.example",
  "route": "competitions"
}
```

Bu alanlar mevcut `/provider/v1/launch` isteğinin gövdesidir. API anahtarı yalnız operatör backend'inde kalır. Iframe güncel sağlayıcı arayüzünü kullanır. Dosyalı modülde yeni istemci paketini yüklemek gerekir. Oyuncu, sağlayıcıdaki Dönem savaşları sayfasından katılır ve kendi site cüzdanına döner.

## 5. Arayüz API'leri ve izinler

Aşağıdaki uçlar oyuncu arayüzünün oturumuyla kullanılır; operatörün sunucu API anahtarı bu oturumun yerine geçmez.

```http
GET /play/:slug/api/competitions
GET /play/:slug/api/competitions/history?kind=daily&date=2026-10-27
POST /play/:slug/api/competitions
Content-Type: application/json
```

```json
{"periodId":"daily-<server-issued-period-start>"}
```

`periodId` değerini liste yanıtından al. Katılım isteğinde tutar, skor, ödül veya bonus gönderme. Sunucu tutarı ve bonusu dönem kaydından alır. Tekrar edilen geçerli katılım aynı `roomId` döndürür. Yayın ve tekrar için mevcut oda uçları kullanılır. Liste her türün son 10 dönemini (en fazla 30), her dönem için ilk 100 skoru ve giriş yapan oyuncunun kendi sonucunu döndürür.

Geçmiş uç noktasında `kind` daily/weekly/monthly, `date` İstanbul saatine göre YYYY-MM-DD biçimindedir. Bugün ve önceki 30 gün seçilebilir; geçersiz veya bu aralığın dışındaki tarih 400 döndürür. Seçilen tarihin içinde bulunduğu dönemin ilk 100 sırası, oyuncunun kendi sonucu ve son 30 güne ait dönem özetleri döner. Kayıt olmayan tarihte `period` null olur. Özetlerde ilk üç kayıt; tam tabloda beraberlikler dahil ilk 100 skor gösterilir. Yeni dönem sıfır katılımla ayrı kayıtta başlar; önceki skorlar, ödüller ve işlem kayıtları silinmez. Son 30 gün arayüzün erişim aralığıdır, veri silme süresi değildir.

Admin uçları ayrı sağlayıcı panel oturumu kullanır. Okuma `settings.read`, değişiklik `settings.manage` ve mevcut CSRF başlığı gerektirir.

```http
GET /control/api/competitions
PATCH /control/api/competitions
```

PATCH gövdesi `settings` nesnesinin tamamı ve güncel `revision` değeridir. Eşzamanlı eski sürümle kayıt 409 döndürür. Tutarlar kuruş, oranlar baz puandır: 500000 = 5.000 TL; 500 = %5. Panel bunları TL ve yüzde olarak düzenler. Ayar değişiklikleri denetim günlüğüne yazılır.

## 6. Yayına almadan kontrol

- Önce modülü kapalı tutarak havuzu ve desteklenen bonusları yapılandır.
- Her site için izinli tutar, oyun erişimi ve cüzdan modelini doğrula.
- Katılım, tekrar istek, tur sonucu, dönem kapanışı, beraberlik ve cüzdan yeniden denemelerini test et.
- Gerçek sağlayıcı turunun satın alma, sonuç doğrulama ve yayınını ayrıca gözle. Birim testindeki kontrollü sağlayıcı yanıtı, gerçek oyun testi değildir.
- Üretimde dönem tutarlarını, kesintiyi ve ödül dağılımını oyuncuya göster. Cüzdan aktarımı bekleyen sonuçları tamamlanmış ödeme gibi sunma.


## 7. Site katılım ve ödül raporu

Operatör panelindeki **Dönem savaşları** sayfası yalnız oturumun bağlı olduğu sitenin oyuncularını gösterir. Günlük, haftalık ve aylık görünüm ile geçmiş dönem seçilebilir. Personelin `rooms.read`, `players.read` ve `finance.read` izinlerinin üçü de gerekir. Ortak sıralamadaki derece gösterilir; başka sitelerin oyuncu kimlikleri, kullanıcı adları, odaları veya finans kayıtları bu rapora eklenmez.

```http
GET /operator-api/competitions?kind=daily&limit=50&offset=0
```

Bu uç operatör panelinin cookie oturumunu kullanır. API anahtarı panel oturumu yerine geçmez. Kendi sunucundan aynı raporu almak için `read` kapsamlı, bu siteye bağlı anahtarı kullan:

```http
GET /provider/v1/competitions?kind=daily&limit=50&offset=0
Authorization: Bearer <SERVER_API_KEY>
```

```javascript
const report = await client.competitions({ kind: 'daily', limit: 50 });
const previous = report.periods[1];
if (previous) {
  const archive = await client.competitions({
    kind: 'daily', periodId: previous.id, offset: 0, limit: 50
  });
}
```

- `kind`: `daily`, `weekly` veya `monthly`; varsayılan `daily`.
- `periodId`: yanıttaki `periods` listesinden seçilir; yoksa türün son dönemi. Farklı türle eşleşmeyen veya bulunamayan dönem 404 döndürür.
- `limit`: 1–100, varsayılan 50. `offset`: 0–100000000, varsayılan 0. Bilinmeyen veya tekrarlanan sorgu alanları 400 döndürür; `tenantId` gönderilmez.
- `periods`: seçilen türün en yeni 100 dönem başlığı. Daha eski, bilinen geçerli dönem kimliği de okunabilir; kayıtlar silinmez.
- `period`: oyun, bonus, katılım bedeli, kapanış ve dağıtım ayarlarının dönem açılırken alınan kopyası; açılmış dönem yoksa `null`.
- `summary`: sayfalama dışında, seçili dönemde yalnız bu sitenin toplamları.
- `entries`: yalnız bu sitenin sayfalanmış katılımcıları. `publicId` arena kimliği, `externalId` site üye kimliği, `siteUsername` sitenin ilettiği kullanıcı adıdır. Eksik özel kimlik alanları `null` olabilir.
- `rank`: tüm siteler arasındaki sıra. Kesinleşmeden önce değişebilir; eşit skor aynı sırayı paylaşır. İptal veya bitmemiş turda `null`.
- `pagination.total` ve `hasMore`: sonuçların devamı; her sonraki sayfada aynı `periodId` kullanılır.

Tüm tutarlar TRY kuruşudur. `entryVolume` kabul edilmiş katılımların toplam bedelidir; iptal edilenleri de içerir. `refunds` onaylanan, `pendingRefunds` bekleyen iadeyi gösterir. `totalScores` yalnız geçerli, doğrulanmış bonus skorlarıdır. `awardedPrizes` kesinleşmiş ödül, `paidPrizes` cüzdan teslimi onaylanan tutar, `pendingPrizes` onay bekleyen farktır. Ödül ve katılım hacmi operatör geliri değildir; sitenin komisyon payı `operatorShare` alanındadır. Bekleyen ödül veya iade, onay gelene kadar ödenmiş kabul edilmez.

Katılımcı `status` alanı `playing`, `scored` veya `void` olur. `paymentStatus`: dönem öncesi `awaiting-period`, dağıtımda `pending`, hesaplaşma tamamlanınca `complete`, iade için `refund-pending` / `refunded`. Kazanan sayısı pozitif ödül alan site oyuncularıdır; beraberlikte üçten fazla ödüllü oyuncu olabilir.

## 8. Olay geçmişi ve paket güncellemesi

`/provider/v1/events` ve `/provider/v1/webhooks/events` dönem odasına ait hareketlerde ek `competition` bağlamı döndürür: `periodId`, `kind`, `entryId`, `entryStatus`, `periodStatus`, `gameId`, `gameName`, `buyInMinor`, `scoreMinor`, `prizeMinor`, `rank`. Bu alan **okuma anındaki dönem bağlamıdır**; değişmez olayın tarihsel anlık görüntüsü değildir. Finans işleminin `id`, `cursor`, `amountMinor` ve `balanceAfter` alanları değişmez. Bir bakiyeyi `scoreMinor` veya `prizeMinor` üzerinden yeniden artırma. Tek cüzdanda para hareketini yalnız imzalı, tekil işlem kimlikli callback belirler; çekilen olay listesi yeni ödeme talimatı değildir.

Iframe otomatik olarak sağlayıcıdaki güncel arayüzü gösterir; mevcut kimlik/cüzdan bağlantısı korunur. Modül kurulumunda güncel `slot-battles-client.zip` içeriğini birlikte dağıt. Sunucu raporu için güncel `slot-battles-sdk.mjs` ve OpenAPI şemasını al. Toplu entegrasyon ZIP'i TR/EN dönem rehberlerini, güncel SDK ve istemciyi içerir. Operatörün Postman koleksiyonuna dönem raporu GET isteği eklenmiştir. Paketler API anahtarı veya site oyuncu verisi içermez.
