fix: 配额系统添加 pro 套餐并支持未知套餐 fallback 到 free #1262

Merged
xiaoxia merged 3 commits from fix/quota-pro-tier-fallback into develop 2026-08-07 15:16:44 +08:00
Owner

问题

用户 subscription_plan="pro" 时,QUOTA_TIERS 只有 free/basic/premium,导致 get_tier("pro") 返回 None,所有配额 limit=0,创建标题等操作被 429 拦截。

修复

packages/domain/quota.py

  1. 在 QUOTA_TIERS 中添加 "pro" 套餐,配额与 premium 完全一致(100GB存储、100视频/月、20并发、无限模板等)
  2. get_tier() 方法对未知套餐 fallback 到 free 而非返回 None,防止未来再有类似问题
  3. get_limit() 方法同步更新 fallback 逻辑

测试更新

  • 更新 3 个测试文件中所有关于未知套餐的测试用例,验证 fallback 到 free 的行为
  • 新增 TestProTier 测试类(3个测试)验证 pro 套餐正确性
  • 全量配额相关测试 202 个全过
## 问题 用户 subscription_plan="pro" 时,QUOTA_TIERS 只有 free/basic/premium,导致 get_tier("pro") 返回 None,所有配额 limit=0,创建标题等操作被 429 拦截。 ## 修复 ### packages/domain/quota.py 1. 在 QUOTA_TIERS 中添加 "pro" 套餐,配额与 premium 完全一致(100GB存储、100视频/月、20并发、无限模板等) 2. `get_tier()` 方法对未知套餐 fallback 到 free 而非返回 None,防止未来再有类似问题 3. `get_limit()` 方法同步更新 fallback 逻辑 ### 测试更新 - 更新 3 个测试文件中所有关于未知套餐的测试用例,验证 fallback 到 free 的行为 - 新增 TestProTier 测试类(3个测试)验证 pro 套餐正确性 - 全量配额相关测试 202 个全过 ✅
xiaoxia added 1 commit 2026-08-07 14:57:45 +08:00
fix: 配额系统添加 pro 套餐并支持未知套餐 fallback 到 free
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 39s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m0s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m7s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m31s
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m44s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m8s
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
ffc56aa511
- 在 QUOTA_TIERS 中添加 pro 套餐,配额与 premium 相同
- QuotaRegistry.get_tier() 对未知套餐 fallback 到 free 而非返回 None
- QuotaRegistry.get_limit() 同步更新 fallback 逻辑
- 更新所有相关单元测试以匹配新行为
- 新增 TestProTier 测试类验证 pro 套餐正确性

修复问题:用户 subscription_plan='pro' 时所有配额 limit=0 导致创建操作被拦截

🚀 预览环境已部署

项目 详情
PR号 #1262
预览链接 https://pr-1262.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1262 | | 预览链接 | [https://pr-1262.preview.xiaoxiajianji.com](https://pr-1262.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
auto-approve-bot added 1 commit 2026-08-07 14:59:53 +08:00
style: auto-format with black + isort + prettier [skip ci-format-check]
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 41s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 46s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m27s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m38s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m45s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m1s
AI Code Review / AI Code Review (pull_request) Failing after 2m46s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m2s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m31s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 5m35s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 6m16s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m44s
CI/CD Pipeline / CI Gate (pull_request) Successful in 34s
9ca7ae89b5
xiaoxia added 1 commit 2026-08-07 15:09:05 +08:00
fix: 解决 AI Code Review 阻塞级问题
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 26s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 49s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 59s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m19s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m34s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m14s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 4m54s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 4m14s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 4m27s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 4m14s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Successful in 5m38s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m21s
CI/CD Pipeline / CI Gate (pull_request) Successful in 9s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 51s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 53s
b1f4b1d034
1. pro 套餐改用别名引用 premium,避免硬编码重复(DRY 原则)
2. 恢复 get_tier() 返回 Optional[QuotaTier],未知套餐返回 None
3. 恢复 get_limit() 对未知套餐返回 0(默认拒绝策略)
4. 同步恢复所有单元测试的原始断言逻辑
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:否
  • 阻塞级问题数量:0 个

