> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flextell.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotency

> POST isteklerini güvenle tekrar etmek için izleyebileceğiniz örüntüler.

"Idempotent" bir istek, aynı girdi ile birden fazla kez gönderildiğinde yan etki **yaratmayacak** istektir. `GET`, `PUT`, `DELETE` doğası gereği idempotenttir — aynı URL'e tekrar istek atmak kaynak durumunu değiştirmez (veya kasten değiştirir ama tekrarlanabilir).

`POST` ise genellikle yeni bir kaynak **oluşturur**; aynı `POST`'u iki kez gönderirseniz iki kayıt oluşur.

<Note>
  Flextell API şu anda `Idempotency-Key` header'ı gibi yerleşik bir idempotency mekanizmasını desteklemez. Bu sayfa, bu eksiğe rağmen güvenli yazma yapmanız için önerilen örüntüleri özetler. İleride resmi bir `Idempotency-Key` desteği eklenirse [Changelog](/resources/changelog)'da duyururuz.
</Note>

## Hangi istekler dikkat ister?

Aşağıdaki yazma uçları yan etki yaratır ve **yanlışlıkla iki kez gönderilmesi hoş olmayan** sonuçlar doğurabilir:

* `POST /v1/appointments` — çift randevu
* `POST /v1/sales` — çift satış kaydı
* `POST /v1/sales/{id}/payments` — çift tahsilat
* `POST /v1/stocks/entry` — çift stok girişi
* `POST /v1/stocks/adjustment` — çift düzeltme
* `POST /v1/stocks/transfer` — çift transfer
* `POST /v1/conversations/{id}/messages` — aynı mesajın iki kere gönderilmesi

## Örüntü 1 — İstemcide kilit (en basit)

Bir butonu "gönderim sırasında" devre dışı bırakın:

```js theme={null}
async function createSale(payload) {
  if (submitting) return; // çift tıklamayı engelle
  submitting = true;

  try {
    return await api.post("/v1/sales", payload);
  } finally {
    submitting = false;
  }
}
```

Bu, tek bir sekmedeki çift tıklamayı kapsar ama sunucu tarafı tekrar sorununu (istemci 500 aldı ama istek aslında işlendi) çözmez.

## Örüntü 2 — Doğal anahtar ile kontrol

Veri modelinizin "doğal bir eşsiz anahtarı" varsa, isteği atmadan önce kaynağın zaten var olup olmadığını kontrol edin.

Örnek: Randevu oluştururken `(customer_id, starts_at, doctor_id)` doğal olarak eşsizdir. Önce bir `GET` ile aynı kombinasyona sahip aktif randevu var mı kontrol edin; yoksa oluşturun.

```js theme={null}
async function ensureAppointment(args) {
  const existing = await api.get("/v1/appointments", {
    params: {
      customer_id: args.customer_id,
      from: args.starts_at,
      to: args.starts_at,
    },
  });

  if (existing.data.length > 0) {
    return existing.data[0];
  }

  return api.post("/v1/appointments", args);
}
```

## Örüntü 3 — İstemci tarafı idempotency anahtarı

Kendi tarafınızda bir UUID üretip isteklerle eşleştirin. Aynı UUID için birden fazla gönderim olursa sunucuya atmadan önce yerel tablonuzdan önceki sonucu döndürün.

```js theme={null}
const localIdempotencyStore = new Map();

async function idempotentPost(uuid, url, body) {
  if (localIdempotencyStore.has(uuid)) {
    return localIdempotencyStore.get(uuid);
  }

  const pending = api.post(url, body);
  localIdempotencyStore.set(uuid, pending);

  try {
    return await pending;
  } catch (err) {
    localIdempotencyStore.delete(uuid); // hata durumunda yeniden denenebilsin
    throw err;
  }
}
```

Bu tek bir istemci oturumundaki duplikasyonu çözer ama farklı cihaz/oturumları korumaz.

## Örüntü 4 — Sunucu yanıtını kontrol etme

Çağrı zaman aşımına uğradı veya ağ hatası verdi; istek gerçekten işlendi mi bilmiyorsunuz. Tekrar göndermeden önce kaynağı sorgulayın:

```js theme={null}
try {
  return await api.post("/v1/sales", payload);
} catch (err) {
  if (err instanceof NetworkTimeout) {
    // Son 5 dakikada aynı müşteri/tutar kombinasyonuna sahip satış oluştu mu?
    const recent = await api.get("/v1/sales", {
      params: { customer_id, from: fiveMinutesAgo, to: now },
    });
    const maybe = recent.data.find(sameShape(payload));
    if (maybe) return maybe;
  }
  throw err;
}
```

## Öneriler

* **Para ve stok etkileyen uçlarda** mutlaka bir deduplikasyon örüntüsü kullanın.
* **Mesaj gönderimi** gibi yüksek hacimli uçlarda kullanıcıya "gönderiliyor..." göstergesi bırakın; ağ hatasında satırı "tekrar dene" butonuyla kullanıcıya bırakın.
* Otomatik retry yalnızca `429`, `5xx` ve ağ hatalarında uygulanmalı; `4xx` hatalarında isteği tekrarlamak sorunu çözmez.
