diff --git a/BUGFIX.md b/BUGFIX.md index 27d076d..ac5800b 100644 --- a/BUGFIX.md +++ b/BUGFIX.md @@ -69,65 +69,41 @@ ## Medium — 建议修复 -- [ ] **#15 房间 ID 空间仅 9000 个** - - 文件:`src/lib/store.ts` - - 4 位数字 (1000-9999) 碰撞概率高,fallback 也没兜住 P2002 - - 修复:扩展到 6 位字母数字,或 catch P2002 后重试 +- [x] **#15 房间 ID 空间仅 9000 个** ✅ + - 扩展为 6 位字母数字 (30^6 ≈ 7.3 亿),createRoom 用 P2002 重试 -- [ ] **#16 盲盒想法编辑/删除有 TOCTOU** - - 文件:`api/blindbox/route.ts` PUT / DELETE - - 状态检查和修改之间可被并发抽取,drawn 的想法可能被编辑/删除 - - 修复:用 `updateMany({ where: { id, status: "in_pool" } })` 替代先查后改 +- [x] **#16 盲盒想法编辑/删除有 TOCTOU** ✅ + - PUT/DELETE 改用 updateMany/deleteMany 原子操作 -- [ ] **#17 lat/lng 未校验为合法坐标** - - 文件:`api/room/create/route.ts` - - `lat=0`(赤道有效坐标)被当 falsy 拒绝;非数值字符串也能通过 - - 修复:`Number.isFinite(lat)` + 范围校验 (-90~90, -180~180) +- [x] **#17 lat/lng 未校验为合法坐标** ✅ + - Number.isFinite + 范围校验 (-90~90, -180~180) -- [ ] **#18 swipe action 未校验** - - 文件:`api/room/[id]/swipe/route.ts` - - 非 `like`/`pass` 值静默通过,只增 count 不记偏好 - - 修复:校验 `action` 是否为允许的值 +- [x] **#18 swipe action 未校验** ✅ + - 校验 action 必须为 'like' 或 'pass' -- [ ] **#19 JSON.parse(preferences) 可能崩溃** - - 文件:`api/user/route.ts` GET - - 残损 JSON 导致 500,用户无法加载 profile - - 修复:使用 safe parse helper,fallback 为 `{}` +- [x] **#19 JSON.parse(preferences) 可能崩溃** ✅ + - GET 和 PUT 响应均加 try/catch,fallback {} -- [ ] **#20 ShareCardModal data 每次新引用触发 useEffect** - - 文件:`src/components/ShareCardModal.tsx` - - 内联对象导致 data 引用每次变化,图片重复加载 - - 修复:改用 `imageSrc` 字符串作为 useEffect 依赖,或在调用侧 useMemo +- [x] **#20 ShareCardModal data 每次新引用触发 useEffect** ✅ + - 依赖改为 imageSrc 字符串而非整个 data 对象 -- [ ] **#21 BlindboxRoomPage 多处 setTimeout 未清理** - - 文件:`src/app/blindbox/[code]/page.tsx` - - confetti rAF 循环、确认退出 3s 定时器、focus 定时器均未在 unmount 时清理 - - 修复:用 ref 存储 timer ID,useEffect return 中 clearTimeout / cancelAnimationFrame +- [x] **#21 BlindboxRoomPage 多处 setTimeout 未清理** ✅ + - timersRef 统一收集所有 setTimeout,unmount 时批量清理;confetti rAF 用 alive ref 控制 -- [ ] **#22 外部 API (高德) 失败返回泛化 500** - - 文件:`api/room/create`、`api/location/suggest`、`api/location/regeo` - - 用户不知道是定位服务不可用 - - 修复:wrap fetch 加 try/catch,throw `ApiError("位置服务暂时不可用", 503)` +- [x] **#22 外部 API (高德) 失败返回泛化 500** ✅ + - 三个高德 API 路由 fetch 加 try/catch → 503 -- [ ] **#23 navigation.ts location.split(",") 不校验格式** - - 文件:`src/lib/navigation.ts` - - 无逗号的字符串产生 `undefined` 坐标 - - 修复:校验 split 结果长度为 2 且两部分非空 +- [x] **#23 navigation.ts location.split(",") 不校验格式** ✅ + - 校验 split 结果长度为 2 且两部分非空 -- [ ] **#24 handleReset / handleNarrow 吞掉 fetch 错误** - - 文件:`src/app/room/[id]/page.tsx` - - 无 res.ok 检查,失败时用户无反馈 - - 修复:检查 res.ok,失败时 throw +- [x] **#24 handleReset / handleNarrow 吞掉 fetch 错误** ✅ + - 检查 res.ok,失败时 toast 提示 -- [ ] **#25 confettiCanvasRef 未使用(死代码)** - - 文件:`src/app/blindbox/[code]/page.tsx` - - 渲染了 canvas 但 confetti() 使用全局实例 - - 修复:删除 ref 和 `` 元素 +- [x] **#25 confettiCanvasRef 未使用(死代码)** ✅ + - 删除 ref 和 canvas 元素 -- [ ] **#26 requireString 接受纯空格字符串** - - 文件:`src/lib/validation.ts` - - `" "` 是 truthy 但没有实质内容 - - 修复:加 `.trim()` 校验 +- [x] **#26 requireString 接受纯空格字符串** ✅ + - 加 .trim() 校验 ---