Kurtarmaya çağrıldığımız neredeyse her SaaS yeniden yazımı, orijinal ekibin daha ilk ayda söylediği aynı üç kelimeye dayanır: «onu sonra ekleriz». Çok kiracılılık, rol bazlı erişim denetimi, gerçek faturalama. Müşteriler edinildikten sonra eklenen şeyler gibi görünürler. Tam tersidirler — binanın biçiminin ta kendisidirler ve duvarlar bir kez örüldükten sonra her şeyi yıkmadan temeli değiştiremezsiniz.
Bugün tek bir kod tabanı üzerinde 40'tan fazla ülkede çalışan platformlar inşa ettik. Bunu mümkün kılan neden hem sıkıcı hem de hemfikir: kiracılık, erişim ve faturalama ilk günden, ilk özellikten önce kararlaştırıldı. İşte bu kararlar şöyle görünüyor — ve onları ertelemenin maliyeti şu.
01Ekipler bundan neden kaçınır (ve bu neden bir tuzaktır)
Baskı gerçektir. Tek bir pilot müşteriniz, gelecek hafta bir demonuz ve gerçekten ürün gibi görünen özelliklerle dolu bir backlog'unuz var. Çok kiracılılık o ilk müşteri için görünmezdir — onu göremez, dolayısıyla gereksiz bir süs gibi görünür. Bu yüzden ekip «şimdilik» tek kiracılı bir uygulama inşa eder ve sonra onu genelleştirmeyi vaat eder.
Tuzak şu: «şimdilik tek kiracı» tek bir varsayımı her katmana sızdırır: dünyada tam olarak bir tane kuruluş olduğu varsayımını. Bu varsayım sonunda sorgularınıza, kimlik doğrulamanıza, önbelleklerinize, arka plan işlerinize, dosya yollarınıza yerleşir. Onu daha sonra çekip çıkarmak bir refactoring değildir — bir yeniden yazımdır; çünkü varsayım tek bir yerde değil, her yerdedir.
Kiracılığı ilk günden eklemek size belki iki haftalık mimari ve disiplin maliyeti çıkarır. Onu ikinci yılda eklemek — gerçek müşterileriniz, gerçek verileriniz ve gerçek erişilebilirlik beklentileriniz olduğunda — yük altında aylar süren bir yeniden yazımdır; başarısız olmaya hakkınızın olmadığı bir veri taşımayla birlikte. İş, ertelerseniz yok olmaz. Birikir.
02Kiracı ilk sütundur
Kuralımız basit: bir müşteriye ait her satır bir tenant_id taşır ve onsuz sorgu yapabilecek hiçbir kod yolu yoktur. İnsanların hatırladığı bir kural değil — veritabanının ve framework'ün zorunlu kıldığı bir kısıt; öyle ki unutmak yalnızca tavsiye dışı olmaktan çıkar, imkânsız hâle gelir.
Kullandığımız en temiz sürüm, veritabanının kendisine dayanır. Satır düzeyi güvenlik politikaları, kiracı sınırının uygulama kodunuzun bir katman altında, bir ORM hatasının ya da unutulmuş bir WHERE ifadesinin bir müşterinin verilerini başka birine sızdıramayacağı yerde zorunlu kılındığı anlamına gelir. Uygulama, geçerli kiracıyı bağlantı üzerinde ayarlar; veritabanı bunun dışında herhangi bir şey döndürmeyi reddeder.
-- sınır uygulamanın içinde değil, altında yaşar ALTER TABLE orders ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON orders USING (tenant_id = current_setting('app.tenant')::uuid); -- uygulama kiracıyı her istek için ayarlar; unutulmuş bir WHERE -- ifadesi artık başkasının verisi yerine sıfır satır döndürür SET app.tenant = 'a91f…'; SELECT * FROM orders; -- her zaman yalnızca bu kiracının siparişleri
Bu tek karar, koca bir felaket niteliğindeki hata sınıfını — kiracılar arası veri sızıntısını — kalıcı olarak endişe listenizden çıkarır. Tüm projenin en yüksek kaldıraçlı iki günlük işidir.
SaaS'taki en pahalı hata, bir müşteriye başka bir müşterinin verilerini gösteren hatadır. Mimarinizi onun olabilir olmaması için değil, olamayacak şekilde tasarlayın.
— Kısıt olarak izolasyon üzerine03RBAC bir ayarlar sayfası değildir
Yeniden yazıma dönüşen ikinci «sonra», erişim denetimidir. Ekipler örtük bir iki rollü dünyayla — admin ve kullanıcı — kod tabanının her yanına dağılmış if ifadelerine sabitlenmiş hâlde canlıya geçer. Sonra bir kurumsal müşteri «yalnızca faturalama» rolü ya da «salt okunur denetçi» ister ve siz izin mantığını iki yüz yerde keşfedersiniz.
İzinleri en baştan veri olarak modelleriz: roller, izinler ve aralarındaki atamalar tablolarda yaşar ve korumalı her eylem tek bir merkezi otoriteye bir soru sorar: «bu aktör, bu kiracıda, bu kaynak üzerinde bu işi yapabilir mi?» Bir rol eklemek bir release değil, bir satır hâline gelir. Bir platformun, uygulama koduna dokunmadan kurumsal müşterinin organizasyon şemasına evet demesine olanak veren şey budur.
- İzinler, kaynaklar üzerindeki fiillerdir —
invoice:read,invoice:void— «yönetici» gibi muğlak düzeyler değil. - Roller, izin demetleridir; bir kiracının bir araya getirebileceği demetler, öyle ki iki müşteri «admin» ile farklı şeyler kastedebilir.
- Her denetim tek bir kapıdan geçer. Tek bir yerdeki yetkilendirme mantığı denetlenebilirdir; dağınık
ififadeleri bir yüktür.
04Faturalama bir üründür, tesisat değil
Faturalama, «onu sonra ekleriz»in en çok acıttığı yerdir; çünkü onu eklediğinizde elinizde el sıkışmayla yapılmış anlaşmalı müşteriler, kimin kime ne borçlu olduğuna dair tutarsız veriler ve abonelik diye temiz bir kavram olmadan bir durum vardır. Faturalamayı sonradan eklemek, para mutabakatı yapmak demektir ve bir hatanın yalnızca utandırıcı olmadığı tek yer burasıdır — bir iade, bir ihtilaf ya da bir uyumluluk sorunudur.
Faturalama modelini kiracı modeliyle aynı anda tasarlarız: planlar, abonelikler, kullanım, faturalar ve bunları birbirine bağlayan yaşam döngüsü. İlk müşterilere elle fatura kesilse bile veri modeli ilk günden oradadır; öyle ki self servis planları daha sonra etkinleştirmek bir özelliktir, gelir geçmişinizin tamamının bir taşıması değil.
Bir kod tabanı, bir dağıtım modeli, birçok kiracı.
Bakımı yapılacak ya da birbirinden ayrışmaya bırakılacak müşteriye özel fork yok.
İzolasyon, kural gereği değil, veritabanı düzeyinde zorunlu kılındı.
05Kırk ülke, tek bir kod tabanı
40'tan fazla ülkeye ulaşmak bir ölçeklendirme hikâyesi gibi geliyor. Gerçekte bir yapılandırma hikâyesidir. Platformun ülkeye özel kod dalları yoktur — bölgeden bölgeye farklılık gösteren şeyleri veri olarak ifade edecek kadar zengin bir kiracı modeli vardır: para birimi, vergi kuralları, dil, tarih biçimleri, bir faturadaki yasal metin.
«Kod» ile «yapılandırma» arasındaki sınır ilk günden doğru çizildiğinde, yeni bir ülke bir mühendislik projesi değil, bir işe alıştırma görevidir. Yanlış çizildiğinde ise her yeni pazar bir fork'tur ve bir yıldan kısa sürede aynı uygulamanın inceden inceye farklılaşan bir düzine sürümünü sürdürür ve her düzeltmeyi bir düzine kez teslim edersiniz. «Tek bir kod tabanı» sonucu, ilk müşteriden önce alınan kararlardan doğar.
Bunu ilk günden yapmanın faydası ilk ay görünmez — üçüncü yıl görünür: bir özelliği bir kez teslim ettiğinizde ve 40 ülke onu eşzamanlı olarak aldığında, tek kiracılı rakibiniz ise onu hâlâ yedinci müşteri fork'una entegre ederken.
06İlk günün kontrol listesi
Bu çeyrekte bir SaaS platformu başlatıyorsanız, tek bir özellik yazmadan önce almanız gereken kararlar şunlardır — acil oldukları için değil, geri alınamaz oldukları için:
- Her şeye bir
tenant_idkoyun ve onu uygulamanın altında zorunlu kılın. Satır düzeyi güvenlik ya da eşdeğeri. Kiracılar arası bir sorguyu olası değil, imkânsız kılın. - İzinleri veri olarak modelleyin. Roller ve atamalar tablolarda, tek bir merkezi yetkilendirme kapısı. Bir rol eklemek bir satır olmalı.
- Faturalama veri modelini erken inşa edin. Planlar, abonelikler, faturalar — başlangıçta elle fatura kesseniz bile. Parayı sonradan eklemeyin.
- Kodu yapılandırmadan ayırın. Müşteriye ya da bölgeye göre değişen her şey veridir. 41. ülke bir işe alıştırma formu olmalı.
- Önce kiracı sağlama yolunu yazın. Yeni bir kiracıyı temizce, makul varsayılanlarla oluşturmak en sık çalıştırdığınız işlemdir. Onu ilk günden otomatikleştirin.
Bunların hiçbiri egzotik değil. Yeniden yazımı asla yapmak zorunda kalmamak karşılığında, başta birkaç haftalık disiplindir. Tek bir kod tabanıyla 40 ülkeye ulaşan ekipler şanslı değildi — yalnızca sonradan eklenemeyecek üç şey hakkında «sonra» demeyi reddettiler.

