Severity Summary
🔴 Blocker: 0
🟡 Major: 3
🔵 Minor: 8
🟡
[Business] 排队队列死锁 — 第 4+ 个并发条目永久卡在 queued
→ review.service.ts:26(queue 数组从未 push)、:32-36(并发满分支)、:56-58(processQueue 无可消费)
Fix: 并发满分支 `queue.push(entryId)`,使 processQueue 能消费 DB 中的 queued 条目
🟡
[Interface] GET entries `limit` 无上限 — 可一次拉全表
→ entries.ts:50(parseInt(limit) 未 clamp)
Fix: `Math.min(parseInt(limit, 10) || 50, 500)`,offset 非负校验
🟡
[Security] 前端 token 存 localStorage + 无严格 CSP
→ web/src/services/api.ts(token 注入);index.css 大量内联样式使 CSP 受限
Fix: 换 httpOnly cookie 认证,或加严格 CSP(需与内联样式权衡);至少评审侧注入面已由 H3 封堵
🔵
[Business] 并发计数双源(DB `active.cnt` + 内存 `activeCount`),重启/多实例漂移
→ review.service.ts:32 / :43
Fix: 以 DB 为准或引入进程内调度器;单实例当前可接受
🔵
[Data] 评审收尾"写 ai_report + 插 review_snapshots + 删 clone 目录"多步非原子
→ review.service.ts(executeReview 尾部)
Fix: 包事务(写库两步),目录清理失败不影响评分一致性
🔵
[Performance] GET /projects 每项目一条统计 SQL(N+1)
→ projects.ts GET /
Fix: 单条 GROUP BY 查询;规模小可接受
🔵
[Redundancy] dimGuidelines「规模、功能点、技术难度」与「规模与功能点与技术难度」两段正文完全重复
→ review.service.ts dimGuidelines
Fix: 共用同一段指南文本
🔵
[Redundancy] PDF 与前端 SVG 雷达/条形图逻辑双份实现
→ pdf.service.ts / ProjectView.tsx(RadarChart/BarChart)
Fix: 可选,抽出共享 SVG 生成器(跨运行时,成本高,可保留)
🔵
[Redundancy] DEFAULT_DELIVERABLES 三处重复定义
→ ProjectView.tsx(DeliverablesView + DetailPanel)、entries.ts(init + export)
Fix: 收敛为共享常量
🔵
[Interface] 成功响应格式不一({success:true} vs 整条记录)
→ 各路由
Fix: 约定统一包装;前端已兼容,非阻塞
🔵
[Security] 改密码不使既有 JWT 失效(authSecret 未轮换);登录限流 Map 重启清零
→ auth.ts
Fix: 如需强制登出则轮换 AUTH_SECRET;限流可持久化(单管理员可接受)
Manual Review Required
权限模块:单管理员 token 24h、无刷新/撤销/轮换、localStorage 存储(单管理员工具可接受,需确认)
数据迁移:ALTER TABLE try/catch 幂等、无显式回滚计划(本规模可接受)
评审引擎执行参赛者仓库代码(npm install/build/start、spawn cmd)— 未信任代码执行,需沙箱(doc §8.2)
Knowledge Accumulation Suggestions
历史坑位 — 并发排队只写 DB 状态、未入内存队列(review.service.ts queue[] 从未 push)
业务规则 — max_score_cap / final_level 需在「评审管线 + 人工修正」双路径保持一致
架构约束 — 评审引擎需在隔离/沙箱环境运行,禁止裸机直跑参赛代码