feat(membership): enforce tenant subscription plans with blocked UI

Add configurable membership plans (free/plus/pro) synced to DB on boot, a
subscription guard middleware that blocks tenant endpoints on expired or
missing plans, and a MembershipBlockedView that surfaces the reason so
the admin can contact the tenant owner. Quota and brand-library reads now
honor the active plan's policy JSON and expired subscriptions.
This commit is contained in:
2026-04-18 20:56:05 +08:00
parent 9ec9314aea
commit 63667ed2d1
28 changed files with 1738 additions and 80 deletions
+16
View File
@@ -95,6 +95,22 @@ const enUS = {
defaultTestAccount: "Default account",
defaultTestPassword: "Default password",
},
membershipBlocked: {
eyebrow: "Access Paused",
title: "This tenant plan is unavailable",
reasonTrialExpired: "The free trial's 3-day page access window has ended. All business pages are now locked. Please contact an administrator to reactivate trial access.",
reasonRequired: "This tenant does not have an active plan. All business pages are now locked. Please contact an administrator.",
reasonInactive: "This tenant plan has expired or been disabled. All business pages are now locked. Please contact an administrator to restore access.",
plan: "Current Plan",
expiredAt: "Expired At",
articleLimit: "Article Limit",
companyLimit: "Company Limit",
contactAdmin: "Once the administrator reactivates access, refresh this page to continue.",
logout: "Log out",
refresh: "Check again",
refreshing: "Checking…",
stillBlocked: "Access is still blocked. Please contact your administrator before checking again.",
},
shell: {
localeLabel: "Language",
quotaTitle: "Plan & Quota",