"Önce MVP'yi çıkaralım, çok kiracılığı sonra düşünürüz" cümlesini çok duyduk. Sorun şu ki kiracı (tenant) kavramı, veritabanından yetkilendirmeye, önbellekten faturaya kadar sistemin her katmanına dokunur. Sonradan eklemek, binanın temelini kat çıktıktan sonra değiştirmeye benzer.
Ziraat danışmanları ve kooperatifler için geliştirdiğimiz Tarlamapp platformunda ilk gün verdiğimiz beş karar şunlardı.
1. İzolasyon modeli: Paylaşımlı tablo mu, ayrı şema mı?
Üç yaygın model var: her kiracıya ayrı veritabanı, her kiracıya ayrı şema, ya da tüm kiracılar için paylaşımlı tablolar ve her satırda tenantId. Kiracı sayısı yüzlerle binler arasındaysa ve yasal bir ayrım zorunluluğu yoksa, paylaşımlı tablo modeli işletmesi en ucuz olanıdır.
Biz bu modeli seçtik; ancak bir şartla: tenantId filtresini geliştiricinin hatırlamasına bırakmamak.
2. Kiracı filtresi tek bir yerde uygulanmalı
En tehlikeli hata, bir sorguda where tenantId = ? koşulunu unutmaktır; bir kooperatifin verisi başka birine görünür. Bunu önlemek için kiracı bağlamını isteğin başında çözüp tüm veri erişim katmanına otomatik olarak uyguluyoruz. Postgres kullanıyorsanız Row Level Security ikinci bir güvenlik ağı olarak çok değerlidir.
alter table field enable row level security;
create policy tenant_isolation on field
using (tenant_id = current_setting('app.tenant_id')::uuid);Ayrıca her listeleme uç noktası için "başka kiracının verisini döndürmüyor" testini otomatik yazıyoruz.
3. Paket limitleri kodun içine gömülmemeli
"Ücretsiz pakette 3 tarla, Pro'da 50" gibi kurallar ilk gün if olarak yazılır ve sonra her yere yayılır. Bunun yerine limitleri veri olarak tutun: paket → özellik → limit. Uygulama yalnızca "bu kiracı bu işlemi yapabilir mi?" diye tek bir servise sorar. Pazarlama ekibi yeni bir paket tasarladığında kod değişmez.
4. Faturalandırma, kullanımdan ayrı tutulmalı
Kullanım olaylarını (yüklenen fotoğraf, yapılan analiz) değişmez kayıtlar olarak saklıyoruz; faturalandırma bu kayıtları dönem sonunda okuyor. Böylece fiyatlandırma değişse bile geçmiş kullanım doğru hesaplanıyor ve "neden bu kadar ödedim?" sorusuna satır satır cevap verilebiliyor.
5. Gözlemlenebilirlik kiracı bazında olmalı
Bir kiracı "sistem yavaş" dediğinde genel ortalamalara bakmak işe yaramaz. Log, metrik ve izleme kayıtlarına tenantId ekleyin. Hangi kiracının en çok kaynak kullandığını, hangisinin hata aldığını tek bir sorguyla görebilmek, hem destek süresini hem de altyapı maliyetini doğrudan düşürür.
Özet
İzolasyon modelini ölçeğe ve yasal gereksinime göre seçin.
Kiracı filtresini otomatikleştirin, veritabanı seviyesinde de kilitleyin.
Limitleri ve fiyatları kod değil veri olarak tutun.
Kullanımı değişmez olaylar olarak kaydedin.
Her kaydı kiracıyla etiketleyin.
Bu beş karar ilk sprinte birkaç gün ekler; ama bize sonradan aylarca sürecek bir yeniden yazımı kazandırdı.


