# 项目代码质量全景分析 & 重构计划 > 生成时间: 2026-03-02 | 分析工具: Claude Code 7-agent 并行审查 ## 模块评分总览 | # | 模块 | 评分 | 重构优先级 | 核心问题 | |---|------|------|-----------|----------| | 1 | 认证 & 用户 API | 7.5 | 高 | 无真正鉴权机制,userId 可伪造 | | 2 | 房间投票 API | 7.0 | 中 | atomicUpdateRoom 并发 lost update | | 3 | 盲盒系统 API | 7.0 | 中 | AI 错误静默吞掉,plan/route.ts 臃肿 | | 4 | 位置服务 API | 6.5 | 中 | 高德 API 调用代码 4 处重复,无超时/缓存 | | 5 | 前端页面 | 5.5 | 高 | blindbox/[code] 1300行 37个useState | | 6 | 组件 & Hooks | 6.5 | 高 | ShareCard 三兄弟 60% 重复,BlindboxPlan 742行 | | 7 | 基础设施 & Lib | 6.5 | 高 | Room JSON blob 模型、前后端代码边界模糊 | **全局平均: 6.6 / 10** --- ## 跨模块共性问题 TOP 5 ### 1. 无真正的认证机制 (影响: 全局) 所有 API 的 userId 由客户端 localStorage 传入,任何人可伪造身份操作他人数据。登录接口签发了用户信息但没有 JWT/Cookie,形同虚设。 ### 2. AI/外部 API 错误被静默吞掉 (影响: 盲盒、位置、Lib) ai.ts 所有函数的 catch 都是 return null,amap 调用无超时,blindboxPlanGen.ts 多处空 catch。生产环境问题排查极其困难。 ### 3. 巨型组件/页面 (影响: 前端) - blindbox/[code]/page.tsx: 1300行, 37个useState, 12个useEffect - BlindboxPlan.tsx: 742行 - blindbox/page.tsx: 658行, 18个useState - MatchResult.tsx: 513行 ### 4. 代码重复 (影响: 组件、位置、盲盒) - ShareCard 三个文件 ~1024行,重复率 ~60% - 高德 transit API 调用在 4处 复制粘贴 - 标签更新映射代码 3处 重复 - generateRoomCode 函数 2处 相同实现 ### 5. Room 数据模型: JSON Blob 反模式 (影响: 房间、Lib) Room.data 用一个 JSON 字符串存储全部状态,无法利用数据库约束、索引和关联查询。同项目的 BlindBoxRoom 系列已证明团队有能力做好关系化建模。 --- ## 重构路线图 ### P0 -- 立即修复 (安全/数据完整性) - [ ] **实现 JWT/httpOnly Cookie 认证链路** (2-3天) - 登录签发 JWT,设置 httpOnly cookie - 新增 getAuthUserId(req) 从 cookie 中提取用户 - 所有 /api/user/*, /api/blindbox/*, /api/room/* 改用服务端鉴权 - 前端移除 userId 参数传递,改为 cookie 自动携带 - [ ] **修复 atomicUpdateRoom 并发安全** (0.5天) - SQLite 下使用 IMMEDIATE 事务或应用层锁 - 如迁移到 PostgreSQL,使用 SELECT ... FOR UPDATE - [ ] **所有 catch 块至少加 console.error** (0.5天) - ai.ts: tagIdea, suggestIdeas, generateSchedule, refinePlan, suggestAlternativeItems - blindboxPlanGen.ts: 多处空 catch - 前端组件: BlindboxPlan, MatchResult, SwipeDeck, RestaurantCard 等 - API routes: applyTags 的 fire-and-forget ### P1 -- 短期重构 (代码质量) - [ ] 拆分 blindbox/[code]/page.tsx 为 5-6 个子模块 + hooks (2-3天) - [ ] 抽取 ShareCardShell 消除三兄弟重复 (1天) - [ ] 拆分 BlindboxPlan.tsx (1天) - [ ] 完善 amap.ts 为完整 API 客户端 (1天) - [ ] 统一数据获取层 SWR 替代裸 fetch+useState (1-2天) ### P2 -- 中期优化 (架构改善) - [ ] Room JSON blob 拆为关系化模型 (3-5天) - [ ] 引入 zod 做 AI 返回值 + request body 校验 (1-2天) - [ ] blindboxPlanGen.ts 拆为 4 个子模块 (1天) - [ ] ApiError 独立 + validation 纯函数化 (0.5天) - [ ] plan/route.ts PATCH/GET 内部拆分 (0.5天) ### P3 -- 长期改善 - [ ] 部分页面引入 Server Component 混合渲染 - [ ] 补全 a11y (aria-label、键盘导航) - [ ] SSE 重连策略 (指数退避) - [ ] 文件重命名 (store.ts → roomRepository.ts) --- ## 各模块详细分析 ### 模块1: 认证 & 用户 API (7.5/10) **亮点:** - 已有 apiHandler 统一错误处理框架 - validation.ts 提供输入校验工具 - P2002 唯一约束冲突有分层防御 **问题:** 1. [Critical] userId 由客户端传入可伪造,无 JWT/session 2. [Critical] 登录成功后无状态维持(不签发 token) 3. [Warning] JSON.parse 部分未做防御处理 4. [Warning] GET /api/user 无需鉴权即可查任意用户 email 5. [Warning] login 接口缺少暴力破解防护 6. [Suggestion] 用户序列化逻辑重复 7. [Suggestion] achievements 业务逻辑偏重可抽 service ### 模块2: 房间投票 API (7.0/10) **亮点:** - atomicUpdateRoom 原子操作封装 - buildRoomStatus 视图层分离 - roomEvents 发布/订阅模式 - 各 handler 职责单一 (10-30行) **问题:** 1. [Critical] atomicUpdateRoom 事务隔离级别不足,并发 lost update 2. [Critical] Room.data JSON blob 反模式 3. [Warning] SSE 连接中被踢用户无实时通知 4. [Warning] 房间过期清理机制不可靠 (进程内变量) 5. [Warning] getRoomData 中 fire-and-forget delete 6. [Warning] buildRoomStatus 每次查 DB 获取 UserProfile,缺缓存 7. [Suggestion] 房间 ID 使用 Math.random() 非密码学安全 ### 模块3: 盲盒系统 API (7.0/10) **亮点:** - Agent + Legacy 双路径容错设计 - requireMembership 公共权限检查 - IdeaTags 多维标签系统设计合理 - 路由数量合理,职责清晰 **问题:** 1. [Critical] applyTags 静默吞掉所有错误 2. [Critical] retag 端点串行处理无并发控制 3. [Critical] plan/route.ts 227行承担过多职责 4. [Warning] 标签更新映射代码 3处 重复 5. [Warning] roomId 验证方式不一致 6. [Warning] plan/stream 未使用 apiHandler 7. [Warning] plan GET 的 pending/history 有 N+1 查询 8. [Suggestion] blindboxPlanGen.ts 808行应拆分 ### 模块4: 位置服务 API (6.5/10) **亮点:** - 三个 location 端点都有测试覆盖 - apiHandler 统一包装 **问题:** 1. [Critical] 高德 transit API 调用在 4处 复制粘贴 2. [Critical] fetch 调用缺少超时控制 3. [Critical] debug 端点未用 apiHandler 且缺 try-catch 4. [Warning] amap.ts 封装过于薄弱 (仅 7行) 5. [Warning] 缺少缓存策略 6. [Warning] fetch 响应未检查 HTTP 状态码 7. [Warning] 输入验证不够严格 (经纬度未校验范围) 8. [Suggestion] POI 类型定义散落多文件 ### 模块5: 前端页面 (5.5/10) **亮点:** - 路由设计清晰语义明确 - Skeleton 骨架屏使用 **问题:** 1. [Critical] blindbox/[code]/page.tsx 1300行 37个useState "上帝组件" 2. [Critical] blindbox/page.tsx 658行表单代码重复 3. [Critical] profile/page.tsx 521行 18个useState 4. [Warning] 数据获取方式不一致 (裸fetch vs SWR) 5. [Warning] userId 通过 URL 参数传递 6. [Warning] 错误静默吞掉 7. [Warning] panic/page.tsx 598行位置搜索逻辑应抽取 8. [Suggestion] 所有页面都是 "use client" 未利用 SSR 9. [Suggestion] 重复的页面布局模式 (ambient glow + 返回按钮) ### 模块6: 组件 & Hooks (6.5/10) **亮点:** - Hooks 设计整体合理 - Toast 系统简洁 - useShare 正确处理 AbortError **问题:** 1. [Critical] ShareCard 三兄弟 ~60% 代码重复 2. [Critical] BlindboxPlan.tsx 742行职责过多 3. [Warning] 多处错误被静默吞掉 4. [Warning] useRoomPolling SSE 重连策略不足 5. [Warning] MatchResult.tsx 513行职责偏重 6. [Warning] useEffect 依赖项不完整 7. [Suggestion] 可访问性(a11y)严重不足 8. [Suggestion] ShareCard inline style 缺注释说明原因 ### 模块7: 基础设施 & Lib (6.5/10) **亮点:** - 前后端目前无实际交叉引用错误 - sceneConfig/avatars 等纯函数设计良好 **问题:** 1. [Critical] Room JSON blob + WeekendPlan/Decision JSON 存储 2. [Warning] store.ts 命名严重误导 (服务端代码叫 store) 3. [Warning] api.ts 混合两类职责 4. [Warning] blindboxPlanGen.ts 808行过大 5. [Warning] 两套房间模型 (Room vs BlindBoxRoom) 设计差异大 6. [Warning] ai.ts AI 返回值校验不统一 7. [Warning] userId.ts 基于 localStorage UUID 无安全性 8. [Suggestion] runAgentLoop 硬编码 finalize_plan 工具名 9. [Suggestion] roomEvents 进程内存级发布订阅