mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-13 21:33:32 +08:00
fix: harden unicode safety checks
This commit is contained in:
@@ -39,7 +39,7 @@ AI 编写修复 → AI 审查修复 → AI 表示“看起来正确” → 漏
|
||||
→ 修复了生产路径,忘记了沙箱路径
|
||||
→ AI 审核时再次遗漏(第 4 次出现)
|
||||
|
||||
修复 4:测试在首次运行时立即捕获了问题 ✅
|
||||
修复 4:测试在首次运行时立即捕获了问题 PASS:
|
||||
```
|
||||
|
||||
模式:**沙盒/生产环境路径不一致**是 AI 引入的 #1 回归问题。
|
||||
@@ -249,14 +249,14 @@ User: "バグチェックして" (or "/bug-check")
|
||||
**频率**:最常见(在 4 个回归问题中观察到 3 个)
|
||||
|
||||
```typescript
|
||||
// ❌ AI adds field to production path only
|
||||
// FAIL: AI adds field to production path only
|
||||
if (isSandboxMode()) {
|
||||
return { data: { id, email, name } }; // Missing new field
|
||||
}
|
||||
// Production path
|
||||
return { data: { id, email, name, notification_settings } };
|
||||
|
||||
// ✅ Both paths must return the same shape
|
||||
// PASS: Both paths must return the same shape
|
||||
if (isSandboxMode()) {
|
||||
return { data: { id, email, name, notification_settings: null } };
|
||||
}
|
||||
@@ -282,7 +282,7 @@ it("sandbox and production return same fields", async () => {
|
||||
**频率**:在使用 Supabase/Prisma 添加新列时常见
|
||||
|
||||
```typescript
|
||||
// ❌ New column added to response but not to SELECT
|
||||
// FAIL: New column added to response but not to SELECT
|
||||
const { data } = await supabase
|
||||
.from("users")
|
||||
.select("id, email, name") // notification_settings not here
|
||||
@@ -291,7 +291,7 @@ const { data } = await supabase
|
||||
return { data: { ...data, notification_settings: data.notification_settings } };
|
||||
// → notification_settings is always undefined
|
||||
|
||||
// ✅ Use SELECT * or explicitly include new columns
|
||||
// PASS: Use SELECT * or explicitly include new columns
|
||||
const { data } = await supabase
|
||||
.from("users")
|
||||
.select("*")
|
||||
@@ -303,13 +303,13 @@ const { data } = await supabase
|
||||
**频率**:中等——当向现有组件添加错误处理时
|
||||
|
||||
```typescript
|
||||
// ❌ Error state set but old data not cleared
|
||||
// FAIL: Error state set but old data not cleared
|
||||
catch (err) {
|
||||
setError("Failed to load");
|
||||
// reservations still shows data from previous tab!
|
||||
}
|
||||
|
||||
// ✅ Clear related state on error
|
||||
// PASS: Clear related state on error
|
||||
catch (err) {
|
||||
setReservations([]); // Clear stale data
|
||||
setError("Failed to load");
|
||||
@@ -319,14 +319,14 @@ catch (err) {
|
||||
### 模式 4:乐观更新未正确回滚
|
||||
|
||||
```typescript
|
||||
// ❌ No rollback on failure
|
||||
// FAIL: No rollback on failure
|
||||
const handleRemove = async (id: string) => {
|
||||
setItems(prev => prev.filter(i => i.id !== id));
|
||||
await fetch(`/api/items/${id}`, { method: "DELETE" });
|
||||
// If API fails, item is gone from UI but still in DB
|
||||
};
|
||||
|
||||
// ✅ Capture previous state and rollback on failure
|
||||
// PASS: Capture previous state and rollback on failure
|
||||
const handleRemove = async (id: string) => {
|
||||
const prevItems = [...items];
|
||||
setItems(prev => prev.filter(i => i.id !== id));
|
||||
@@ -362,11 +362,11 @@ const handleRemove = async (id: string) => {
|
||||
|
||||
| AI 回归模式 | 测试策略 | 优先级 |
|
||||
|---|---|---|
|
||||
| 沙盒/生产环境不匹配 | 断言沙盒模式下响应结构相同 | 🔴 高 |
|
||||
| SELECT 子句遗漏 | 断言响应中包含所有必需字段 | 🔴 高 |
|
||||
| 错误状态泄漏 | 断言出错时状态已清理 | 🟡 中 |
|
||||
| 缺少回滚 | 断言 API 失败时状态已恢复 | 🟡 中 |
|
||||
| 类型转换掩盖 null | 断言字段不为 undefined | 🟡 中 |
|
||||
| 沙盒/生产环境不匹配 | 断言沙盒模式下响应结构相同 | 高 |
|
||||
| SELECT 子句遗漏 | 断言响应中包含所有必需字段 | 高 |
|
||||
| 错误状态泄漏 | 断言出错时状态已清理 | 中 |
|
||||
| 缺少回滚 | 断言 API 失败时状态已恢复 | 中 |
|
||||
| 类型转换掩盖 null | 断言字段不为 undefined | 中 |
|
||||
|
||||
## 要 / 不要
|
||||
|
||||
|
||||
Reference in New Issue
Block a user