# 深度代码审查模式库 基于多个生产项目(Next.js/FastAPI/Go 全栈)实战总结的常见问题与修复方案。 ## TypeScript/JavaScript 专项 ### 类型安全 (来自实际项目教训) ```typescript // ============================================ // 问题 1: useState 泛滥 // 来源: ai-stats/page.tsx 中发现 6 处 useState // ============================================ // ❌ 实际项目中的坏代码 const [data, setData] = useState(null); const [report, setReport] = useState({}); // eslint-disable @typescript-eslint/no-explicit-any // 更糟: 直接禁用规则 // ✅ 修复: 定义完整接口类型 interface AiStatsData { totalReplies: number; avgQualityScore: number; channels: ChannelStatusData[]; } const [data, setData] = useState(null); // ============================================ // 问题 2: JSON.parse 无类型验证 // 来源: auth-store.ts 中 atob(token) 后直接 parse // ============================================ // ❌ 危险: 解析后未验证结构 const payload = JSON.parse(atob(parts[1])); return payload.role; // 可能 undefined // ✅ 使用 Zod 进行运行时验证 import { z } from 'zod'; const TokenPayload = z.object({ sub: z.string(), role: z.enum(['admin', 'user']), exp: z.number(), }); const result = TokenPayload.safeParse(JSON.parse(atob(parts[1]))); if (!result.success) throw new Error('Invalid token payload'); ``` ### 重复代码消除 (DRY) ```typescript // ============================================ // 问题 3: 工具函数在多处重复定义 // 来源: golden/page.tsx 和 customer/[id]/page.tsx 各自定义 formatRelativeTime // ============================================ // ❌ 多个文件各自实现相同逻辑 // golden/page.tsx: function formatRelativeTime(date) { ... } // customer/page.tsx: function formatRelativeTime(date) { ... } // ✅ 提取到共享模块 // lib/format.ts export function formatRelativeTime(date: string | Date | null): string { if (!date) return '-'; const d = new Date(date); if (isNaN(d.getTime())) return '-'; // ... 统一实现 } ``` ### 错误处理 ```typescript // ============================================ // 问题 4: fetch 后未检查 response.ok // 来源: ProjectX 项目 lib/api.ts // ============================================ // ❌ 缺少响应状态检查 const data = await fetch(url); // ✅ 完整错误处理链 async function request(url: string, options?: RequestInit): Promise { try { const response = await fetch(url, options); if (!response.ok) { const error = await response.json().catch(() => ({})); throw new ApiError(response.status, error.code, error.message); } return response.json(); } catch (error) { if (error instanceof ApiError) throw error; throw new ApiError(0, 'NETWORK_ERROR', '网络错误'); } } ``` ## Python/FastAPI 专项 ### 异常处理收窄 ```python # ============================================ # 问题 5: except Exception 吞掉所有错误 # 来源: auto_delivery_service.py:184 # ============================================ # ❌ 过宽的异常捕获 try: result = process_delivery(data) except Exception: return None # 数据库错误也被静默吞掉 # ✅ 分类处理异常 from sqlalchemy.exc import SQLAlchemyError try: result = process_delivery(data) except (ValueError, KeyError) as e: logger.warning(f"数据格式异常: {e}") return None except SQLAlchemyError as e: logger.error(f"数据库错误: {e}", exc_info=True) raise # DB 错误必须向上传播 ``` ### 数据库字段持久化 ```python # ============================================ # 问题 6: 内存中修改字段但从未持久化到 DB # 来源: example_selector.py:337 设置 last_used_at 但 batch update 只更新 times_used # ============================================ # ❌ 字段赋值但未包含在 batch update 中 golden.last_used_at = now_cst() # 内存中修改 # batch update 只更新 times_used, last_used_at 被遗漏 # ✅ batch update 必须包含所有修改字段 stmt = ( sa_update(GoldenExample) .where(GoldenExample.id == golden.id) .values( times_used=golden.times_used + 1, last_used_at=now_cst(), # 同步持久化 ) ) await session.execute(stmt) ``` ### 数据库约束完整性 ```python # ============================================ # 问题 7: 缺少唯一约束,依赖应用层去重 # 来源: models/example_usage.py # ============================================ # ❌ 无数据库层面约束 class ExampleUsage(Base): conversation_id = Column(Integer) golden_example_id = Column(Integer) # ✅ 添加唯一约束 + 复合索引 class ExampleUsage(Base): conversation_id = Column(Integer, nullable=False) golden_example_id = Column(Integer, nullable=False) __table_args__ = ( UniqueConstraint('conversation_id', 'golden_example_id', name='uq_conv_golden'), Index('ix_conv_golden', 'conversation_id', 'golden_example_id'), ) ``` ## Go/Gin 专项 ```go // 检查清单: // - [ ] error 是否全部处理(不允许 _ 忽略 error) // - [ ] goroutine 是否有 recover 保护 // - [ ] 数据库连接是否使用连接池 // - [ ] GORM 查询是否避免了 N+1 // - [ ] context 是否正确传递和取消 ```