Çok kiracılı CRM: 19 modül, 4.000’den fazla test
Perde ve ev tekstili sektörü için çok kiracılı bir CRM’in teknik liderliğini yaptım. Aşağıda ürünün mimarisi, kiracı izolasyonunun nasıl korunduğu ve devralınabilir bir teslimin neye benzediği yazıyor.
Proje neydi?
Proje, perde ve ev tekstili sektöründeki bayilerin tekliften montaja kadar tüm sürecini tek sistemde yürüttüğü çok kiracılı bir CRM’di. Tek bir kod tabanı ve tek bir veritabanı birden çok bayiye hizmet eder; her bayi yalnızca kendi verisini görür. Ürün Qolay Bilişim bünyesinde geliştirildi ve üretime alındı; benim rolüm teknik liderlikti.
- Rol
- Software Developer Technical Lead
- Dönem
- 2025 – 2026
- Modül grubu
- 19
- Otomatik test
- 4.000+
- Mimari
- Çok kiracılı · tek veritabanı, kiracı kimliğiyle izolasyon
- Durum
- Üretimde · teslim edildi
Hangi teknoloji yığını kullanıldı?
Önyüzde Angular ve mobil eşlenik için Ionic/Capacitor, arka uçta Node.js/Express ve Sequelize, veritabanında MySQL 8 kullanıldı. Arka plan işleri Redis üzerinde BullMQ ile, dosya depolama MinIO ile, anlık bildirim Firebase Cloud Messaging ile, SMS Netgsm ile yürütüldü. Tüm yığın tek bir sanal sunucuda Docker Compose ile çalışıyor.
| Katman | Seçim | İşlevi |
|---|---|---|
| Web önyüz | Angular · TypeScript | Bayi ve merkez kullanıcılarının ana arayüzü |
| Mobil | Ionic · Capacitor | Aynı kod tabanının saha kullanımı için ikinci hedefi |
| Arka uç | Node.js · Express · Sequelize | İş kuralları, yetkilendirme, veri erişimi |
| Veritabanı | MySQL 8 | Tüm kiracıların verisi, kiracı kimliğiyle bölünmüş |
| Kuyruk | Redis · BullMQ | Rapor üretimi, bildirim, toplu işler |
| Nesne depolama | MinIO | Belge, görsel ve teklif çıktıları |
| Bildirim | Firebase Cloud Messaging · Netgsm | Anlık bildirim ve SMS |
| Çalıştırma | Ubuntu · Docker Compose · nginx · Certbot | Üç katmanlı ağ ayrımıyla tek VDS üzerinde |
| Teslim | GitHub Actions · konteyner kayıt defteri | Sabitlenmiş imaj etiketleriyle sürekli teslim |
Kiracı izolasyonu nasıl korunuyor?
Kiracı izolasyonu tek bir kuralla korunuyor: kiracı kimliği isteğe bağlı bir filtre değil, veri katmanının zorunlu parçası. Bu kural üç yerde ayrı ayrı uygulanıyor — senkron istekler, kuyruğa düşen arka plan işleri ve nesne depolamadaki yol şeması. Üçünde de kural yorumla değil testle korunuyor.
- İstek düzeyi. Kimlik doğrulama sonrası kiracı bağlamı sabitlenir; veri erişim katmanı bu bağlam olmadan sorgu üretmez.
- Arka plan işleri. Kuyruğa yazılan her iş kendi kiracı kimliğini taşır. Arka planda “şu anki kullanıcı” diye bir bağlam yoktur; olduğunu varsaymak en sık yapılan hatadır.
- Kiracı aktifliği. Bir kiracının aboneliği pasife düştüğünde erişim ara katmanda kesilir. Bu kontrol her istekte veritabanına gitmesin diye Redis’te önbelleklenir.
- Nesne depolama. Dosya yolları kiracıya göre bölünür, imzalı bağlantılar süre ve kapsamla sınırlanır.
- Test. Sızıntı testleri paketin en kritik bölümü. “A kiracısının kaydı B kiracısına görünüyor mu” sorusu her modül için ayrı ayrı sorulur.
Şema değişiklikleri çok kiracılı bir sistemde nasıl yapılır?
Şema değişiklikleri eklemeli yapılır, yıkıcı değil. Uygulanan desen genişlet–daralt: önce yeni alan eklenir, bir süre kod hem eski hem yeni alanı yazar, veri taşındıktan ve doğrulandıktan sonra eski alan kaldırılır. Tek bir göç adımıyla tüm kiracıları aynı anda riske atmak kabul edilmez.
- Genişlet. Yeni sütun veya tablo eklenir, eskisi yerinde kalır. Bu adım geri alınabilir.
- Çift yazma. Uygulama her iki alana da yazar, okuma hâlâ eskiden yapılır.
- Taşı ve doğrula. Geçmiş veri taşınır; iki alanın tutarlılığı ölçülür.
- Okumayı çevir. Okuma yeni alana geçer, eski alan yalnızca yazılmaya devam eder.
- Daralt. Eski alan kaldırılır. Buraya kadar her adım ayrı ayrı geri alınabilirdi.
Bu disiplinin bedeli, bir değişikliğin tek seferde bitmemesidir. Karşılığı ise şudur: göç adımlarından biri hata verdiğinde geri dönülecek bir yer vardır. Çok kiracılı bir sistemde bu takas her zaman bu yönde yapılır.
Teslim neye benziyor?
Teslim yalnızca çalışan bir sistem değil, başka bir ekibin devralabileceği bir kurulumdur. Bu projede teslim paketi şunları içerdi: sabitlenmiş imaj etiketleriyle Docker Compose tanımı, üç katmanlı ağ ayrımı, şifrelenmiş yedekleme, sağlık kontrolü uç noktası ve sürüm numaralarıyla alan kurallarını tutan yazılı bir proje kuralları dosyası.
- Sabitlenmiş imaj etiketleri. “En son” etiketiyle çalışan bir üretim ortamı, tanımı gereği tekrarlanabilir değildir.
- Üç katmanlı ağ. Genel, uygulama ve veri katmanları ayrı ağlarda; veritabanı dışarıya hiç açılmaz.
- Sağlık kontrolü uç noktası. Bağımlılıkların durumunu tek tek döndürür — “ayakta mı” değil, “neyi yapabiliyor” sorusuna cevap verir.
- Şifrelenmiş yedek. Yedeğin geri yüklenebildiğinin de test edilmesi şartıyla.
- Proje kuralları dosyası. Sürüm numaraları ve alan değişmezleri (kiracı izolasyonu, vergi hesabı) yazılı; sonraki geliştirici bunları koddan çıkarmak zorunda kalmaz.
Bu projeden çıkardığım üç ders
- İzolasyon bir özellik değil, bir değişmezdir. Özellik listesine giren şey unutulabilir; değişmez olan şey teste bağlanır. Kiracı sızıntısı testleri, ürünün en az değişen ama en çok koruyan bölümüydü.
- Geri bildirim listesi mimariden hızlı büyür. Sahadan gelen 55’ten fazla değişiklik talebini 19 modül grubuna ayırıp risk düzeyine göre sıraladık. Sıralamayı yapmadan çalışmak, en yüksek riskli maddeyi en sona bırakmak demektir.
- Mobil eşlenik bir kural olmalı, bir niyet değil. Webde yapılan her değişikliğin mobil tarafa yansıtılması yazılı bir kural haline getirilmediğinde, iki hedef altı ay içinde birbirinden ayrılır.
Son güncelleme: