Cluster ERP tek bir kurulumdan birçok müşteri şirkete hizmet verebilir. Her şirketin, yani kiracının (Tenant), kendi fiziksel PostgreSQL veritabanı vardır; ayrı bir kontrol düzlemi veritabanı kiracı kayıt defterini, ticari üyelikleri, operatör hesaplarını ve hız sınırı sayaçlarını tutar. Kip varsayılan olarak kapalıdır ve multi_tenant ayarıyla açılır. Bu sayfa core/tenancy.py dosyasını, server/dependencies.py içindeki kiracı yönlendirmesini, core/request_context.py içindeki istek bağlamını ve server/membership.py içindeki üyelik komutlarını açıklar. Kurulum ve ayrılma komutları kiracı yaşam döngüsü sayfasındadır.
Kısaca¶
- Yalıtım veritabanı düzeyindedir: A kiracısına çözülen bir istek bağlantısı A'nın veritabanını adlandıran bir motor alır; unutulacak bir sorgu süzgeci yoktur (
src/cluster_erp/core/tenancy.py:1-16). - Kontrol düzlemi tabloları kendi bildirim tabanını,
ControlBasekullanır; böylece kiracı şeması yaratma onları hiç yaratmaz, tersi de olmaz (src/cluster_erp/core/tenancy.py:86-93). - Bir istek, belirtecinin imzası doğrulanmış kiracı iddiasıyla veya girişte
X-Tenant-Domainbaşlığıyla yönlendirilir;activebir kiracıya çözülmeyen her şey tek bir genel HTTP 401 alır (src/cluster_erp/server/dependencies.py:104-157). - Bir kiracının veritabanı kısıtındaki dört durumu vardır:
provisioning,active,suspendedveclosed(src/cluster_erp/core/tenancy.py:124-129). - Günlük bir geçiş, üyelik dönemi bitmiş kiracıları askıya alır (
src/cluster_erp/core/tenancy.py:324-354,src/cluster_erp/server/app.py:372-403).
Nasıl çalışır¶
Kontrol düzlemi¶
ControlBase altı tablo bildirir; core/tenancy.py içinde grep __tablename__ ile sayıldı:
| Varlık | Tablo | Amaç | Kaynak |
|---|---|---|---|
Tenant |
control_tenants |
Anahtar, ad, durum, veritabanı adı, posta alan adları, bölge, kapanış verisi | src/cluster_erp/core/tenancy.py:96-129 |
Operator |
control_operators |
Operatör konsolu hesapları | src/cluster_erp/core/tenancy.py:132-154 |
OperatorAction |
control_operator_actions |
Operatör eylemlerinin denetim izi | src/cluster_erp/core/tenancy.py:157-170 |
RateLimitBucket |
control_rate_limits |
Anonim uçlar için ortak sabit pencere sayaçları | src/cluster_erp/core/tenancy.py:173-183 |
ControlRetentionRun |
control_retention_runs |
Her kontrol düzlemi saklama geçişinin özeti | src/cluster_erp/core/tenancy.py:186-198 |
Membership |
control_memberships |
Plan, durum, yönetici e-postası, ödeme referansı, dönem sonu, kurulum durumu, özet olarak kayıt belirteçleri | src/cluster_erp/core/tenancy.py:201-285 |
Bir kiracı anahtarı katı bir tanımlayıcı desenine uymalıdır, çünkü veritabanı adının soneki olur: tenant_db_prefix artı anahtar (src/cluster_erp/core/tenancy.py:42-46, src/cluster_erp/core/tenancy.py:458-468). Posta alan adları normalize_domain ile küçük harfli ve IDNA kodlu saklanır (src/cluster_erp/core/tenancy.py:53-70). Her kiracının sabit bir veri yerleşimi region değeri vardır; veritabanı o bölgenin sunucusunda durur (src/cluster_erp/core/tenancy.py:107-108, src/cluster_erp/core/tenancy.py:593-595).
Kiracı çözümleme¶
Akış şeması get_db_session bağımlılığının bir isteğin veritabanını nasıl bulduğunu gösterir.
flowchart TD
start["get_db_session"] --> mode{"multi_tenant açık mı?"}
mode -->|hayır| default["süreç varsayılanı Database"]
mode -->|evet| token["Bearer veya çerezlerden routing_token"]
token --> claim["read_tenant_claim, sonra TenantRegistry.by_key"]
claim --> found{"kiracı bulundu mu?"}
found -->|hayır| domain["X-Tenant-Domain, sonra TenantRegistry.by_domain"]
found -->|evet| active
domain --> active{"durum active mi?"}
active -->|hayır| err["AUTH_TENANT_UNRESOLVED 401"]
active -->|evet| ctx["request.state.tenant_key, set_tenant_context"]
ctx --> engine["TenantRegistry.database_for"]Düz anlatımla:
multi_tenantkapalıyken her istek süreç genelindeki veritabanını kullanır (src/cluster_erp/server/dependencies.py:116-118).- Aksi hâlde bağımlılık Bearer belirtecini, erişim çerezini veya yenileme çerezini alır; Bearer bir yenilemede yenileme belirtecini gövdeden okur (
src/cluster_erp/server/dependencies.py:127-134,src/cluster_erp/modules/auth/session_cookies.py:87-109). read_tenant_claimkiracı anahtarını yalnızca imzası doğrulanan bir belirteçten döndürür; süresi dolmuş bir oturumun yenileyebilmesi için süre yok sayılır (src/cluster_erp/modules/auth/jwt_utils.py:63-77).- Kullanılabilir bir iddia yoksa
X-Tenant-Domainbaşlığı canlı, etkin kiracılarla eşleştirilir (src/cluster_erp/server/dependencies.py:139-142,src/cluster_erp/core/tenancy.py:477-493). - Bulunamayan veya etkin olmayan bir kiracı HTTP 401 ile
AUTH_TENANT_UNRESOLVEDfırlatır (src/cluster_erp/server/dependencies.py:143-148). - Kiracı anahtarı giriş ucu için
request.stateüzerinde, depolama anahtarları için istek bağlamında yayımlanır (src/cluster_erp/server/dependencies.py:149-150,src/cluster_erp/core/request_context.py:23-27). database_forkiracı için önbellekteki motoru döndürür (src/cluster_erp/server/dependencies.py:151-157).
Motor önbelleği¶
TenantRegistry süreç başına en çok tenant_max_engines kiracı motoru tutar ve en uzun süredir kullanılmayanı havuzunu kapatarak çıkarır. Her kiracı motoru tenant_pool_size ve tenant_pool_max_overflow kullanır (src/cluster_erp/core/tenancy.py:288-305, src/cluster_erp/core/tenancy.py:597-615). Açılışta kayıt defteri, bağlantı bütçesi sunucu sınırını aşabilecekse uyarır (src/cluster_erp/server/app.py:119-121).
Kiracı başına arka plan işi¶
Zamanlanmış işler active_tenants üzerinde gezer; saklama ve günlük temizlikleri için askıdaki kiracılar da isteğe bağlı olarak katılır (src/cluster_erp/core/tenancy.py:495-510). Oturum bağımlılığı ayrıca isteğin kiracı veritabanını bir bağlam değişkeninde yayımlar; böylece EventBus işleyicileri oturumlarını çağıranın kiracısında açar (src/cluster_erp/server/dependencies.py:178-184).
Üyelik ve durum¶
| Durum | Anlam | Belirleyen | Kaynak |
|---|---|---|---|
provisioning |
Kayıtlı; veritabanı yaratılıyor | create_tenant |
src/cluster_erp/core/tenancy.py:443-475 |
active |
Girişte çözülür | kurulum, extend, activate |
src/cluster_erp/server/membership.py:83-125 |
suspended |
Çözülmez; veri korunur | süre dolumu taraması, suspend |
src/cluster_erp/core/tenancy.py:324-354, src/cluster_erp/server/membership.py:108-125 |
closed |
İlişki bitti; satır notuyla korunur; üyelikler iptal edilir | close_tenant |
src/cluster_erp/core/tenancy.py:550-585 |
Üyelik komut satırı list, sweep, retention, extend, suspend ve activate sunar (src/cluster_erp/server/membership.py:156-170). Operatör konsolu da uzatma, askıya alma ve etkinleştirme sunar; bkz. operatör konsolu.
Neden böyle kurulmuştur¶
- Modül açıklaması, müşteri başına bir fiziksel veritabanının yalıtımı yapısı gereği sağladığını söyler (
src/cluster_erp/core/tenancy.py:10-14). - Bilinmeyen alan adları ve etkin olmayan kiracılar yanlış parola gibi yanıtlanır; böylece uç müşterileri saymak için kullanılamaz (
src/cluster_erp/core/tenancy.py:477-483,src/cluster_erp/server/dependencies.py:112-114). - Fatura durumu kontrol düzleminde durur; böylece askıya alınmış bir müşteri kendi veritabanı ne derse desin askıda kalır (
src/cluster_erp/core/tenancy.py:201-206). - Motor önbelleği sınırlıdır; böylece birçok kiracıya hizmet veren uzun ömürlü bir işçi veritabanı bağlantılarını tüketemez (
src/cluster_erp/core/tenancy.py:288-296).
Kurallar ve sınırlar¶
multi_tenantvarsayılan olarak kapalıdır; tek kiracılı bir kurulum önceki davranışını korur (src/cluster_erp/config/settings.py:78-84).- Çok kiracılı kipte ayar doğrulayıcısı depolama, yedek ve mail şifreleme anahtarlarını ister (
src/cluster_erp/config/settings.py:805-821). Bkz. ikinci doğrulama adımı ve gizli değer saklama. - Kayıt ve operatör konsolu uçları yalnızca çok kiracılı kipte bağlanır (
src/cluster_erp/server/app.py:1440-1457). tests/test_tenancy.py(12 test) vetests/test_refresh_routing_body.py(3 test) saf kiracılık kurallarını ve gövdeden yönlendirmeyi sabitler;web-client/_e2e_tenant_isolation.mjs,web-client/_e2e_sep_companies.mjsveweb-client/_e2e_tenant_regions.mjsuçtan uca süitleri yalıtımı ve bölgeleri kapsar (grep -c "def test_"ile sayıldı ve adla bulundu).
Diğer parçalarla etkileşim¶
- Kimlik doğrulama ve oturumlar kiracı anahtarını belirteçlere basar.
- Kayıt kiracıları ve üyelikleri yaratır.
- Veri yerleşimi denetimi bölgeleri doğrular.
- Veritabanı ve oturumlar oturum bağımlılığını genel olarak anlatır.
Sınırlar ve açık noktalar¶
- Bir kiracıyı başka bölgeye taşımak koddan belirlenemedi; alan yorumu bölgenin asla değişmediğini söyler (
src/cluster_erp/config/settings.py:90-92). Tenantüzerindekideleted_atdeğeriniclose_tenantbasar (src/cluster_erp/core/tenancy.py:568-569); yeniden açma yolu koddan belirlenemedi.
Tanıtılan terimler¶
| Terim | Kod tanımlayıcısı | Tanım | Türkçe terim | Kaynak |
|---|---|---|---|---|
| tenant | Tenant |
Kendi fiziksel veritabanı olan tek bir müşteri şirket. | kiracı | src/cluster_erp/core/tenancy.py:96 |
| control plane | ControlBase |
Kiracıların, üyeliklerin, operatörlerin ve sayaçların ayrı veritabanı. | kontrol düzlemi | src/cluster_erp/core/tenancy.py:86 |
| membership | Membership |
Bir kiracının arkasındaki ticari kayıt: plan, durum, dönem ve kurulum durumu. | Üyelik (webapp/i18n/tr.json anahtarı signup.title) |
src/cluster_erp/core/tenancy.py:201 |
| tenant key | Tenant.key |
Bir kiracının kararlı, küçük harfli tanımlayıcısı; veritabanı adının soneki olarak da kullanılır. | kiracı anahtarı | src/cluster_erp/core/tenancy.py:99 |
| tenant registry | TenantRegistry |
Kontrol düzlemine süreç başına erişen, sınırlı motor önbellekli nesne. | kiracı kayıt defteri | src/cluster_erp/core/tenancy.py:288 |
İlgili sayfalar¶
- Kimlik, erişim, kiracılık, gizlilik ve lisans
- Kayıt
- Operatör konsolu
- Kiracı yaşam döngüsü
- Ayarlar başvurusu
92f8051 numaralı commit ile 2026-11-13 tarihinde doğrulandı.