📊 审查概览

  • 整体评价:通过
  • 建议级问题数量:2 个

🔴 阻塞级问题(必须修复)

💡 改进建议(不阻塞合并)

  1. [tests/unit/domain/test_quota.py: 384] 测试断言完整性

    • 具体内容:在 test_list_tiers 方法中,移除了 assert "premium" in tiers 的显式检查。虽然通过 assert len(tiers) == 4 和检查其他三个套餐可以间接推断 premium 存在,但保留显式检查能更清晰地表达测试意图,防止未来代码变更导致套餐名称拼写错误但数量巧合一致的情况。建议参考 tests/unit/test_quota_domain.py 中的写法,保留 premium 的显式断言。
  2. [tests/unit/domain/test_quota.py: 389] 测试注释与断言不一致

    • 具体内容:test_get_limit_nonexistent_plan 方法的注释更新为“不存在的套餐 fallback 到 free 配额”,但断言依然是 assert reg.get_limit(...) == 0。根据另一个测试文件 tests/unit/test_quota.py 中的行为(test_check_unknown_plan 期望 limit 为 0),实际逻辑应为返回 0 而非 free 配额(free 配额为 2GB)。建议将注释修正为“不存在的套餐返回 0”或确认代码逻辑是否真的发生了变更。

良好实践

  • 使用别名引用 QUOTA_TIERS["pro"] = QUOTA_TIERS["premium"] 来实现完全一致的配额逻辑,避免了数据重复维护,符合 DRY 原则。
  • 新增了 TestProTier 测试类,专门针对 pro 套餐进行了存在性、一致性和具体维度的测试,覆盖充分。

格式检查通过 | 逻辑审查通过 | 性能良好


🤖 由 AI 代码审查机器人自动生成 | 2026-08-07 07:15:11 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:否 - 阻塞级问题数量:0 个 ### 📊 审查概览 - 整体评价:通过 - 建议级问题数量:2 个 ### 🔴 阻塞级问题(必须修复) 无 ### 💡 改进建议(不阻塞合并) 1. **[tests/unit/domain/test_quota.py: 384] 测试断言完整性** - 具体内容:在 `test_list_tiers` 方法中,移除了 `assert "premium" in tiers` 的显式检查。虽然通过 `assert len(tiers) == 4` 和检查其他三个套餐可以间接推断 `premium` 存在,但保留显式检查能更清晰地表达测试意图,防止未来代码变更导致套餐名称拼写错误但数量巧合一致的情况。建议参考 `tests/unit/test_quota_domain.py` 中的写法,保留 `premium` 的显式断言。 2. **[tests/unit/domain/test_quota.py: 389] 测试注释与断言不一致** - 具体内容:`test_get_limit_nonexistent_plan` 方法的注释更新为“不存在的套餐 fallback 到 free 配额”,但断言依然是 `assert reg.get_limit(...) == 0`。根据另一个测试文件 `tests/unit/test_quota.py` 中的行为(`test_check_unknown_plan` 期望 limit 为 0),实际逻辑应为返回 0 而非 free 配额(free 配额为 2GB)。建议将注释修正为“不存在的套餐返回 0”或确认代码逻辑是否真的发生了变更。 ### ✅ 良好实践 - 使用别名引用 `QUOTA_TIERS["pro"] = QUOTA_TIERS["premium"]` 来实现完全一致的配额逻辑,避免了数据重复维护,符合 DRY 原则。 - 新增了 `TestProTier` 测试类,专门针对 `pro` 套餐进行了存在性、一致性和具体维度的测试,覆盖充分。 --- ✅ 格式检查通过 | ✅ 逻辑审查通过 | ✅ 性能良好 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-07 07:15:11 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia merged commit 5034e25749 into develop 2026-08-07 15:16:44 +08:00

🗑️ 预览环境已清理

PR #1262 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1262 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.