Private
Tracker *Bug Feature Support Testing
Subject *
Description Edit getTenantBillingSummary properly falls back to the platform setting and returns allowTenantSelfCancellation to the frontend? cancelTenantSubscription honors both the per-tenant override and the platform fallback? Any relevant unit tests are updated/added when creating a new tenant, allowTenantSelfCancellation should defaults to the company setting allowTenantSelfCancellation value... is this correct way of configuration ? The short answer is no, copying/freezing the value at creation time is generally an anti-pattern. Instead, the best practice for multi-tenant SaaS architecture is Hierarchical Inheritance (Cascading 3-State Configuration). Why copying at tenant creation causes issues If you copy the platform/company default into newTenant.saasBilling.allowTenantSelfCancellation at creation time: Loss of Global Policy Control: If the platform superadmin later changes the platform setting in PlatformBillingSettingsPage.tsx (which advertises: "Platform billing settings updated successfully across all tenants"), none of the existing tenants will reflect the change because their values were hardcoded on creation. Database Migration Overhead: Any time policy changes globally, you would need to run a batch database migration across all tenant documents instead of simply changing a single platform-level setting. The Recommended Pattern: Hierarchical Inheritance (3-State) Instead of hardcoding a boolean at creation, leave the tenant setting as null (unset), and dynamically resolve the effective value using a fallback chain: Effective Value = Tenant Override ( if not null ) ⟶ Platform/Company Setting ⟶ Hardcoded Fallback (false) Effective Value=Tenant Override(if not null)⟶Platform/Company Setting⟶Hardcoded Fallback (false) In this model: null (Default for every new tenant) → → "Inherit Global Platform Setting". true → → Explicit Override: Force-enabled for this specific tenant (even if platform default is disabled). false → → Explicit Override: Force-disabled for this specific tenant (even if platform default is enabled). Evidence Already in Your Codebase Your codebase was actually designed for this hierarchical model: In company-model.js: javascript // Line 1059: Tenant-level override defaults to null saasBilling: { allowTenantSelfCancellation: { type: Boolean, default: null }, }, // Line 1079: Platform-level default billingSettings: { allowTenantSelfCancellation: { type: Boolean, default: false }, } In billing.controller.js: toggleTenantSelfCancellation specifically allows superadmins to override this per company. Current Inconsistencies to Fix in Your Logic While the schema was designed for hierarchical inheritance, a few places in tenantBilling.service.js have conflicting or incomplete resolution logic: 1. In resolveBillingContext (tenantBilling.service.js#L586): It currently does: javascript // Boolean(null) becomes false, ignoring the global setting! allowTenantSelfCancellation: billing.status === "trialing" || Boolean(billing.allowTenantSelfCancellation), 2. In cancelTenantSubscription (tenantBilling.service.js#L3440-L3446): It currently checks only globalSettings.allowTenantSelfCancellation and ignores company.saasBilling?.allowTenantSelfCancellation. If a superadmin overrides a specific tenant to allow self-cancellation, the backend still blocks them. 3. In getTenantBillingSummary (tenantBilling.service.js#L1780-L1903): PlanUsagePage.tsx#L638 expects data.allowTenantSelfCancellation at the top level of the API response, but getTenantBillingSummary defines allowTenantSelfCancellation on line 1781 and never attaches it to the return object. Suggested Helper for Resolution Create a unified helper in tenantBilling.service.js: javascript const resolveAllowTenantSelfCancellation = async (company) => { // Always allow cancellation during trialing period if (company.saasBilling?.status === "trialing") return true; // 1. Check tenant explicit override (true / false) if (company.saasBilling?.allowTenantSelfCancellation != null) { return Boolean(company.saasBilling.allowTenantSelfCancellation); } // 2. Fall back to platform global default const globalSettings = await getPlatformBillingSettings(); return Boolean(globalSettings.allowTenantSelfCancellation); }; Summary Recommendation Do not copy the setting to the tenant record on creation; leave it as null. Use the fallback/inheritance pattern at runtime so platform-wide changes take effect automatically, while preserving the ability for superadmins to set specific per-tenant overrides.
Status New
Priority *Low Normal High Immediate
Assignee Ajit ABindu DandaChandra SekharDivya InapakurthiKarthik PalakondaPavan Kumar MuralaRavi Shankar PalleRavindra AtthotaSai MahanandaSai Priyatham SadineniSowjanya atthotaSravani RangannapalemTeja Sriram SanganiYalavarthi Thriveni
Target version Sprint (10/05/2026- 10/09/2026) sprint (10/12/2026 - 10/31/2026) Backlog
Parent task
Start date
Due date
Estimated time Hours
% Done0 % 10 % 20 % 30 % 40 % 50 % 60 % 70 % 80 % 90 % 100 %