feat: 接入远程订阅策略门禁 T-705
Tests / Python 3.11 / Windows (push) Has been cancelled

This commit is contained in:
chengma
2026-07-28 15:42:19 +08:00
parent 593c6f77cb
commit df9da63841
15 changed files with 925 additions and 73 deletions
+47
View File
@@ -61,6 +61,53 @@ get_cmhub_api_key(path="data/config/cmhub.json", masked=False) -> str
```
`data/config.json` 只保存 `ai.backend`、`ai.cmhub.base_url/title_alias/image_alias/vision_alias/connect_timeout` 等非密钥配置;`vision_alias` 默认 `vision-standard`,供商品套图中的「AI帮写」独立使用。T-529 后普通设置页固定保存 `ai.backend=cmhub`,不暴露后端切换;`data/config/cmhub.json` 必须 gitignore,展示时打码,不写日志/导出。
## client_policy / update_check 模块(`app/client_policy.py`、`app/update_check.py`)
启动版本接口 `GET /api/v1/client/releases/latest?platform=windows` 除 `release` 外可返回顶层 `client_policy`。策略解析与版本解析互相隔离:策略字段错误不能破坏强制升级判断,`release=null` 也可单独下发策略。
```python
class ClientPolicyError(ValueError): ...
class ClientPolicy:
policy_version: int
subscription_check_enabled: bool
subscription_enforcement_enabled: bool
updated_at: str
source: str
warning: str
mode: str # off / observe / enforce
parse_client_policy(value, source="remote") -> ClientPolicy
policy_cache_path(config=None) -> str # data/config/client_policy.json
save_cached_policy(policy, config=None, path=None, cached_at=None) -> str
load_cached_policy(config=None, path=None) -> ClientPolicy
resolve_client_policy(remote_policy, config=None, path=None) -> ClientPolicy
check_for_update(...) -> UpdateCheckResult # 同时透传 client_policy/client_policy_error
```
`policy_version` 必须为整数 `1`,两个开关必须为 JSON 布尔值,`updated_at` 必须是带时区 ISO 8601。`false/true` 非法组合归一化为 `false/false`。有效远程策略写非敏感原子缓存;远程缺失/非法/不可达时先用缓存,无缓存回退 `true/false` 观察模式。缓存不得包含 API Key、账号、套餐或订阅结果。
## subscription 模块(`app/subscription.py`)
```python
class SubscriptionStatus:
state: str
account_name: str
plan_name: str
expires_at: str
grace_expires_at: str
manage_url: str
notice_id: str
real_entitlement_allowed: bool
allows_product_workflows: bool # 只返回 real_entitlement_allowed
check_status(config=None, ...) -> SubscriptionStatus
safe_manage_url(value, base_url) -> str
```
订阅状态接口为 `GET /api/v1/cmshopee/subscription/status`。成功响应必须提供顶层严格布尔字段 `real_entitlement_allowed`;强制模式只认该字段,不使用展示状态 `status` 或服务端兼容字段 `allowed` 推断授权。`true` 只允许与 `active/grace` 同时出现,字段缺失、类型错误或组合矛盾统一归为“暂时无法验证”。`manage_url` 只接受与默认网关同主机的 HTTPS 地址。
AI 模型清单(`data/config/ai_models.json`,含本地明文密钥,已建;UI 由 设置复用):
```python