fix(subscription): preserve wallet overflow snapshots#5649
Conversation
WalkthroughThree subscription persistence functions ( ChangesSubscription Targeted Persistence and Snapshot Test
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
model/subscription_test.go (1)
84-91: 💤 Low value
FOR UPDATEis a no-op on SQLite—consider a comment or conditional.SQLite serializes writes at the database level and ignores row-level locking hints. The
gorm:query_option "FOR UPDATE"clause here mimics production flow (which targets MySQL/PostgreSQL), but new contributors may be confused if they expect actual row locking in this test.This isn't a bug—the test still validates the column update behavior—but a brief comment documenting the SQLite limitation would improve clarity.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@model/subscription_test.go` around lines 84 - 91, The `FOR UPDATE` clause in the query at the transaction setup is not enforced by SQLite since it serializes writes at the database level and ignores row-level locking hints. Add a comment above the `tx.Set("gorm:query_option", "FOR UPDATE")` line explaining that while this `FOR UPDATE` clause is a no-op on SQLite, it is included to mimic the production behavior that would be used with MySQL or PostgreSQL, ensuring the test validates the same code path as production.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@model/subscription_test.go`:
- Around line 84-91: The `FOR UPDATE` clause in the query at the transaction
setup is not enforced by SQLite since it serializes writes at the database level
and ignores row-level locking hints. Add a comment above the
`tx.Set("gorm:query_option", "FOR UPDATE")` line explaining that while this `FOR
UPDATE` clause is a no-op on SQLite, it is included to mimic the production
behavior that would be used with MySQL or PostgreSQL, ensuring the test
validates the same code path as production.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3a574b08-67a4-410c-9920-13d68ab0bb7f
📒 Files selected for processing (2)
model/subscription.gomodel/subscription_test.go
Important
📝 变更描述 / Description
本 PR 修复订阅用量更新时误覆盖
user_subscriptions快照字段的问题。allow_wallet_overflow是从订阅计划复制到用户订阅上的快照字段。当前订阅重置额度、预扣额度、退款回滚额度时使用了Save,会把整个UserSubscription结构写回数据库。对于历史数据中allow_wallet_overflow为 SQLNULL的记录,Go 会按bool零值读成false,后续只想更新用量字段的操作就可能把该快照列误写成显式false。修复方式:把相关路径从整行
Save改为只更新自身负责的列:amount_usedlast_reset_timenext_reset_timeupdated_at这样订阅重置、预扣、退款回滚不会再改动
allow_wallet_overflow等订阅快照字段。同时新增回归测试:构造
allow_wallet_overflow = NULL的用户订阅,依次执行 reset、pre-consume、refund delta,确认该列仍保持NULL,不会被用量更新改写。🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
暂无关联 Issue。
提交前已搜索现有 Issues 和 PRs,关键词包括:
allow_wallet_overflowwallet overflowno matched subscription for group未发现重复提交。已有相关 PR #5616 只处理重复迁移列的问题,不覆盖本次整行
Save覆盖快照字段的问题。✅ 提交前检查项 / Checklist
Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。📸 运行证明 / Proof of Work
本地验证已通过:
同类修复已先在 fork 部署验证:
ghcr.io/mxyhi/new-api:main-e26d7dca5f57x-new-api-version: main-e26d7dca5f57allow_wallet_overflow=false的异常行数:0no matched subscription for group: cc-max、panic或fatal