docs: refine software subscription task
This commit is contained in:
+3
-3
@@ -104,10 +104,10 @@
|
||||
| T-623 | 图片生成任务单图 / 多图筛选 | T-614, T-620 | 已完成:`ImageGenerationTaskAdmin` 的列表右侧新增“输入图片类型”筛选,提供“单图生图”和“多图生图”。数据库聚合计数识别 1 条子输入的单图、2 条及以上的多图;无子输入且历史 `input_image` 非空的任务兼容归单图;无输入图任务不归类。筛选可与既有状态 / 日期过滤叠加,结果不重复;未改模型、迁移、任务状态、计费、API、worker、媒体文件或详情页缩略图。已通过 6 条目标 admin 测试、`check`、迁移一致性和 `init.ps1`。 | DONE |
|
||||
| T-624 | 蝦皮圈设备登记与会话观测 | T-301, T-401 | 已完成:新增 `apps.licensing`、`ClientDevice` / `DeviceSession` / `DeviceBindingAudit` 与 `licensing.0001_initial`。设备登记用 API Key 鉴权、心跳用短期 `X-Device-Session`;重复登记不重复建设备并轮换旧会话,设备/公钥/会话只存摘要或 hash,活跃时间默认每日节流。admin 只读展示设备、会话和审计摘要,不回显敏感值。现有生成、余额、模型目录、异步任务和通用 API Key 语义未改变。已通过本地迁移、21 条目标回归测试、`check`、迁移一致性和 `init.ps1`。 | DONE |
|
||||
| T-625 | 蝦皮圈设备使用关联与迁移观测 | T-624, T-613, T-614, T-615 | 已完成阶段 1 关联观测:有效 `X-Device-Session` 仅在标题、同步图片、异步图片提交、vision 的预扣 `CallRecord` 写入服务端解析的可空 `client_device`;无头旧调用保持原返回、扣点、提交和轮询。新增 `billing.0010_callrecord_client_device_and_more` 与 `(client_device, created_at)` 索引;admin 支持展示 / 按设备筛选。`generation_route_usage` 新增 `product_code`、内部 `client_device_id`、`device_session_present` 白名单字段,不记录设备摘要、公钥、令牌、Key、prompt 或图片。伪造/过期会话在预扣前返回 401,吊销/跨账号会话返回 403;仍不做订阅授权拦截。已通过 4 条新增入口/兼容/安全/遥测测试及 14 条 licensing/生成回归、迁移、`check` 和一致性验证。 | DONE |
|
||||
| T-626 | 软件套餐、权益与设备席位基础模型 | T-624, T-401 | 已完成阶段 2 基础模型:新增 `SoftwarePlan`、`SoftwareEntitlement`、`LicenseSeat`、`LicenseEvent` 和 `licensing.0002_softwareentitlement_licenseseat_licenseevent_and_more`。授予时复制套餐名称/价格/时长/设备数/宽限期快照并预创建固定席位;`(entitlement, seat_number)` 唯一。服务层以事务锁权益和席位执行授予、续期、撤销、绑定与解绑,所有人工操作原因必填并写事件;续期从 `max(now, expires_at)` 起算,不触碰钱包。admin 提供套餐维护及权益授予/续期/撤销专用入口,权益/席位/事件只读。未接购买、支付、迁移凭证或生成授权。已通过套餐快照、续期、撤销、审计、后台权限及双连接单席位并发测试、迁移和 `check`。 | DONE |
|
||||
| T-626 | 软件套餐、权益与设备席位基础模型 | T-624, T-401 | 已完成阶段 2 基础模型:新增 `SoftwarePlan`、`SoftwareEntitlement`、`LicenseSeat`、`LicenseEvent` 和 `licensing.0002_softwareentitlement_licenseseat_licenseevent_and_more`。授予时复制套餐名称/价格/时长/设备数/宽限期快照并预创建固定席位;`(entitlement, seat_number)` 唯一。服务层以事务锁权益和席位执行授予、续期、撤销、绑定与解绑,所有人工操作原因必填并写事件;续期从 `max(now, expires_at)` 起算,不触碰钱包。admin 提供套餐维护及权益授予/续期/撤销专用入口,权益/席位/事件只读。未接购买、支付、迁移凭证或生成授权。已通过套餐快照、续期、撤销、审计、后台权限及双连接单席位并发测试、迁移和 `check`。**评审遗留(2026-07-21,须在 T-629 强制前修复)**:① `renew_software_entitlement` 只更新权益自身字段,不刷新该权益下已签发 `DeviceCredential.expires_at`(签发时钉死为旧 `grace_expires_at`),续费用户在旧宽限期后会被判 `license_expired`;现有续期测试只断言权益未覆盖凭证。② `revoke_software_entitlement` 不吊销凭证也不释放席位,裁决层由 `is_usable_at()` 兜底不构成安全问题,但留下 `revoked_at=null` 凭证与占用席位的数据残留。 | DONE |
|
||||
| T-627 | 存量用户迁移权益、网页确认与设备凭证 | T-624, T-626, T-501 | 已完成存量迁移闭环:新增 `LegacyMigrationGrant`、短时 `MigrationRequest` 和 `DeviceCredential`,均只保存 hash/摘要;admin 通过显式用户+套餐授予迁移资格和快照,新注册用户无自动路径。客户端用旧 API Key + 当前设备会话申请迁移并一次性取得凭证明文;同账号 portal 确认后事务内绑定席位、按 hash 签发凭证,重复确认/轮询不重复占位或签发。用户可自助解绑,凭证吊销并释放席位且写审计。新增迁移 API、portal 确认/设备页;旧生成 API 完全不变。已覆盖资格、缺会话、跨账号、过期、重复确认、凭证 hash、状态轮询与解绑;迁移 / `check` / 迁移一致性通过。 | DONE |
|
||||
| T-628 | 蝦皮圈专属授权入口与影子校验 | T-625, T-626, T-627, T-613, T-614 | 已完成:新增 `/api/v1/cmshopee/` 的 title、vision、异步图片提交和已接受任务读取,均复用原 API / 计费 core。统一授权判定检查设备会话、凭证、用户、产品、席位和权益,返回 `device_not_bound` / `device_mismatch` / `license_required` / `license_expired`;当前仅写脱敏 `would_reject` 日志,不阻断专属或通用调用。通用 `/api/v1/generate/*` 未改,任务读取不追加订阅校验;`CMSHOPEE_AUTHORIZATION_SHADOW_MODE=true` 为部署口径。已验证正确 / 缺失 / 过期凭证判定、迁移流程回归、`check` 和迁移一致性。 | DONE |
|
||||
| T-629 | 软件套餐购买、续订订单与权益入账 | T-626, T-627, T-628, T-304, T-305 | 新增与 `RechargeOrder` **分离**的 `SoftwareOrder`,实现蝦皮圈套餐选择、创建待支付订单、支付回调/主动查单后的幂等权益发放与续期;不得把软件订阅金额兑换为点数,也不得改动充值订单或既有点数回调契约。订单须锁定套餐名称、价格、时长、设备数等快照,回调必须验签、校验订单金额/通道、按订单号幂等;同一订单重复回调最多延长一次。portal 提供订阅状态、套餐购买/续订入口和订单只读记录,支付失败/取消保持 pending/failed 语义并保留审计。复用现有支付网关的微信路径但不假设自动续费协议;第一版“月订阅”是用户每月主动续订,自动代扣仅登记后续任务。测试覆盖订单快照、重复回调、金额不匹配、并发回调、续期起算、退款/撤销后的权益状态、充值链路回归;真实生产支付验收依赖既有微信回调闭环修复,未提供商户条件时仅按 mock/SDK 契约测试。 | TODO |
|
||||
| T-628 | 蝦皮圈专属授权入口与影子校验 | T-625, T-626, T-627, T-613, T-614 | 已完成:新增 `/api/v1/cmshopee/` 的 title、vision、异步图片提交和已接受任务读取,均复用原 API / 计费 core。统一授权判定检查设备会话、凭证、用户、产品、席位和权益,返回 `device_not_bound` / `device_mismatch` / `license_required` / `license_expired`;当前仅写脱敏 `would_reject` 日志,不阻断专属或通用调用。通用 `/api/v1/generate/*` 未改,任务读取不追加订阅校验;`CMSHOPEE_AUTHORIZATION_SHADOW_MODE=true` 为部署口径。已验证正确 / 缺失 / 过期凭证判定、迁移流程回归、`check` 和迁移一致性。**评审说明(2026-07-21)**:`CMSHOPEE_AUTHORIZATION_SHADOW_MODE` 当前仅被写入日志事件,没有任何分支依据它决定放行或拒绝,属阶段 2 预期行为;须留档提醒——切换强制拦截不是改环境变量即可,需要在专属入口显式加入拒绝分支并同步部署说明,避免运维误判为纯配置开关。 | DONE |
|
||||
| T-629 | 软件套餐购买、续订订单与权益入账 | T-626, T-627, T-628, T-304, T-305 | **DOING。** 新增与 `RechargeOrder`、`PointsLedger` 完全分离的 `SoftwareOrder`,实现蝦皮圈套餐选择、创建待支付订单、支付回调/主动查单后的幂等权益发放与续期;不得把软件订阅金额兑换为点数,也不得修改既有充值订单、充值回调或钱包入账契约。订单必须锁定产品代码、套餐名称、金额、币种、时长、设备数、宽限期和支付通道快照,并保存明确的发放结果(目标权益、`LicenseEvent`、发放时间);支付渠道加 `payment_txn_no` 必须只归属一个软件订单,已支付订单收到不同交易号一律拒绝。微信支付能力仅复用验签、下单、查单的渠道适配,订阅回调/查单服务与路由独立于 `RechargePayment` / `apply_recharge_payment()`。回调必须验签、校验订单金额/通道、锁订单并按订单号幂等;同一订单的并发或重复回调最多发放/续期一次。portal 提供订阅状态、套餐购买/续订入口和订单只读记录;订单状态明确为 `pending -> paid`,渠道下单失败为 `failed`,过期支付票据为 `expired`,不得把未支付订单发放权益。第一版“月订阅”由用户每月主动续订,不假设自动代扣协议。**退款范围:本卡不新增退款发起或自动退款回收权益。** 已支付订单的退款及关联权益撤销走运营人工流程、必须按订单留痕;要支持自动回收时,需另建按订单权益周期/发放账本任务,不能简单缩短累计 `expires_at` 而误伤后续续费。测试覆盖订单/套餐快照、同订单重复与并发回调、不同交易号、金额/通道/验签不一致、主动查单、续期起算、未支付不发权益、充值链路回归,以及回调 HTTP 契约。真实生产支付验收依赖既有微信回调到账闭环修复;未提供商户条件时仅按 mock/SDK 契约测试。**前置修复(本卡支付上线验收前完成)**:先修 T-626 遗留 ①,在 `renew_software_entitlement` 事务内同步刷新该权益下所有未吊销 `DeviceCredential.expires_at`,并测试续期后凭证仍可通过授权判定;再修遗留 ②,撤销权益时吊销未吊销凭证并释放其占用席位,逐项写审计事件。 | DOING |
|
||||
|
||||
## 里程碑
|
||||
|
||||
|
||||
@@ -76,10 +76,10 @@
|
||||
|
||||
- 已完成:T-001 初始化 Django + DRF 项目骨架;T-002 建立 apps 目录、自定义 User 与配置;T-003 接通 django-admin 与最小测试;T-004 Phase 0 骨架审核修补;T-101 Provider 适配器层 + 移植 cmbot 调用;T-102 AiModel + ModelAlias 模型 + 别名解析;T-103 配置变更审计;T-104 跑通一次录制标题生成;T-105 Phase 1 AI 层审核修补;T-201 User / UserWallet / ApiKey / PointsLedger / CallRecord 模型;T-202 PricingRule / ExchangeRate 模型 + 计费计算;T-203 并发安全扣点 / 退点;T-204 Phase 2 计费核心审核加固;T-301 API Key 鉴权;T-302 生成标题 / 图片接口;T-303 余额查询接口;T-304 充值回调;T-305 扫码充值下单 + 轮询;T-306 Phase 3 对外 API 安全加固;T-501 注册 / 登录(allauth);T-502 API Key 自助管理页;T-503 个人中心 / 记录页;T-504 充值页(扫码 + 轮询到账);T-505 Phase 4 用户端审核优化;T-401 运营后台完善;T-402 完整验收 MVP;T-403 部署 / 运行文档;T-601 可用别名发现;T-602 django-admin 中文化(第 1-3 层);T-603 django-admin 中文化(第 4 层·字段级);T-604 中文敏感词本地过滤;T-605 免邮箱验证策略落地;T-606 公开首页 + 客户端下载入口;T-607 桌面端最新版本检查接口;T-608 新用户注册赠送试用点数(当前 10 点);T-609 桌面端版本检查接口增加强制更新标记;T-610 首页导入模板下载入口;T-611 用户端品牌名统一为虾皮圈;T-612 生图同步接口止血(上游硬截止 + 长请求池校准);T-613 抽生成核心 service(计费+审核+上游共享 core);T-614 生图异步任务化接口(提交+轮询,新增不动旧接口);T-615 旧同步生图接口用量遥测 + 弃用口径;T-616 生图失败自动重试 2 次;T-617 桌面端版本检查接口增加文件大小字段;T-618 客户端发布版本后台必填文件校验元数据。
|
||||
- 已完成补充:T-619 多张图片理解并返回文字;T-620 图生图支持单图 / 多图主图与参考图;T-622 图片生成任务后台图片缩略预览;T-623 图片生成任务单图 / 多图筛选;T-624 蝦皮圈设备登记与会话观测;T-625 蝦皮圈设备使用关联与迁移观测;T-626 软件套餐、权益与设备席位基础模型;T-627 存量用户迁移权益、网页确认与设备凭证。
|
||||
- 正在进行:无。
|
||||
- 待开始:T-629 软件套餐购买、续订订单与权益入账。T-621 注册赠点运营后台配置继续留在 Backlog。真实支付回调到账闭环、客户端发布、生产多图理解模型配置和线上旧同步接口用量观察仍可继续拆任务。
|
||||
- 正在进行:T-629 软件套餐购买、续订订单与权益入账;先修 T-626 的凭证续期同步与撤销清理,再建设与充值隔离的软件订单、支付回调和 portal。
|
||||
- 待开始:T-621 注册赠点运营后台配置继续留在 Backlog。真实支付回调到账闭环、客户端发布、生产多图理解模型配置和线上旧同步接口用量观察仍可继续拆任务。
|
||||
- 当前 blocker:支付商户真实密钥/证书与生产 SDK 依赖仍待提供;微信回调到账闭环仍需真实支付验收;真实 AI 标题生成已在线上跑通,图片生成慢 / 504 / 客户端超时风险已拆为 T-612~T-616 并完成工程侧处理。
|
||||
- 下一个可领取任务:T-629 软件套餐购买、续订订单与权益入账。T-621 保留在 Backlog,具体范围见 [`06-tasks.md`](06-tasks.md)。
|
||||
- 当前任务:T-629 软件套餐购买、续订订单与权益入账。软件订阅订单与 `RechargeOrder` / 点数账本隔离;第一版不实现自动退款回收权益,真实支付验收仍依赖微信回调到账闭环。T-621 保留在 Backlog,具体范围见 [`06-tasks.md`](06-tasks.md)。
|
||||
|
||||
## 当前可运行内容
|
||||
|
||||
|
||||
+14
@@ -2090,3 +2090,17 @@
|
||||
- 配置:增加 `CMSHOPEE_AUTHORIZATION_SHADOW_MODE=true`,当前仅作为影子部署口径与日志字段;正式执行阻断需单独任务、灰度和回滚验收。
|
||||
- 验证:凭证正确、无设备、无凭证和过期的判定测试已覆盖;T-627 迁移专项 4 条回归、`manage.py check` 与 `makemigrations --check --dry-run` 通过。
|
||||
- 下一步:领取 T-629,建立与点数充值订单隔离的软件套餐购买、续订订单和幂等权益入账。
|
||||
|
||||
## 2026-07-21 评审:T-624~T-628 静态代码复核
|
||||
|
||||
- 范围:`apps/licensing/` 全模块、`apps/api/views.py` 授权入口、`apps/api/telemetry.py`、`apps/api/urls.py`、`apps/licensing/admin.py`。因当前 WSL 环境未安装 Python/Django,未能实际运行测试与 `check`,本次为静态代码审查,卡片自述的测试通过情况未独立复验。
|
||||
- 结论:五张卡与实现一致,判定达标。设备与公钥只存 HMAC/SHA256 摘要,会话与凭证只存 hash;重复登记复用设备并轮换旧会话;遥测字段为白名单,未泄露摘要、令牌、Key、prompt;401/403 映射与卡片一致;专属入口以 Mixin + 独立路由隔离,通用 `/api/v1/generate/*` 未受影响。
|
||||
- 发现①(须在 T-629 前修):`renew_software_entitlement` 不刷新已签发 `DeviceCredential.expires_at`。凭证有效期在签发时钉死为当时的 `grace_expires_at`,续费后不随权益延长,用户会在旧宽限期后被判 `license_expired`。当前影子模式不阻断故未暴露,切强制即影响付费用户。已写入 T-626 遗留与 T-629 前置修复。
|
||||
- 发现②:`revoke_software_entitlement` 不吊销凭证也不释放席位,裁决层由 `is_usable_at()` 兜底,属数据残留非安全问题。已随①一并登记到 T-629。
|
||||
- 发现③:`CMSHOPEE_AUTHORIZATION_SHADOW_MODE` 仅写入日志,无任何分支依据它拒绝请求。符合阶段 2 预期,但已在 T-628 卡片留档,提醒切强制需要改代码而非改配置。
|
||||
|
||||
## 2026-07-21 开始:T-629 软件套餐购买、续订订单与权益入账
|
||||
|
||||
- 先收紧任务口径:软件订单、支付回调与权益发放必须和 `RechargeOrder` / `PointsLedger` 隔离;支付交易号在软件订单域内唯一,并可追溯至目标权益和授权事件。
|
||||
- 第一版只支持用户主动月度续订,不实现自动代扣,也不实现支付退款后的自动权益回收;退款与撤销走带订单号和原因的运营人工流程。自动回收须在未来以按订单权益周期/发放账本为基础单列任务,不能直接回滚累计到期时间。
|
||||
- 实现顺序:先修 T-626 的凭证续期同步和撤销清理,再实现独立软件订单、独立回调/查单、portal 与 HTTP/并发回归测试。
|
||||
|
||||
Reference in New Issue
Block a user