Introductionâ
Tenant capability (tenantcap) is a framework-level optional capability in LinaPro, providing plugins and the host with multi-tenant fundamentals such as tenant resolution, tenant visibility validation, user-tenant relationship queries, and tenant switching. Plugins obtain the consumer-side interface via services.Tenant().
Similar to the organization capability, tenant capability follows the capability provider + consumer-side service model. Provider plugins (such as linapro-tenant-core) implement the concrete tenant logic, while the consumer side accesses it through the tenantcap.Service interface. When the provider is unavailable, the system degrades to single-tenant mode using the platform tenant (PlatformTenantID = 0).
Design Philosophyâ
Consumer-Side Serviceâ
tenantcap.Service is the consumer-facing interface for ordinary plugins and host core services:
- Availability check:
Available()determines whether the tenant capability provider is available - Current tenant:
Current()returns the tenant ID for the current request, falling back to the platform tenant when unavailable - Platform bypass:
PlatformBypass()determines whether the current request allows cross-tenant access - Tenant visibility:
EnsureTenantVisible()validates whether the current user can access a given tenant - User-tenant relationships:
ListUserTenants()returns the list of active tenants visible to the user - Tenant switching:
SwitchTenant()validates the legitimacy of a tenant switch
Providerâ
tenantcap.Provider defines the base contract that tenant capability plugins must implement:
- Tenant resolution:
ResolveTenantresolves tenant identity from the HTTP request - Tenant validation:
ValidateUserInTenantvalidates a user's access to a tenant - Tenant listing:
ListUserTenantsreturns active tenants visible to the user - Tenant switching:
SwitchTenantvalidates the legitimacy of a tenant switch
tenantcap.Resolver is an HTTP request-level tenant resolver interface used by the tenant middleware to establish tenant context before a request enters business processing. Multiple Resolver instances can form a chain of responsibility, attempting resolution in configured order.
Architectural Positionâ
Tenant capability plays several key roles in the system:
- Request pipeline: The tenant resolution middleware uses
RequestResolverto establish tenant context after authentication - Business processing: Plugins read the current tenant and validate visibility through
Service - Data filtering: The host internally uses
ScopeServiceto inject tenant filter conditions (not exposed to plugins)
Key Capabilitiesâ
Primary methods of tenantcap.Service (consumer side):
| Method | Description |
|---|---|
Available | Determines whether the tenant capability provider is available |
Status | Returns detailed activation status and provider information |
Current | Returns the current request tenant ID; falls back to the platform tenant when unavailable |
PlatformBypass | Determines whether the current request is allowed to bypass tenant filtering |
EnsureTenantVisible | Validates whether the current user can access a given tenant |
ValidateUserInTenant | Validates whether a specified user can access a given tenant |
ListUserTenants | Returns the list of active tenants visible to the user |
SwitchTenant | Validates the legitimacy of a user switching to a target tenant |
Design Constraintsâ
- Degrades to platform tenant. When tenant capability is unavailable,
Current()returnsPlatformTenantID (0), and the system operates in single-tenant mode. ScopeServiceis not exposed to plugins. Tenant filtering involves database query builders and is consumed through host-internal interfaces.RequestResolveris not exposed to plugins. HTTP request-level tenant resolution is the responsibility of host middleware; ordinary plugins do not need to use it directly.ProviderandResolverare registered independently.Providersupplies tenant business logic;Resolversupplies HTTP request resolution. They can be implemented by different plugins.
Provider Guideâ
To implement a custom tenant capability plugin, you need to:
- Implement the
tenantcap.Providerinterface, providing tenant resolution, validation, listing, switching, and other methods - Optionally implement the
tenantcap.Resolverinterface to provide HTTP request-level tenant resolution - Register a factory function via
tenantcap.Provide(pluginID, factory) - The factory function receives a
ProviderEnvcontaining host services such asPluginID,BizCtx, andPluginLifecycle
Provider plugins must register their factory in init(), and the host lazily constructs the instance on first use.
Related Servicesâ
- OrgService - Organization capability and tenant capability complement each other, jointly forming the multi-tenant + organization data model
- BizCtxService - Tenant resolution results are projected into BizCtx's TenantID field
- AuthService - TenantService validates legitimacy before tenant switching
- TenantFilterService - Uses tenant information from Tenant to filter data