Repository navigation
fix: preserve independent rule changes during queued saves - #26
Merged
Merged
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
Bulk rule actions can submit an empty payload before the initial configuration fetch completes, causing the request to be rejected.
Pull request overview
This PR prevents queued built-in rule saves from overwriting independent changes by applying atomic partial updates.
Changes:
- Added a guarded
/api/config/builtin_rulesendpoint. - Updated frontend rule saves to submit deltas.
- Added concurrency, validation, bulk-update, and security regression tests.
File summaries
| File | Description |
|---|---|
tests/test_atomic_rule_updates.py |
Tests atomic updates and validation. |
frontend/src/pages/Settings.tsx |
Routes rule changes through queued saves. |
frontend/src/api/settings.ts |
Adds the partial rule-save API client. |
engine/panel.py |
Implements atomic built-in rule updates. |
Review details
Suppressed comments (1)
frontend/src/pages/Settings.tsx:1385
- Because
cfgis undefined during the initial config fetch,builtinRulesis{}and either button builds an empty payload. The new endpoint explicitly rejects empty objects (panel.py:3617-3619), so clicking All On/All Off before the fetch completes now returns 400 instead of applying the requested bulk action. Build the payload from the completeBUILTIN_RULE_GROUPSlist (or disable the buttons untilcfgis loaded) so the request is always non-empty and includes every rule.
save(() => saveBuiltinRules(next), t('settings.toast.allOn'))
}}>{t('settings.words.allOn')}</Button>
<Button size="sm" variant="outline" className="h-6 text-[11px]" onClick={() => {
const next = Object.fromEntries(Object.keys(builtinRules).map((r) => [r, false]))
save(() => saveBuiltinRules(next), t('settings.toast.allOff'))
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
改动说明 / What does this PR do?
连续修改不同规则时,保存队列虽然会依次发送请求,但请求里的整张规则表已经在入队前生成。如果两个操作使用同一旧快照,后一次成功保存会覆盖前一次修改;例如依次关闭 EMAIL 和 PHONE,最终 EMAIL 又恢复开启。
这次新增受现有控制面校验保护的
/api/config/builtin_rules接口,只在配置锁内合并明确修改的规则。单项开关和全部开启/关闭都沿用原来的保存队列、结果反馈及缓存刷新,避免携带无关规则的旧值。配置尚未加载或没有可用规则时,全部开启/关闭按钮会禁用,避免发送空请求。原有整体配置接口保持兼容。影响范围 / Scope
验证 / Validation
新增 4 项回归检查,覆盖独立修改、并发保存、批量及重复修改、非法更新的原子拒绝,以及 Host / Origin / token 校验。
本地 macOS / Python 3.13:539 项单元测试通过;Python 编译检查、流式和出口代理冒烟、前端构建、Lint、中英文字典对齐及版本一致性检查均通过。
自检 / Checklist