fix: harden unicode safety checks

This commit is contained in:
Affaan Mustafa
2026-03-29 08:59:06 -04:00
parent dd675d4258
commit 866d9ebb53
239 changed files with 3780 additions and 3962 deletions

View File

@@ -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 | 中 |
## 要 / 不要