TL;DR: 14 saatte bir üretim seviyesinde e-ticaret sepeti oluşturdum, Laravel Volt’u keşfetmek için. Bu makale, önemli mühendislik kararlarına odaklanıyor: eşzamanlılık yönetimi, kısmi başarısızlık kurtarma, veri anlık görüntüleme ve sorgu optimizasyonu. Tüm kaynak kodu GitHub’da mevcut.
🎯 Bağlam
🎯 Bağlam
Yılbaşı tatili sırasında Laravel Volt kullanarak üretim seviyesi bir e-ticaret sepeti geliştirmek için zaman ayırdım. Proje, ilk committen son düzenlemelere kadar yaklaşık 14 saat sürdü. Bu bir eğlence projesi değildi, teknik bir değerlendirme için verilen fırsattı. Stack’imi seçme esnekliğim vardı ve ilk kez Laravel Volt denemek istedim. Nihayetinde ekip farklı bir uygulama yaklaşımını tercih etti ve yollarımız dostça ayrıldı. Ancak bu deneyim bana derinlemesine düşünmeyi ve mühendislik yargısını zorladı.
📦 Tam kaynak kodu buradan erişilebilir: https://github.com/Ojsholly/laravel-ecommerce-cart
Bu makale, UI veya özelliklerin tamlığı hakkında değil. Gerçek para, gerçek envanter ve gerçek kullanıcı beklentileri yöneten sistemleri geliştirirken dikkate almanız gereken arka uç kararları üzerine.
🛠️ Teknoloji Yığını
🛠️ Teknoloji Yığını
| Katman | Teknoloji |
|---|---|
| Framework | Laravel 12 |
| Dil | PHP 8.4 |
| Frontend | Livewire 3 + Volt (ilk kez Volt kullanımı) |
| Stil | Tailwind CSS |
| Veritabanı (Geliştirme) | PostgreSQL |
| Veritabanı (Test) | SQLite (bellekte) |
| Arka Plan İşlemleri | Laravel Queues & Scheduler |
| Test | Pest |
| Versiyon Kontrolü | GitHub |
Volt tercihimin sebebi, belirgin Livewire sınıfları yazmadan reaktif bileşenler oluşturmayı denemekti. Öğrenme eğrisi beklediğimden daha dikti, ancak bu durum gereksiz kodları azalttı.
🎯 Önemli Problemler
🎯 Önemli Problemler
E-ticaret sepeti oluştururken, ilginç problemler UI’da değil, uç noktada bulunur:
- ⚡ İki kullanıcı son ürünü aynı anda satın alırsa ne olur?
- 🛒 Bir sepetin içinde bazı ürünler tükendiğinde kısmi kontrol nasıl yapılır?
- 📧 Düşük stok bildirimlerinin gereksiz yere adminleri rahatsız etmesini nasıl engellersiniz?
- 📸 Ürünler değişse bile geçmiş sipariş verilerinin doğru kalmasını nasıl sağlarsınız?
Bunlar, genellikle junior mühendislerin gözden kaçırdığı ve üretimde olaylara neden olan sorunlardır.
1. ⚡ Eşzamanlılık ve Satır Seviyesinde Kilitleme
1. ⚡ Eşzamanlılık ve Satır Seviyesinde Kilitleme
Ödeme işleminin en kritik kısmı stok doğrulamasıdır. Satırları düzgün kilitlemezseniz, envanteri aşırı satarsınız.
Problem: Yarış Koşulları
Problem: Yarış Koşulları
İşte basit bir yaklaşım (bunu yapmayın):
// ❌ Yarış durumu: iki istek de stok = 1'i görebilir
$product = Product::find($productId);
if ($product->stock_quantity >= $quantity) {
$product->decrement('stock_quantity', $quantity);
}
Problem: Stok kontrolü ile azaltma işlemi arasında başka bir istek girebilir. Her iki istek de stock_quantity = 1 olduğuna karar verebilir ve her ikisi de devam ederse, sadece bir tane olan üründen iki adet satış yapabilirsiniz.
Yarış Durumunu Görselleştirme
Yarış Durumunu Görselleştirme
| Zaman Çizelgesi | Kullanıcı A | Kullanıcı B | Veritabanı Stoku |
|---|---|---|---|
| T1 | Stok okuma → 1 görüyor | 1 | |
| T2 | Stok okuma → 1 görüyor | 1 | |
| T3 | Kontrol: 1 >= 1 ✅ | 1 | |
| T4 | Kontrol: 1 >= 1 ✅ | 1 | |
| T5 | Azalt → stok = 0 | 0 | |
| T6 | Azalt → stok = -1 ❌ | -1 |
Sonuç: Her iki alışveriş işlemi de başarılı oluyor, ancak envanter artık negatif. Aşırı satış yaptınız.
Çözüm: İyimser Kilitleme
Çözüm: İyimser Kilitleme
// ✅ İşlem süresince satırı kilitleyin
$product = Product::lockForUpdate()->find($productId);
if ($product && $product->hasStock($quantity)) {
$product->decrement('stock_quantity', $quantity);
}
Bu, bir veritabanı işlemi içinde sarıldığı için, kilit, işlem onaylanana kadar tutulur. Başka bir istek, işlem tamamlanana kadar o satırı okuyamaz veya değiştiremez.
Tam Ödeme İşlemi Uygulaması
Tam Ödeme İşlemi Uygulaması
public function processCheckout(Cart $cart): Order
{
return DB::transaction(function () use ($cart) {
[$availableItems, $unavailableItems] = $this->validateStock($cart);
<span class="k">if</span> <span class="p">(</span><span class="nv">$availableItems</span><span class="o">-></span><span class="nf">isEmpty</span><span class="p">())</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nc">InsufficientStockException</span><span class="p">(</span><span class="s1">'Tüm ürünler stokta yok.'</span><span class="p">);</span>
<span class="p">}</span>
<span class="nv">$order</span> <span class="o">=</span> <span class="nc">Order</span><span class="o">::</span><span class="nf">create</span><span class="p">([</span><span class="cm">/* ... */</span><span class="p">]);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$availableItems</span> <span class="k">as</span> <span class="nv">$item</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">createOrderItem</span><span class="p">(</span><span class="nv">$order</span><span class="p">,</span> <span class="nv">$item</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">decrementStock</span><span class="p">(</span><span class="nv">$item</span><span class="o">-></span><span class="n">product</span><span class="p">,</span> <span class="nv">$item</span><span class="o">-></span><span class="n">quantity</span><span class="p">);</span>
<span class="p">}</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">removeAvailableItemsFromCart</span><span class="p">(</span><span class="nv">$cart</span><span class="p">,</span> <span class="nv">$availableItems</span><span class="p">);</span>
<span class="k">return</span> <span class="nv">$order</span><span class="p">;</span>
<span class="p">});</span>
}
private function validateStock(Cart $cart): array
{
$availableItems = collect();
$unavailableItems = collect();
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$cart</span><span class="o">-></span><span class="n">items</span> <span class="k">as</span> <span class="nv">$item</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$product</span> <span class="o">=</span> <span class="nc">Product</span><span class="o">::</span><span class="nf">lockForUpdate</span><span class="p">()</span><span class="o">-></span><span class="nf">find</span><span class="p">(</span><span class="nv">$item</span><span class="o">-></span><span class="n">product_id</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$product</span> <span class="o">&&</span> <span class="nv">$product</span><span class="o">-></span><span class="nf">hasStock</span><span class="p">(</span><span class="nv">$item</span><span class="o">-></span><span class="n">quantity</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$availableItems</span><span class="o">-></span><span class="nf">push</span><span class="p">(</span><span class="nv">$item</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nv">$unavailableItems</span><span class="o">-></span><span class="nf">push</span><span class="p">(</span><span class="nv">$item</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">[</span><span class="nv">$availableItems</span><span class="p">,</span> <span class="nv">$unavailableItems</span><span class="p">];</span>
}
💡 Ana Fikir: Satır seviyesinde kilitleme olmadan, öfkeli müşterileriniz olacak çünkü ürettiklerinizin stokta olmadığını ödeyecekler. Bununla, yük altında doğru davranan bir sisteminiz olur.
2. 🛒 Kısmi Başarısızlıkları Uygun Şekilde Yönetme
2. 🛒 Kısmi Başarısızlıkları Uygun Şekilde Yönetme
Karşılaştığım yaygın bir senaryo:
- Kullanıcı sepete 5 ürün ekler
- Başka bir kullanıcı bu ürünlerden birini satın alır, stok azalır
- İlk kullanıcı ödeme yapmak ister
Ne olmalı?
| Yaklaşım | Junior Uygulama ❌ | Senior Uygulama ✅ |
|---|---|---|
| Hata Yönetimi | Tüm ödeme işlemini generik hata ile başarısız yap | Hangi ürünlerin mevcut olduğunu belirle |
| Sepet Yönetimi | Tüm ürünleri sil (kullanıcı niyetini kaybettirir) | Sadece mevcut ürünleri işleme al |
| Stok Yönetimi | Devam et ve aşırı satışı yap | Mevcut olmayan ürünleri sepette tut |
| Kullanıcı Geri Bildirimi | Kafa karıştırıcı hata mesajı | Satın alınanlar hakkında net geri bildirim |
Uygulama
Uygulama
// Mevcut ve mevcut olmayan ürünleri ayırın
[$availableItems, $unavailableItems] = $this->validateStock($cart);
// Sadece mevcut ürünleri işleyin
$pricing = $this->priceCalculationService->calculateOrderPricing($availableItems);
// Sadece satın alınanları çıkarın
$this->removeAvailableItemsFromCart($cart, $availableItems);
Temel içgörü: Kullanıcı niyetini koruyun. Eğer 5 ürün almak istemişse ve sadece 4’ü mevcutsa, 4’ü satın almasını sağlayın ve 5’incisini sepette bırakın. Onların yeniden başlamasına neden olmayın.
Frontend Yönetimi
Frontend Yönetimi
Frontend’de mevcut olmayan ürünler açık bir şekilde belirgin hale getirilmeli:
- ✅ Görsel göstergeler (opaklık, gri tonlamalı görseller)
- ✅ “Stokta Yok” etiketleri
- ✅ Fiyat hesaplamalarından çıkarılmıştır
- ✅ Tüm ürünler mevcut değilse, ödeme butonu devre dışı kalır
💡 Ana Fikir: Bu sadece iyi bir UX değil, doğru davranıştır. Kısmi başarısızlık, dağıtılmış sistemlerde bir gerçektir. Bunu uygun bir şekilde yönetin.
3. 📸 Tarihsel Doğruluk İçin Veri Anlık Görüntüleme
3. 📸 Tarihsel Doğruluk İçin Veri Anlık Görüntüleme
Sıkça karşılaştığım bir yanlış: sipariş kalemlerinde sadece yabancı anahtarları saklamak.
// ❌ Ürün silindiğinde veya fiyatı değiştiğinde ne olur?
OrderItem::create([
'order_id' => $order->id,
'product_id' => $product->id,
'quantity' => $quantity,
]);
Altı ay sonra ürün silinir veya fiyatı değiştirilirse, sipariş tarihiniz bozulur. Müşterilere ne kadar ödediğinizi gösteremezsiniz.
Çözüm: satın alma anında ürün verilerini anlık görüntüleme.
// ✅ Tarihsel doğruluğu koruyun
OrderItem::create([
'order_id' => $order->id,
'product_id' => $product->id,
'quantity' => $quantity,
'price_snapshot' => $product->price,
'product_snapshot' => $product->toSnapshot(),
]);
toSnapshot() metodu, siparişi yeniden oluşturmak için gereksinim duyulan her şeyi yakalar:
public function toSnapshot(): array
{
return [
'id' => $this->id,
'uuid' => $this->uuid,
'name' => $this->name,
'description' => $this->description,
'price' => $this->price,
'images' => $this>images,
'primary_image' => $this->primary_image,
];
}
💡 Ana Fikir: Siparişler yasal belgeleridir. Değişen ürün verileri bile olsa, değişmez ve doğru olmaları gerekir.
4. 📧 Arka Plan İşleri & Bildirim Spam’inden Kaçınma
4. 📧 Arka Plan İşleri & Bildirim Spam’inden Kaçınma
Düşük stok bildirimleri yaygın bir özelliktir. Naif bir uygulama:
// ❌ Stok eşiği altına her düşündüğünde bir bildirim gönder
if ($product->stock_quantity < $lowStockThreshold) {
SendLowStockNotification::dispatch($product);
}
Problem: Stok 5 ise ve eşik 10 ise, stok 0’a ulaşana kadar her satış sonrası bildirim göndereceksiniz. Bu durum 5 kez aynı konuda e-posta göndermeniz demektir.
Çözüm: sadece eşiği geçerken bildirim gönderin.
private function decrementStock(Product $product, int $quantity): void
{
$lowStockThreshold = config('cart.low_stock_threshold', 10);
$stockBeforeDecrement = $product->stock_quantity;
<span class="nv">$product</span><span class="o">-></span><span class="nf">decrement</span><span class="p">(</span><span class="s1">'stock_quantity'</span><span class="p">,</span> <span class="nv">$quantity</span><span class="p">);</span>
<span class="nv">$stockAfterDecrement</span> <span class="o">=</span> <span class="nv">$product</span><span class="o">-></span><span class="nf">fresh</span><span class="p">()</span><span class="o">-></span><span class="n">stock_quantity</span><span class="p">;</span>
<span class="c1">// Sadece eşiği geçerken bildirim gönderin</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$stockBeforeDecrement</span> <span class="o">></span> <span class="nv">$lowStockThreshold</span>
<span class="o">&&</span> <span class="nv">$stockAfterDecrement</span> <span class="o"><</span> <span class="nv">$lowStockThreshold</span><span class="p">)</span> <span class="p">{</span>
<span class="nc">SendLowStockNotification</span><span class="o">::</span><span class="nf">dispatch</span><span class="p">(</span><span class="nv">$product</span><span class="p">);</span>
<span class="p">}</span>
}
💡 Ana Fikir: Bildirim yorgunluğu gerçektir. Adminler, spam gönderirseniz, uyarılarınızı dikkate almaz. Her eşik geçişinde bir bildirim gönderin, satış başına değil.
5. 📊 Günlük Satış Raporları & Sorgu Optimizasyonu
5. 📊 Günlük Satış Raporları & Sorgu Optimizasyonu
Bir diğer yaygın özellik: e-posta ile gönderilen günlük satış raporları. Zorluk, veri toplamayı etkili bir şekilde yapabilmektir, N+1 sorgularından kaçınmak da gerekir.
İşte iş yapısı:
public function handle(): void
{
$stats = $this->calculateStats();
$recentOrders = $this->getRecentOrders();
$topProducts = $this->getTopSellingProducts();
<span class="nc">Mail</span><span class="o">::</span><span class="nf">to</span><span class="p">(</span><span class="nv">$adminEmail</span><span class="p">)</span><span class="o">-></span><span class="nf">send</span><span class="p">(</span>
<span class="k">new</span> <span class="nc">DailySalesReport</span><span class="p">(</span><span class="nv">$stats</span><span class="p">,</span> <span class="nv">$recentOrders</span><span class="p">,</span> <span class="nv">$topProducts</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="n">date</span><span class="p">)</span>
<span class="p">);</span>
}
İlginç kısım, getTopSellingProducts(). Şunları yapmanız gerekir:
- Ürünlere göre satışları toplamak
- Ürün anlık görüntülerini almak (ürünler değişebilmekte)
- N+1 sorgularından kaçınmak
İşte bunu nasıl yaptım:
private function getTopSellingProducts(): Collection
{
// Satış verilerini toplamak için tek sorgu
$topProductsData = Order::completed()
->whereDate('orders.created_at', $this->date)
->join('order_items', 'orders.id', '=', 'order_items.order_id')
->selectRaw('
order_items.product_id,
sum(order_items.quantity) as total_quantity,
sum(order_items.quantity * order_items.price_snapshot) as total_sales
')
->groupBy('order_items.product_id')
->orderByDesc('total_quantity')
->limit(5)
->get();
<span class="c1">// Ürün anlık görüntülerini alan tek sorgu</span>
<span class="nv">$orderItemsByProductId</span> <span class="o">=</span> <span class="nc">OrderItem</span><span class="o">::</span><span class="nf">whereIn</span><span class="p">(</span><span class="s1">'product_id'</span><span class="p">,</span> <span class="nv">$topProductsData</span><span class="o">-></span><span class="nf">pluck</span><span class="p">(</span><span class="s1">'product_id'</span><span class="p">))</span>
<span class="o">-></span><span class="nf">whereHas</span><span class="p">(</span><span class="s1">'order'</span><span class="p">,</span> <span class="k">fn</span><span class="p">(</span><span class="nv">$q</span><span class="p">)</span> <span class="o">=></span> <span class="nv">$q</span><span class="o">-></span><span class="nf">completed</span><span class="p">()</span><span class="o">-></span><span class="nf">whereDate</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="n">date</span><span class="p">))</span>
<span class="o">-></span><span class="nf">get</span><span class="p">()</span>
<span class="o">-></span><span class="nf">keyBy</span><span class="p">(</span><span class="s1>'product_id'</span><span class="p">);</span>
<span class="c1">// Toplama verileri anlık görüntülerle eşleştiriliyor</span>
<span class="k">return</span> <span class="nv">$topProductsData</span><span class="o">-></span><span class="nf">map</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="nv">$item</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$orderItemsByProductId</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$orderItem</span> <span class="o">=</span> <span class="nv">$orderItemsByProductId</span><span class="o">-></span><span class="nf">get</span><span class="p">(</span><span class="nv">$item</span><span class="o">-></span><span class="n">product_id</span><span class="p">);</span>
<span class="nv">$snapshot</span> <span class="o">=</span> <span class="nv">$orderItem</span><span class="o">-></span><span class="n">product_snapshot</span> <span class="o">??</span> <span class="p">[];</span>
<span class="k">return</span> <span class="p">[</span>
<span class="s1>'name'</span> <span class="o">=></span> <span class="nv">$snapshot</span><span class="p">[</span><span class="s1>'name'</span><span class="p">]</span> <span class="o">??</span> <span class="s1>'Bilinmeyen Ürün'</span><span class="p">,</span>
<span class="s1>'quantity'</span> <span class="o">=></span> <span class="nv">$item</span><span class="o">-></span><span class="n">total_quantity</span><span class="p">,</span>
<span class="s1>'revenue'</span> <span class="o">=></span> <span class="nb">number_format</span><span class="p">((</span><span class="n">float</span><span class="p">)</span><span class="nv">$item</span><span class="o">-></span><span class="n">total_sales</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span>
<span class="p">];</span>
<span class="p">});</span>
}
💡 Ana Fikir: N+1 sorguları performansı öldürür. N ürün için N+1 sorgudan daha iyi olan, iki sorgu yapmaktır.
🏗️ Kaygıların Ayrılması
🏗️ Kaygıların Ayrılması
Süreç boyunca benimsediğim bir model: iş mantığını denetleyicilerden ve Livewire bileşenlerinden uzak tutmak.
Bileşenler sade olmalıdır:
public function placeOrder(): void
{
try {
$checkoutService = app(CheckoutService::class);
$order = $checkoutService->processCheckout($this->cart);
<span class="nv">$this</span><span class="o">-></span><span class="nf">dispatch</span><span class="p">(</span><span class="s1>'cart-updated'</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">dispatch</span><span class="p">(</span><span class="s1>'notify'</span><span class="p">,</span> <span class="n">message</span><span class="o">:</span> <span class="s1>'Sipariş başarıyla verildi!'</span><span class="p">,</span> <span class="n">type</span><span class="o">:</span> <span class="s1>'success'</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">redirect</span><span class="p">(</span><span class="nf">route</span><span class="p">(</span><span class="s1>'orders.show'</span><span class="p">,</span> <span class="nv">$order</span><span class="p">),</span> <span class="n">navigate</span><span class="o">:</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">\Exception</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">dispatch</span><span class="p">(</span><span class="s1>'notify'</span><span class="p">,</span> <span class="n">message</span><span class="o">:</span> <span class="nv">$e</span><span class="o">-></span><span class="nf">getMessage</span><span class="p">(),</span> <span class="n">type</span><span class="o">:</span> <span class="s1>'error'</span><span class="p">);</span>
<span class="p">}</span>
}
Tüm karmaşa CheckoutService‘da bulunur. Bu, test etmeyi kolaylaştırır, mantığı yeniden kullanılabilir hale getirir ve kod tabanını daha sürdürülebilir kılar.
💭 Volt Hakkında Öğrendiklerim
💭 Volt Hakkında Öğrendiklerim
Laravel Volt’u kullanmaktaki ilk deneyimimdi ve karışık bir deneyimdi.
Beğendiğim şeyler:
- Geleneksel Livewire sınıflarından daha az gereksiz kod
- Basit bileşenler için daha hızlı iterasyon
- Prototipleme için iyi
Karşılaştığım zorluklar:
- Hesaplanmış özellikler belirli adlandırma geleneklerine ihtiyaç duyar (
getXProperty()) - Açık sınıf dosyaları olmadan hata ayıklamak daha zordur
- IDE desteği, geleneksel Livewire kadar güçlü değil
Tekrar kullanır mıydım? Hızlı prototipleme için, evet. Büyük bir üretim uygulaması için, daha iyi araçlar ve keşfedilebilirlik için geleneksel Livewire sınıflarını kullanmayı tercih edebilirim.
🎓 Yansımalar
🎓 Yansımalar
Bu sepeti 14 saatte oluşturmak zorundaydım. Aşırı mühendislik yapmaya veya taraf tutmaya vaktim yoktu. Öncelikle doğruluğa, sonrasında cilaya odaklanmak zorundaydım.
Önemli Olanlar:
- ✅ İşlemler ve kilitleme
- ✅ Kısmi başarısızlıkları uyumlu bir şekilde ele almak
- ✅ Veri anlık görüntüleme için tarihsel doğruluğu sağlamak
- ✅ Bildirim spamından kaçınmak
- ✅ Sorgu optimizasyonu
Bu süre içinde önemli olmayanlar:
- ⏸️ Mükemmel UI cilası
- ⏸️ Kapsamlı admin kontrol panelleri
- ⏸️ Ödeme geçidi entegrasyonu
💡 Ana Fikir: Bu tür bir önceliklendirme, senior mühendisliği tanımlar: neyi inşa edeceğinizi, neyi erteleyeceğinizi ve neyi tamamen atlayacağınızı bilmek.
🎯 Son Düşünceler
🎯 Son Düşünceler
Ekip nihayetinde farklı bir teknoloji yığını ile ilerlemeye karar verdi. Bu normal. Her proje için uygun çözüm olmayabilir, ve bu sorun değil. Ancak, bu alıştırma bana günlük işimde pek karşılaşmadığım problemleri düşünme fırsatı sundu ve Volt’u gerçek dünya bağlamında keşfetme şansı verdi.
Repo açık kaynaklı. Kilitleme mantığı kullanışlı bulursanız yıldız verin: https://github.com/Ojsholly/laravel-ecommerce-cart
Kod tabanı şunları içeriyor:
- ✅ 123 geçerli test (Pest)
- ✅ Eşzamanlılık idaresi ile tam ödeme akışı
- ✅ Bildirimler ve raporlar için arka plan işleri
- ✅ Kısmi ödeme desteği
- ✅ Ürün anlık görüntüleme
- ✅ Sorgu optimizasyonu
Bu mükemmel değil, ancak doğru. Ve üretim sistemlerinde, doğruluk önemlidir.
🔗 Bağlantılar ve Kaynaklar
🔗 Bağlantılar ve Kaynaklar
- 📦 GitHub Deposu: https://github.com/Ojsholly/laravel-ecommerce-cart
- ⭐ Depoyu yıldızlayın eğer kilitleme mantığını veya kısmi hata yönetimini kullanışlı bulduysanız
- 💬 Sorularınız var mı? İletişim kurmaktan çekinmeyin—her zaman Laravel mimarisi ve mühendislik karşıtları hakkında konuşmaktan mutluluk duyarım.
Okuduğunuz için teşekkürler! Eğer bu makale e-ticaret sepeti uygulamanızı farklı düşünmenizi sağladıysa, ekibinizle paylaşmayı düşünün.
Kaynak: Orijinal Makale
- 🎯 Bağlam
- 🛠️ Teknoloji Yığını
- 🎯 Önemli Problemler
- 1. ⚡ Eşzamanlılık ve Satır Seviyesinde Kilitleme
- 2. 🛒 Kısmi Başarısızlıkları Uygun Şekilde Yönetme
- 3. 📸 Tarihsel Doğruluk İçin Veri Anlık Görüntüleme
- 4. 📧 Arka Plan İşleri & Bildirim Spam’inden Kaçınma
- 5. 📊 Günlük Satış Raporları & Sorgu Optimizasyonu
- 🏗️ Kaygıların Ayrılması
- 💭 Volt Hakkında Öğrendiklerim
- 🎓 Yansımalar
- 🎯 Son Düşünceler
- 🔗 Bağlantılar ve Kaynaklar


