E-ticaret
E-ticaret yazılımı, stoğun aslında bir söz olduğunu kabul etmeyi reddeden sistemlerin mezarlığıdır.
2/8 chapters written
Chapter 1
Stok bir sayı değil, bir rezervasyon
Neredeyse her e-ticaret sisteminde şu satır bir yerlerde duruyor:
UPDATE products SET stock = stock - 1 WHERE id = ? AND stock > 0
Tek başına doğru bir ifade. Sorun, bu ifadenin hangi soruyu cevapladığı.
İki farklı soru
Sistemde iki ayrı soru var ve ikisi sürekli birbirine karışıyor:
- Depoda kaç tane var? — fiziksel gerçek, sayım sonucu
- Kaç tane söz verebilirim? — ticari karar, hesaplanan bir değer
İkincisine sektörde available-to-promise deniyor ve birinciden farklı bir sayı. Depoda 10 tane olabilir ama:
- 3’ü ödemesi devam eden siparişlere ayrılmış
- 2’si iade olarak gelmiş ama henüz kontrol edilmemiş
- 1’i hasarlı, satılamaz
- 5’i yolda, üç gün sonra gelecek
Söz verebileceğin sayı 10 değil. Ve bu sayı sorgu anına bağlı — beş dakika sonra farklı.
Rezervasyon: sayaç yerine süreli söz
Doğru model şu: müşteri sepete eklediğinde ya da ödemeye geçtiğinde sayacı azaltmıyorsun, süreli bir rezervasyon yaratıyorsun.
rezervasyon
ürün, adet, sahip (oturum/sipariş), son_geçerlilik
Satılabilir miktar artık bir sayaç değil, bir hesap:
satılabilir = fiziksel − (süresi dolmamış rezervasyonlar) − (bloke)
Bu yapının üç avantajı var.
Süre dolduğunda kendiliğinden geri geliyor. Ödemesini yarım bırakan müşterinin tuttuğu stok, iptal işlemi çalışmasa bile on beş dakika sonra serbest kalıyor. Sayaç modelinde bunu telafi etmek için bir temizlik işi yazman ve o işin çalıştığından emin olman gerekiyor — çalışmadığı gün stok sızıyor.
Kimin tuttuğu belli. Sayaç azaldığında geriye bilgi kalmıyor: 7 yerine 4 yazıyor, neden bilmiyorsun. Rezervasyon modelinde “bu üç adedi şu üç oturum tutuyor” sorusunun cevabı var. Destek ekibi için fark budur.
Yarış koşulu tek yerde. Rezervasyon yaratma işlemi tek bir kritik bölge; gerisi okuma. Sayaç modelinde her akış — sepet, ödeme, iptal, iade — sayaca dokunuyor ve her biri ayrı bir yarış koşulu kaynağı.
Nerede tıkanıyor
Rezervasyon modeli bedava değil.
Popüler ürün tek satıra dönüşüyor. Bin kişi aynı anda aynı ürünü rezerve etmeye çalıştığında o ürünün satırı bir kilit noktası oluyor. Çözümü ürün bazında kilit yerine rezervasyon eklemek — yani satır güncellemek yerine satır yazmak — ve satılabilir miktarı toplamla hesaplamak. Yazma çakışması kalkıyor, okuma pahalılaşıyor.
Okuma pahalılaşınca önbellek geliyor, önbellek gelince tutarlılık gidiyor. Ürün sayfasında gösterdiğin “son 3 ürün” bilgisinin bayat olması kabul edilebilir. Sepete eklerken de bayat olması kabul edilemez. Bu iki okumayı ayırmadığın sürece ya yavaş ya yanlış olacak.
Kısmi sipariş kararı ticari, teknik değil. Üç kalemden ikisi rezerve edilebiliyorsa ne yapacağın bir ürün kararı: bekletmek, kısmi göndermek ya da tamamını reddetmek. Sistem üçünü de destekleyebilmeli; hangisinin seçileceği kodda sabit olmamalı.
Havacılığın tersi
İlginç olan, havacılığın bu problemi tam tersinden çözmesi: koltuktan fazla bilet satıp, açığı kapıda tazminatla kapatıyor.
Bunu yapabilmelerinin tek sebebi tazminatın önceden hesaplanabilir olması — hangi durumda ne ödeneceği düzenlemeyle belli. E-ticarette siparişi iptal edilen müşterinin kaybı düzenlenmiş değil; maliyet itibar tarafında ve ölçülemiyor.
Ölçemediğin riski optimize edemezsin. O yüzden biz rezerve ediyoruz, onlar fazla satıyor. Aynı problem, farklı bir maliyet fonksiyonu.
Chapter 2
Sepet bir tablo değil, bir zaman penceresi
Sepet, e-ticaret sistemlerinde en hafife alınan yapı. Görünüşte basit: ürün kimliği, adet, kullanıcı.
Gerçekte sepet bir zaman penceresi — içindeki her şey dışarıdaki dünya değiştikçe geçersizleşiyor.
Sepetteki her alan bayatlayabilir
Müşteri ürünü sepete koyduğu anda şunlar doğruydu:
| Alan | Ne kadar sonra bayatlar |
|---|---|
| Fiyat | Kampanya bitince, saniyeler içinde olabilir |
| Stok | Başkası aldığında |
| Kargo ücreti | Adres değişince, sepet tutarı eşiği geçince |
| Kampanya uygunluğu | Sepete başka ürün eklenince |
| Vergi | Teslimat ülkesi seçilince |
Yani sepet, dondurulmuş bir görüntü değil; her gösterimde yeniden hesaplanması gereken türev bir şey. Sepeti bir tablo olarak tutup içine fiyat yazan sistemler, o fiyatın ne zaman güncelleneceği sorusunu er ya da geç çözmek zorunda kalıyor — genellikle üretimde, bir şikâyetle.
Fiyat ne zaman donar
Bu sorunun teknik bir cevabı yok; ticari bir söz seçiyorsun.
Sepete eklerken donuyorsa müşteriye “gördüğün fiyat senindir” demiş oluyorsun. Sonucu: sepette iki hafta bekleyen ürün eski fiyatla satılıyor, ve zamlı dönemde sepetler birer opsiyon sözleşmesine dönüşüyor. Buna bir son kullanma süresi koymadıysan, bilançoda görürsün.
Ödemede donuyorsa müşteri sepete koyduğu fiyattan farklı bir tutar görebiliyor. Doğru olan bu ama açıkça söylenmesi gerekiyor; söylemezsen sepette 100 lira gören müşterinin ödemede 120 görmesi bir güven kaybı.
Ara çözüm çoğu sistemin yaptığı: fiyat kısa bir süre — tipik olarak 15-30 dakika — donuyor, süre dolduğunda sepet sessizce yeniden değerleniyor ve değişiklik varsa kullanıcıya gösteriliyor.
Hangisini seçersen seç, kodda tek bir yerde olmalı. Bu kararın iki farklı serviste iki farklı şekilde uygulandığı sistemler gördüm; sonuç, kimsenin üretemediği ama ayda birkaç kez olan fiyat tutarsızlıkları.
Sepet kimin
İkinci hafife alınan konu: sepetin sahibi.
Anonim kullanıcının sepeti bir çerezde ya da oturumda yaşıyor. Giriş yaptığında ne olacak? Eski sepetle yenisi birleşecek mi, üzerine mi yazacak, yoksa kullanıcıya mı sorulacak?
Üçü de savunulabilir. Savunulamaz olan, bu kararın verilmemiş olması — o zaman davranış hangi servisin önce çalıştığına bağlı kalıyor ve kullanıcı bazen sepetini kaybediyor.
Aynı soru çoklu cihazda tekrar çıkıyor: telefonda ve masaüstünde açık iki sepet. Birleştirme kuralın yoksa son yazan kazanıyor, ve müşteri ne olduğunu anlamıyor.
Terk edilen sepet bir hata değil
Sepetlerin büyük çoğunluğu siparişe dönüşmüyor ve bu normal. Sepet bir niyet sinyali, bir taahhüt değil.
Bunu kabul etmek iki şeyi değiştiriyor. Birincisi, sepet verisini kalıcı sipariş verisiyle aynı yerde tutmak gereksiz — farklı ömre sahip veriyi aynı deponun aynı garantileriyle saklıyorsun. İkincisi, terk edilmiş sepetler bir temizlik problemi değil, bir veri kaynağı: hangi adımda kaybedildiği ürün ekibinin en değerli girdisi.
Sepeti geçici bir pencere olarak modellemek, hem depolama kararını hem de ürün kararını netleştiriyor.