Tech Issues & Solutions
Gerçek projelerde karşılaştığım "küçük" ama can sıkan problemler ve "hayat kurtaran" çözümleri.
Tek Kod Tabanı, 5 Marka: Layer Mimarisi
Aynı ürün katalogu, sepet ve checkout akışını paylaşan ama farklı tema, footer ve bazı sayfaları olan 5 ayrı marka (Tusdata, Klinisyen, TUSEM, METODOMY, TusTime) vardı. İlk yaklaşım her marka için ayrı repo / ayrı build idi; bu da her bug fix'i 5 kez yapmak demekti. Ortak kodu tek yerde tutup marka bazında yalnızca farklılıkları override etmek gerekiyordu.
Yavaş ERP/Fatura Entegrasyonunun Frontend'e Yansıması
Sipariş onayında backend, ERP'ye fatura kesiyordu ve bu çağrı bazen çok yavaştı. Frontend'de kullanıcı "ödeme başarısız mı?" diye butona tekrar basıyor, çift sipariş riski ve panik doğuyordu. Yavaş/değişken süreli işlemde kullanıcıyı bilgilendirip çift gönderimi engellemek gerekiyordu.
Üçüncü Taraf Scriptler Açılış Hızını Öldürüyordu
GTM, GA4, Hotjar, Meta Pixel, JivoSite (chat) ve reCAPTCHA v3 statik <script> olarak HTML'e gömülüydü; LCP ve INP kötüydü, özellikle mobilde. reCAPTCHA tek başına ~500KB. Tracking'i bozmadan Core Web Vitals'ı düzeltmek gerekiyordu.
reCAPTCHA'yı Kullanıcı Tıklamadan Hazır Etmek
reCAPTCHA en ağır script ama sadece bağış/login formlarında lazım. Her sayfaya koymak israf; sadece submit anında yüklemek "tık → bekleme" yaşatıyor. Heavy script'i yalnızca gerektiğinde, ama kullanıcı butona basmadan ÖNCE hazır etmek gerekiyordu.
Telefon Numarasında Çift +90 Prefix Bug'ı
Uluslararası telefon normalizasyonundan sonra +90+90..., +9090..., 0905... gibi bozuk numaralar oluşuyordu; backend reddediyordu. Hangi formatta gelirse gelsin tek, temiz +90 (5XX) ... formatı lazımdı.
Tek Frontend, Birden Çok Domain (Multi-Tenant)
Aynı Nuxt uygulaması birden fazla domain'den servis ediliyor (white-label bağış siteleri). API çağrıları çağrıldığı domain'e gitmeli — ama SSR ve client'ta "şu anki domain" farklı yerlerden okunuyor. Hem server-render hem hidrasyon sonrası doğru baseURL gerekiyordu.
GA4 Funnel Raporları Bozuluyordu (dataLayer Merge Tuzağı)
Kullanıcı sepete bir kampanya ekleyip hemen başka kampanya eklediğinde, GA4 Enhanced Ecommerce raporlarında ikinci event ilk event'in ürünlerini de içeriyordu → funnel verisi yanlıştı.
Backward-Compatible API Şema Geçişi
Bağış sepetinde niyet (intent_id) eskiden detail seviyesinde tek alandı, backend her hissedara aynı niyeti kopyalıyordu. Yeni gereksinim: her hissedar (shareholder) kendi niyetini taşısın. Sahada eski payload gönderen client'lar vardı; geçişte eski istekleri bozmamak gerekiyordu.
401 Yönetimini Merkezîleştirmek
Token süresi dolduğunda her servis çağrısında ayrı 401 handle etmek kod tekrarı yaratıyordu. Oturum sonlanmasını tek noktadan yönetmek gerekiyordu.
Çok Markalı Tema: Tailwind v4 + CSS Değişkenleri
Her markanın kendi primary/accent rengi vardı ama componentleri (buton, badge, kart) ortaktı. Renkleri component prop'u ile geçmek her yerde :class kirliliği yaratıyordu. Componentleri renkten bağımsız yazıp, rengi tek noktadan markaya göre beslemek gerekiyordu.
SSR ile Auth Token Yarış Durumu
Sayfalar SSR ile render ediliyordu. Korumalı endpoint'lere ilk istek bazen Bearer token olmadan gidiyor, kullanıcı login olmasına rağmen 401 yiyordu — özellikle sayfa yenilemede. Token'ın hem server hem client tarafında tutarlı okunması, fetch'in token hazır olmadan ateşlenmemesi gerekiyordu.
Sepet İş Kuralı: Uzmanlık Karıştırma Kısıtı
Ürünler uzmanlık dalına göreydi (TUS / DUS / YDUS). İş kuralı: bir kullanıcı aynı sepette farklı uzmanlık paketlerini karıştıramaz. Ama bu kontrol başta sadece checkout'ta vardı; kullanıcı en sona kadar gelip "olmaz" duvarına çarpıyordu — kötü UX.
Eski URL'lerin SEO Kaybı Olmadan Taşınması (301)
Ürün URL'leri /urunler/<kategori>/<urun> formatındaydı, yeni format /<kategori>/<urun> olacaktı. Eski linkler Google'da indeksliydi ve dışarıdan paylaşılmıştı; kırılırsa SEO ve kullanıcı kaybı olurdu. Tüm eski linkleri yeni formata, arama motoru dostu (kalıcı) şekilde yönlendirmek gerekiyordu.
Form Validasyonunda Tekrarı Bitirmek: Merkezi Yup Şemaları
İletişim, adres, kredi kartı, kayıt, profil... onlarca form vardı. Validasyon kuralları (TC kimlik, IBAN, telefon) component içinde dağınık ve kopyala-yapıştırdı; bir kuralı değiştirmek birden çok yeri düzeltmek demekti. Validasyonu tek kaynakta toplayıp tekrar kullanılabilir yapmak gerekiyordu.
Checkout'ta Ödeme Tipine Göre Dallanan Akış
Checkout iki ödeme yolu içeriyordu: kredi kartı ve banka havalesi. İki akışın alanları, doğrulaması ve sonrası farklıydı; tek dev component spagetti olmaya başlamıştı. Ödeme akışlarını ayrıştırıp checkout sayfasını yönetilebilir tutmak gerekiyordu.
Tutarlı Hata Yönetimi: [err, data] Tuple + extractApiError
Servisler farklı şekillerde hata fırlatıyordu; bazıları throw, bazıları null dönüyordu. Her component kendi try/catch'ini farklı yazıyor, hata mesajları tutarsızdı. Tüm API katmanında tek tip, tahmin edilebilir hata kontratı kurmak gerekiyordu.
Ürün Filtreleme ve Karşılaştırma State Yönetimi
Ürün listesinde çoklu filtre (uzmanlık, ürün tipi, fiyat) ve maksimum 2 ürünlük karşılaştırma özelliği vardı. Filtre state'i sayfa yenilemede kayboluyor, karşılaştırma seçimi sayfalar arası tutulamıyordu. Durumu kalıcı ve performanslı yönetmek gerekiyordu.
Optimizing a Slow Data Dashboard (10k+ Rows)
Lojistik projemizde, 10.000+ satırlık sevkiyat verisini tek bir tabloda göstermemiz gerekiyordu. Kullanıcı filtreleme yaptığında tarayıcı 2-3 saniye donuyor (Main Thread Blocking) ve scroll performansı çok düşüktü. Müşteri "Excel gibi akıcı olsun" istiyordu.
Race Conditions in Payment Flow
Ödeme sayfasında kullanıcı "Öde" butonuna sabırsızlanıp iki kez tıkladığında, backend'de iki ayrı sipariş oluşuyor ve karttan iki kez çekim yapılıyordu. Ayrıca internet yavaşken kullanıcı işlemin bittiğini sanıp sayfayı kapatıyordu.
Nuxt 3 Hybrid Rendering Strategy
E-ticaret sitemizde ana sayfa ve ürün detay sayfalarının SEO için sunucuda (SSR) render edilmesi gerekiyor, ancak sepet ve kullanıcı paneli gibi dinamik sayfaların sunucu yükünü artırmaması lazım. Tüm siteyi SSR yapmak maliyetli ve yavaş, tamamen SPA yapmak ise SEO'yu öldürüyor. Hibrit bir yapıya ihtiyacımız var.
Scalable Vue 3 Composables
Büyük ölçekli bir dashboard uygulamasında, veri çekme, hata yönetimi ve loading durumları her bileşende tekrar ediliyor. Mixins kullanımı (Vue 2 stili) kodun takibini zorlaştırıyor ve "naming collision" sorunlarına yol açıyor. Mantığı UI'dan tamamen ayırıp, tip güvenli (TypeScript) ve yeniden kullanılabilir bir yapı kurmamız gerekiyor.
Tailwind CSS Multi-Theme System
SaaS projemizde müşteriler kendi marka renklerini (Primary/Secondary) seçmek istiyor. Tailwind'in standart `colors` objesi build-time'da oluştuğu için run-time'da renk değiştiremiyoruz. CSS değişkenleri (CSS Variables) ile Tailwind'i entegre edip, performanstan ödün vermeden dinamik tema desteği sunmalıyız.
Hydration Mismatch Error
Sunucuda render edilen HTML ile client tarafındaki HTML eşleşmiyor. Genellikle tarih formatlama veya rastgele sayı üretiminde oluşur.
useEffect Infinite Loop
useEffect içinde state güncelleniyor ve bu state dependency array içinde var. Bu sonsuz döngüye yol açar.
Dynamic Class Purging
Dinamik olarak oluşturulan classlar (örn: `bg-${color}-500`) production build'de kayboluyor.
Layout Shift (CLS)
Animasyonlar yüklenirken sayfa düzeni kayıyor. Özellikle `layout` prop'u kullanıldığında.
v-if vs v-show Performance
Sık değişen bir toggle işleminde `v-if` kullanmak performansı düşürüyor çünkü DOM elementini sürekli yok edip yeniden yaratıyor.
Next.js Image Optimization
Harici kaynaklardan (S3, Cloudinary) gelen görseller `next/image` ile kullanılamıyor, "hostname is not configured" hatası veriyor.
Vuetify Grid System Breakpoints
Grid sistemi (`v-col`) mobilde beklenen davranışı sergilemiyor, `cols="12"` verilmesine rağmen yan yana gelmeye çalışıyor.
Type Narrowing Fail
Union type (`string | number`) bir değişkende method kullanırken TS hata veriyor.
Docker Container Communication
Microservice mimarisinde, bir container diğerine "localhost" üzerinden erişmeye çalışıyor ama bağlantı reddediliyor.
PostgreSQL Deadlocks
Yüksek trafikli bir e-ticaret sisteminde, eş zamanlı sipariş ve stok güncelleme işlemleri sırasında "Deadlock detected" hataları alınıyor.
Zero-Downtime Deployment
Veritabanı şema değişikliği (Migration) içeren bir deploy sırasında, eski kod yeni şemayla çalışmadığı için sistem 5-10 dakika kapalı kalıyor.
Slow Query Optimization
Milyonlarca satırlık tabloda basit bir "WHERE email = ..." sorgusu bile saniyeler sürüyor.
Nginx CORS & Proxy Pass
Frontend ve Backend farklı domainlerde. Tarayıcı CORS hatası veriyor. Backend kodunda CORS açmak yerine Gateway seviyesinde çözüm isteniyor.
JSON Marshaling Empty Fields
Struct alanları JSON olarak dönerken boş geliyor. Sebebi alan isimlerinin küçük harfle başlaması (private olması).
N+1 Query Problem
Bir liste çekerken her eleman için veritabanına ayrı bir sorgu atılması (örn: Kullanıcıları çekip, döngüde her birinin adresini çekmek).