Skip to content

Commit 5f96f75

Browse files
committed
fix: 修复规则删除无法生效的问题
- 修复IndexedDBStorageManager.saveRules()方法,先清空再保存确保数据一致性 - 添加完整的测试套件验证修复效果 - 使用Playwright复现并验证问题修复 - 添加演示脚本展示修复前后行为差异 问题描述: - 删除规则后点击刷新按钮,被删除的规则会重新出现 - 根本原因是saveRules只使用put操作,不会删除数据库中的旧规则 修复方案: - 修改saveRules方法先clear()清空所有规则,再put()保存新规则 - 确保数据库状态与UI状态完全一致 测试验证: - 手动测试:使用Playwright验证删除和刷新功能 - 自动化测试:添加单元测试和集成测试 - 演示脚本:可视化展示修复效果 影响: - ✅ 规则可以永久删除 - ✅ 刷新功能正常工作 - ✅ 无数据损坏风险 - ✅ 向后兼容
1 parent ff2fadf commit 5f96f75

File tree

9 files changed

+1698
-20
lines changed

9 files changed

+1698
-20
lines changed

BUGFIX-RULE-DELETION.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Bug Fix: Rule Deletion Issue
2+
3+
## Problem Description
4+
5+
Rules could not be permanently deleted from the system. When a user deleted a rule through the UI, the rule would disappear temporarily but would reappear after clicking the refresh button.
6+
7+
## Root Cause Analysis
8+
9+
The issue was in the `IndexedDBStorageManager.saveRules()` method in `src/utils/indexedDBStorage.ts`. The method was using only `put()` operations to save rules, which would add or update existing rules but would not remove rules that were no longer in the provided array.
10+
11+
### Before Fix
12+
```typescript
13+
async saveRules(rules: FilterRule[]): Promise<boolean> {
14+
try {
15+
await this.executeTransaction(STORES.RULES, 'readwrite', (store) => {
16+
const rulesStore = store as IDBObjectStore;
17+
return Promise.all(rules.map(rule =>
18+
new Promise<void>((resolve, reject) => {
19+
const request = rulesStore.put(rule);
20+
request.onsuccess = () => resolve();
21+
request.onerror = () => reject(request.error);
22+
})
23+
));
24+
});
25+
return true;
26+
} catch (error) {
27+
console.error('批量保存规则失败:', error);
28+
return false;
29+
}
30+
}
31+
```
32+
33+
### Problem Flow
34+
1. User deletes a rule → `handleDeleteRule` creates new array without deleted rule
35+
2. `saveRulesToStorage(newRules)` is called with filtered array
36+
3. `saveRules()` uses `put()` to save remaining rules
37+
4. **Deleted rule remains in IndexedDB** because `put()` doesn't remove it
38+
5. When refreshing, `loadRules()` loads all rules from IndexedDB, including the "deleted" one
39+
40+
## Solution
41+
42+
Modified the `saveRules()` method to first clear all existing rules before saving the new ones, ensuring the database state exactly matches the provided rule array.
43+
44+
### After Fix
45+
```typescript
46+
async saveRules(rules: FilterRule[]): Promise<boolean> {
47+
try {
48+
await this.executeTransaction(STORES.RULES, 'readwrite', (store) => {
49+
const rulesStore = store as IDBObjectStore;
50+
51+
// First clear all existing rules
52+
const clearPromise = new Promise<void>((resolve, reject) => {
53+
const clearRequest = rulesStore.clear();
54+
clearRequest.onsuccess = () => resolve();
55+
clearRequest.onerror = () => reject(clearRequest.error);
56+
});
57+
58+
// Wait for clear to complete, then save new rules
59+
return clearPromise.then(() => {
60+
return Promise.all(rules.map(rule =>
61+
new Promise<void>((resolve, reject) => {
62+
const request = rulesStore.put(rule);
63+
request.onsuccess = () => resolve();
64+
request.onerror = () => reject(request.error);
65+
})
66+
));
67+
});
68+
});
69+
return true;
70+
} catch (error) {
71+
console.error('批量保存规则失败:', error);
72+
return false;
73+
}
74+
}
75+
```
76+
77+
## Testing
78+
79+
### Manual Testing with Playwright
80+
1. Created two test rules
81+
2. Deleted one rule → Rule count changed from (2/2) to (1/1)
82+
3. Clicked refresh button → Rule count remained (1/1), deleted rule did not reappear
83+
4. Deleted remaining rule → Rule count changed to (0/0)
84+
5. Clicked refresh button → No rules reappeared
85+
86+
### Automated Tests
87+
Added unit tests in:
88+
- `src/utils/__tests__/indexedDBStorage.test.ts` - Tests the fix logic
89+
- `src/components/RuleManager/__tests__/RuleManager.test.tsx` - Tests the complete deletion flow
90+
91+
All tests pass successfully.
92+
93+
## Impact
94+
95+
- ✅ Rules can now be permanently deleted
96+
- ✅ Refresh button works correctly after deletion
97+
- ✅ No data corruption or loss
98+
- ✅ Backward compatible with existing data
99+
- ✅ Performance impact is minimal (clear + put operations)
100+
101+
## Files Modified
102+
103+
1. `src/utils/indexedDBStorage.ts` - Fixed the `saveRules()` method
104+
2. `vitest.config.ts` - Added test configuration
105+
3. `src/test/setup.ts` - Test setup file
106+
4. `src/utils/__tests__/indexedDBStorage.test.ts` - Unit tests
107+
5. `src/components/RuleManager/__tests__/RuleManager.test.tsx` - Integration tests
108+
6. `package.json` - Added test scripts
109+
110+
## Verification
111+
112+
To verify the fix works:
113+
114+
1. Start the development server: `npm run dev`
115+
2. Open the application and go to Rule Management
116+
3. Create some test rules
117+
4. Delete a rule and observe it disappears
118+
5. Click the refresh button
119+
6. Verify the deleted rule does not reappear
120+
121+
Or run the automated tests:
122+
```bash
123+
npm run test:run
124+
```

0 commit comments

Comments
 (0)