Tezgah ile web checkout aynı gömleği istediğinde
Teck'te en zor kısım barkod okumak değildi. İki satış kanalının aynı fiziksel parça için yarıştığı o milisaniyeyi doğru çözmekti — ve çözümün adı stok alanını güncellemek değil.
Teck'in tarifi basit: mobil uygulamadan barkod okutuyorsun, stok hem mağazada hem online mağazada düşüyor. Üç mağaza, iki yüzden fazla ürün, tek envanter.
Bu cümlenin içindeki zor kelime "tek". Çünkü aynı gömleğin son adedini, tezgahtaki müşteri ile web sitesindeki müşteri aynı anda isteyebiliyor. O anda ne olduğu, ürünün tamamını belirliyor.
Stok bir sayı değil
İlk sürümde ürün tablosunda bir stok alanı vardı. Satış olunca bir azalıyordu.
Bu modelin problemi, iki isteğin aynı anda geldiğinde ikisinin de aynı değeri okuması. İkisi de 1 görüyor, ikisi de 0 yazıyor, iki satış oluyor ve elde tek gömlek var. Klasik kayıp güncelleme.
Doğrusu, tıpkı escrow'da olduğu gibi, sayıyı saklamayı bırakmak. Stok hareketleri değişmez satırlar olarak yazılıyor — giriş, satış, iade, sayım düzeltmesi, mağazalar arası transfer — ve eldeki adet bu hareketlerin toplamı. Böylece "neden bu üründen üç tane var" sorusunun cevabı her zaman elinde oluyor.
Ama toplam almak eşzamanlılığı tek başına çözmüyor. Onun için ikinci parça gerekiyor.
Kaybeden temiz kaybetmeli
İki kanal aynı parça için yarıştığında ikisinin de başarılı olmaması gerekiyor. Ve kaybedenin temiz kaybetmesi gerekiyor: satış hiç olmamış gibi, kullanıcıya net bir mesajla.
Bunu uygulama katmanında çözmeye çalışmak — önce oku, sonra karar ver, sonra yaz — tam olarak yarışın kendisi. Karar veritabanının içinde verilmek zorunda. Satır kilidi, veya negatife düşmeyi imkânsız kılan bir kısıt. Kısıta çarpan istek kaybediyor ve tezgahtaki kasiyer "bu ürün az önce online satıldı" mesajını görüyor.
Kötü senaryo, iki satışın da başarılı görünüp gece raporunda eksi stok çıkması. O noktada artık hangi müşterinin siparişini iptal edeceğine sen karar vermiyorsun — biri kapıda öğreniyor.
Aşırı satış bir veri hatası değil. Bir müşterinin, satın aldığını sandığı şeyi alamaması.
Sayılabilir birim gömlek değil
İkinci yapısal karar: neyin sayıldığı.
"Gömlek" bir ürün. Ama satılan şey gömlek değil — L beden lacivert gömlek. Her beden ve renk çifti kendi barkodu, kendi stok hareketi, kendi fiyat geçmişi olan ayrı bir sayılabilir birim.
Bu ayrımı baştan yapmazsan, ürün tablosuna beden kolonu eklemekle başlıyorsun ve altı ay sonra üç ayrı yerde beden ayrıştıran kod oluyor. Doğru model, ürünün bir başlık, varyantın ise sayılan gerçek şey olması. Rapor tarafında ise ters yöne gidiyorsun: varyant satırlarını toplayıp ürün seviyesinde kâr-zarar çıkarıyorsun.
Kanal bir etiket değil, bir boyut
Üçüncüsü: her hareket hangi kanaldan geldiğini taşıyor — hangi mağaza, tezgah mı web mi.
Bu, "online ne kadar sattık" sorusunu cevaplamak için değil. Kampanya indirimi sonrası kanal bazında kâr-zarar çıkarmak için. Aynı gömlek mağazada tam fiyattan, web'de indirimli satılıyor; ikisini tek ortalamada toplarsan hangi kanalın gerçekten para kazandırdığını göremiyorsun.
Barkod okutmak da bir ağ isteği
Son parça, idempotency yazısında anlattığım şeyin buradaki karşılığı.
Kasiyer barkodu okutuyor, telefon isteği gönderiyor, mağaza Wi-Fi'ı hıçkırıyor, istemci tekrar deniyor. Aynı okutma iki kez giderse stok iki kez düşmemeli. Bu yüzden her okutma bir niyet kimliği taşıyor ve ikinci geliş ilk sonucun kopyasını alıyor.
Perakende yazılımında bunu atlamak kolay, çünkü ofiste test ederken ağ hep çalışıyor. Mağazada çalışmıyor. Ve orada hatanın bedeli, sıradaki müşterinin beklemesi.