Per-route guards only — the global APP_GUARD stays a signed decision (高危#4):
GET /subscriptions/current: TenantIsolationGuard (fail-closed · any authenticated
member of the active organization reads their own plan/usage/mapping).
POST /subscriptions: additionally AuthorizationGuard + organization:update
(owner/admin change the plan). The route never names a tenant id — the repository
stamps the ALS tenant (FR-5 single choke-point).
Provision actually calls PaymentService.createCustomer to establish the tenant ↔
customer mapping (FR-8). Quota超限拒绝 (FR-7) is enforced via QuotaService/QuotaGuard;
the production member-add attach point (Better Auth route) is deferred to a later slice.
组织订阅切片的 HTTP 控制器(多租户 S7 · FR-7/FR-8/D5)。
Remarks
Tenant subscription slice (global-tenancy S7 · FR-7/FR-8/D5).
Per-route guards only — the global APP_GUARD stays a signed decision (高危#4):
GET /subscriptions/current:TenantIsolationGuard(fail-closed · any authenticated member of the active organization reads their own plan/usage/mapping).POST /subscriptions: additionallyAuthorizationGuard+organization:update(owner/admin change the plan). The route never names a tenant id — the repository stamps the ALS tenant (FR-5 single choke-point).Provision actually calls
PaymentService.createCustomerto establish the tenant ↔ customer mapping (FR-8). Quota超限拒绝 (FR-7) is enforced viaQuotaService/QuotaGuard; the production member-add attach point (Better Auth route) is deferred to a later slice.