fix(subscription): report the acting environment's plan for gating
Feature gates and the resource cap are enforced against the environment the user is standing in, but /subscription/my only ever returned the plan of the environment they own. A doctor working as a guest in another clinic consumed the host clinic's resource quota while the panel showed their own plan's cap, so the quota number and the menu locks disagreed with what the server would allow. /subscription/my now also returns context_plan — limits and features of the acting environment, without the other environment's plan identity. effective_plan, subscription and used_trial stay on the owned environment so the purchase flow is unchanged, and useSubscription reads its caps and hasFeature from context_plan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -107,13 +107,21 @@
|
||||
"is_active": true
|
||||
},
|
||||
"used_trial": false,
|
||||
"effective_plan": { "name": "basic", "level": 1, "max_secretaries": 3, "max_resources": 3, "features": {...} }
|
||||
"effective_plan": { "name": "basic", "level": 1, "max_secretaries": 3, "max_resources": 3, "features": {...} },
|
||||
"context_plan": { "max_secretaries": 3, "max_resources": 3, "features": {...} }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`is_granted` یعنی این اشتراک را ادمین بدون پرداخت اعطا کرده است.
|
||||
|
||||
`effective_plan` و `context_plan` دو محیط متفاوت را جواب میدهند و برای کاربری که فقط محیط خودش را دارد یکی هستند:
|
||||
|
||||
- `effective_plan` و `subscription` و `used_trial` مالِ محیطِ **مالکیت**اند. مبنای خرید و ارتقا همین است.
|
||||
- `context_plan` مالِ محیطی است که کاربر همین حالا **در آن ایستاده**. سرور سقف منابع و قفل قابلیتها را با همین محیط میسنجد، پس پنل هم باید سقفها و `hasFeature` را از این بخواند.
|
||||
|
||||
پزشکِ مهمانِ یک کلینیک نمونهٔ واگرایی است: منابعی که میسازد از سهمیهٔ کلینیک میزبان کم میشود، ولی اشتراکِ خودش همان اشتراک شخصی میماند. `context_plan` فقط سقفها و `features` را دارد؛ فیلدهای هویتیِ پلنِ محیط دیگر (`name`, `level`, `uuid`) در آن نمیآید.
|
||||
|
||||
اگر اشتراک فعالی نداشت `subscription` برابر `null` است، اما `effective_plan` همیشه مقدار دارد: پلن اشتراک فعال، یا در نبود اشتراک، **پلن پیشفرض `free`**. فرانتاند برای تعیین دسترسی به امکانات (`hasFeature`) باید از `effective_plan` استفاده کند (نه `subscription`) تا کاربرانِ بدون اشتراک هم امکانات پلن free را داشته باشند. `subscription`/`hasPlan` صرفاً برای نمایش وضعیت اشتراک پولی است.
|
||||
|
||||
### پاسخ کاهشیافته برای کاربرِ بدون مجوزِ `subscription.view` (2026-08)
|
||||
@@ -129,7 +137,8 @@
|
||||
{"success":true,"data":{
|
||||
"subscription": null,
|
||||
"used_trial": false,
|
||||
"effective_plan": { "features": { "patient_records": true, "…": true }, "max_secretaries": 1, "max_resources": 1 }
|
||||
"effective_plan": { "features": { "patient_records": true, "…": true }, "max_secretaries": 1, "max_resources": 1 },
|
||||
"context_plan": { "features": { "patient_records": true, "…": true }, "max_secretaries": 1, "max_resources": 1 }
|
||||
}}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user