# 追光AI 变更日志

## 2026-05-28 UI优化 + 社区页面修复

### 🟡 HeroBanner 新增 orange 配色方案
- **问题**: Skills 页面深红色（crimson `#881337→#e11d48`）视觉过深，用户反馈体验不佳
- **修复**: 新增 `orange` 配色方案 `#c2410c → #ea580c → #f97316 → #fb923c`
- **文件**: `src/components/common/HeroBanner.tsx` — 新增 `orange` scheme，STAR_COUNTS 添加 `orange: 80`，SVG 圆环渲染加入 orange
- **页面**: `src/app/skills/SkillsPageClient.tsx` — colorScheme 从 `crimson` 改为 `orange`

### 🟡 社区话题详情页 Server Component 错误修复
- **问题**: `/community/topic/[id]` 页面报错 `Event handlers cannot be passed to Client Component props`
- **根因**: 页面是 Server Component，但内联了 `onSubmit={async (e) => {...}}` 事件处理函数
- **修复**: 提取回复表单为独立 Client Component `ReplyForm.tsx`，页面仅渲染 `<ReplyForm topicId={topicId} isLocked={topic.isLocked} />`
- **文件**: `src/app/community/topic/[id]/ReplyForm.tsx`（新增）、`src/app/community/topic/[id]/page.tsx`（修改）
- **同时**: ReplyForm 增加 `disabled` 状态防止重复提交

### 📁 变更统计
| 类型 | 数量 |
|------|------|
| 修改文件 | 3个（HeroBanner.tsx + SkillsPageClient.tsx + community/topic/[id]/page.tsx） |
| 新增文件 | 1个（ReplyForm.tsx） |
| 新增配色 | 1个（orange） |
| TypeScript检查 | 零错误通过 |

---

## 2026-05-28 全盘安全扫描 + 系统优化（6项修复）

### 🔴 P0 安全修复：任意用户可创建工具
- **admin/tools/route.ts POST**: 此前无任何认证，任意登录用户可直接创建工具
- **修复**: 添加 `requireAdmin()` 认证检查，输入参数校验（name/websiteUrl/categoryId非空），categoryId有效性校验（存在性检查），slug自动去重
- **注**: 扫描全部25个后台写操作API，其余24个已有requireAdmin

### 🔴 P0 FK回退硬编码修复（4处）
- **问题**: `categoryId || 1` — id=1 在生产数据库不存在（分类从165开始），导致FK约束失败
- **修复方式**: 动态取数据库第一个有效分类 `category.findFirst({ select: { id: true } })` 替代硬编码 `1`
- **修复文件**:
  | 文件 | 修复 |
  |------|------|
  | `scripts/task3-check-tools.mjs` | 自动发布时 FK 回退 |
  | `src/app/api/admin/tools/route.ts` | 创建工具 POST |
  | `src/app/api/admin/pending/batch-publish/route.ts` | 批量发布待审核工具 |
  | `src/app/api/admin/pending-skills/batch-publish/route.ts` | 批量发布待审核技能 |
  | `src/app/api/admin/pending-skills/publish-all/route.ts` | 一键发布所有待审核技能 |

### 🟡 P1 批量操作安全加固
- **validation.ts**: `toolImportSchema.max(100)`、`skillImportSchema.max(100)`、`newsImportSchema.max(50)`、`checkTypeSchema.max(50)`
- **批量发布API**: `pending/batch-publish` 和 `pending-skills/batch-publish` 添加 `ids.length > 500` 上限检查
- **问题**: 原无上限，恶意请求可一次处理任意多条记录

### 🟡 定时任务全盘扫描结果
- **lib库**: prisma/deepseek/github/logo-fetcher/rate-limit 全部符合规范 ✅
- **脚本**: 全部使用 `mariadb://` 协议 + `PrismaMariaDb` adapter ✅
- **API**: 25个后台POST中24个已有requireAdmin（1个漏洞已修复） ✅
- **TypeScript**: `tsc --noEmit` 零错误通过 ✅

### 📊 定时任务执行情况（05-27 → 05-28）
| 任务 | 状态 | 说明 |
|------|------|------|
| Task5 更新星值 | ✅ 正常 | 更新37个技能星值 |
| Task3 工具巡检 | ⚠️ 服务器未更新 | 本地已修复FK回退，需部署脚本到服务器 |
| Task6 评测热门 | ✅ 正常 | 无待评测技能，reviewed:0（正常） |
| Task4 发现技能 | ✅ 正常 | 发现0，跳过42（GitHub新项目少） |
| Task1 发现工具 | ✅ 正常 | 发现6个，导入2个 |
| AI日报 | ✅ 正常 | 生成37号日报，6条内容 |
| Task7 新闻推社区 | ✅ 正常 | 创建6条帖子 |

### 📁 变更统计
| 类型 | 数量 |
|------|------|
| 修改文件 | 8个 |
| 修复问题 | 6项（1P0安全 + 4P0 FK + 1P1批量上限） |
| TypeScript检查 | 零错误通过 |

---

## 2026-05-27 定时任务根因修复 + 新闻推社区功能上线

### 🔴 P0 根因修复：定时任务全部不运行（5月25日故障）

**诊断过程：**
- SSH 调查发现 `logs/` 目录不存在，crontab 环境不加载 `.env` 变量
- 首次修复（wrapper + install-cron）后测试 task5 报错：`error parsing connection string, format must be 'mariadb://'`
- 进一步发现 `.env` 文件值带单引号（`DATABASE_URL='mysql://...'`），`xargs` 导出方式无法正确处理

**三层根因 + 修复：**

| 层次 | 问题 | 修复 |
|------|------|------|
| 环境变量加载 | crontab 不加载 `.env` → 创建 `cron-wrapper.sh` 统一入口，使用 `source` + `set -a`/`set +a` |
| .env 值格式 | 带单引号导致 `SET NAMES utf8mb4'` SQL语法错误 → 去除所有值的引号 |
| 数据库协议 | `mysql://` 与 PrismaMariaDb 不兼容 → 21个脚本添加 `.replace('mysql://', 'mariadb://')` |

### 🔴 P0 脚本语法修复
- **task1-discover-tools.mjs**: 移除 TypeScript 类型注解（`const errors: string[]` / `const categoryMap: Record<string, number>`）— `.mjs` 文件不支持 TS 语法
- **task6-review-hot.mjs**: 移除 `prisma.skillReview.create()` 中的 `tags` 字段 — SkillReview 模型无此字段，Prisma 报 `Unknown argument 'tags'`
- **task7-news-to-community.mjs**: CATEGORY_MAP slug 映射修复 — `ai-products/tech-discussion/open-source/industry-trends` → `ai-tools/ai-news/tech/discuss`（匹配 DB 实际 slug）

### 🟢 新功能上线
- **Task7 新闻推社区**: `scripts/task7-news-to-community.mjs` — 每天 08:00 将日报新闻分发到社区 4 个板块
  - 映射规则：product→AI工具推荐 / business→AI资讯 / model→技术探讨 / opensource→技术探讨 / policy→AI资讯 / insight→观点讨论
  - 首次运行测试：9条日报全部成功分发（[AI资讯]×6, [技术探讨]×2, [观点讨论]×1）

### 🛠 新增工具脚本
- `scripts/fix-db-url.cjs` — 批量修复 21 个脚本的 `mysql://` → `mariadb://` 协议
- `scripts/fix-ts-types.cjs` — 批量移除 `.mjs` 文件中的 TypeScript 类型注解
- `scripts/check-categories.cjs` — 检查数据库社区板块

### 📊 测试验证结果（7个任务全部通过）
| 任务 | 测试结果 |
|------|----------|
| Task5 星值更新 | ✅ 更新37⭐，0失败 |
| Task3 工具巡检 | ✅ 巡检463个，网站失效32个 |
| Task6 评测热门 | ✅ 评测2个（Snailclimb/JavaGuide 4.4⭐, system-prompts 3.4⭐） |
| Task4 技能发现 | ✅ 正常执行 |
| Task1 工具发现 | ✅ 发现10个AI工具，入库6个 |
| 日报生成 | ✅ 生成9条AI日报 |
| Task7 新闻推社区 | ✅ 9条全部分发到社区板块 |

### 📁 变更统计
| 类型 | 数量 |
|------|------|
| 修改的服务器脚本 | 21个（协议修复）+ 3个（bug修复） |
| 新增脚本 | 3个（fix-db-url.cjs, fix-ts-types.cjs, check-categories.cjs） |
| 修复的根因 | 3层（env加载 + 引号 + 协议） + 4个脚本bug |
| 服务器验证 | 7/7 任务全部测试通过 |

---

## 2026-05-25 全面审查优化（三轮扫描 + 43项修复）

### 🔴 P0 安全修复
- **.env入.gitignore**: `.env` 和 `.env.production` 加入忽略列表，创建 `.env.example` 模板文件
- **CSP/HSTS安全头**: next.config.mjs 添加 Content-Security-Policy、Strict-Transport-Security、Permissions-Policy
- **Logo安全加固**: 5MB大小限制 + SVG script/iframe/on-event 标签消毒 + MD5→SHA256
- **middleware权限收紧**: VIP用户不再能访问 /admin/* 和 /api/admin/*，仅admin角色可访问
- **单条发布去重**: pending-skills/[id]/publish 添加 name/sourceUrl/slug 三重去重检查，冲突返回409
- **Web更新星级GitHub认证**: update-stars API 添加 GITHUB_TOKEN 环境变量认证（限流60→5000次/小时）
- **删除危险API**: pending-skills/route.ts 的 DELETE 方法（原可无条件清空全表）已移除
- **skill-discoverer绕过审核**: Web自动发现统一改为写 pendingSkill 表（status:pending），不再跳过审核
- **prisma默认连接修复**: DATABASE_URL未设置时抛出明确错误，移除硬编码默认连接串

### 🔴 P0 可靠性修复
- **deepseek.ts超时重试**: OpenAI客户端添加 timeout:120000 + maxRetries:2，模型名改为 DEEPSEEK_MODEL 环境变量
- **github.ts超时重试**: Octokit 添加 timeout:30000，新增 withRetry 指数退避重试，403/404/422 不重试
- **脚本层DeepSeek保护**: 4个定时脚本(daily-discover/daily-news/task1/task6)添加 AbortSignal.timeout(120000) + withRetry 重试
- **脚本启动验证**: 定时脚本启动时验证 DEEPSEEK_API_KEY + DATABASE_URL 存在性
- **auth.ts OAuth竞态修复**: GitHub OAuth 并发创建用户时 P2002 唯一约束冲突自动回退 findFirst

### 🔴 P0 性能修复
- **skill-discoverer N+1优化**: 批量预加载 sourceUrl/slug/分类到内存 Set，DB查询从 ~360次 降至 ~22次（↓94%）
- **后台API分页限制**: 6个管理后台 API findMany 添加 take:500/1000 防全表扫描
- **getUserStats优化**: 改用 _count 聚合替代加载全量关联记录取 .length

### 🟡 P1 修复
- **分类动态加载**: discover-tools 页面分类列表从硬编码改为 /api/categories 动态加载
- **星级字段统一**: update-stars API 同时写入 rating + githubStars，统一提取 starsToRating() 函数
- **fetch-logos并发Bug修复**: processWithConcurrency 改用 Set<Promise> + then(cleanup) 模式
- **批量发布冲突不删除**: 冲突工具改为跳过标记，不再静默物理删除
- **check-tools API重试**: 添加指数退避重试（最多2次）
- **前端空指针修复**: 13处 email?.split / overallAvg?.toFixed / createdAt?.toLocaleDateString 可选链
- **logo-fetcher日志**: 9处空白 catch 块添加 console.warn 日志
- **rate-limit清理**: 每5分钟自动清理过期IP记录，防止内存无限增长
- **公开API缓存**: 5个公开API添加 Cache-Control 响应头（30s~300s分级缓存）

### 🔴 已修复的前台Bug
- **/reviews 评测列表不显示**: ReviewsList.tsx 添加 useEffect 在挂载时触发初始数据加载

### 📁 变更统计
| 类型 | 数量 |
|------|------|
| 修改文件 | ~55个 |
| 新增文件 | 1个（.env.example） |
| 修复问题 | 43项 |
| TypeScript检查 | 零错误通过 |

---

## 2026-05-25 页面重构 + HeroBanner五色方案

### 🎨 页面重构为三栏布局
- **统一布局**: `grid-cols-[208px_1fr_280px]` (左侧栏208px + 内容区 + 右侧栏280px)
- **/reviews**: HeroBanner + 左侧(外部热度排行+评测分值排行) + 右侧(五维模型+评测说明)
- **/community**: HeroBanner + 左侧(本月活跃用户+积分排行) + 右侧(社区指南)
- **/daily**: 保持原有三栏结构

### 🌈 HeroBanner 五色方案
- **重构组件**: 从三元表达式改为 `SCHEMES` 配置表，代码量从560行减至410行
- **5种配色**:
  | 页面 | 配色 | 背景渐变色 | 高亮色 |
  |------|------|-----------|--------|
  | 首页 `/` | 🔵 cosmos 星空蓝 | `#1e3a5f → #1d4ed8` | `#93c5fd` |
  | 技能 `/skills` | 🩷 crimson 玫红 | `#881337 → #e11d48` | `#fda4af` |
  | 日报 `/daily` | 🟠 dawn 黎明金 | `#78350f → #a16207` | `#fcd34d` |
  | 评测 `/reviews` | 🟣 aurora 极光紫 | `#4c1d95 → #6d28d9` | `#c4b5fd` |
  | 社区 `/community` | 🟢 forest 森林绿 | `#064e3b → #047857` | `#6ee7b7` |
- **接口变更**: 旧 `highlightColor + starStyle` → 新 `colorScheme`，一个参数搞定

### 📁 新增/修改
| 文件 | 操作 | 说明 |
|------|------|------|
| `src/components/common/HeroBanner.tsx` | 重写 | 5色方案+配置表 |
| `src/app/reviews/page.tsx` | 重写 | 三栏布局+左侧排行 |
| `src/app/community/page.tsx` | 重写 | 三栏布局+左侧排行 |
| `src/app/community/CommunitySidebar.tsx` | 新增 | 活跃用户+积分排行 |
| `src/app/api/user/rankings/route.ts` | 新增 | 用户排行API |
| `src/components/layout/Header.tsx` | 修改 | 社区导航图标更换 |

---

## 2026-05-25 等级体系升级 + 论坛二级分类 + 会员空间

### 🔥 20级成长体系 (类似QQ)
- **从4级扩展到20级**: LV01(0分) → LV20(50000分)
- **等级图标**: ⭐(初级) → ⭐⭐⭐(中级) → 🌟(高级) → 🌟🌟(精英) → 🌟🌟🌟(大师)
- **旧等级迁移**: BRONZE→LV01, SILVER→LV03, GOLD→LV06, PLATINUM→LV10
- `src/lib/level-config.ts` — 20级完整配置（含每日限额表）
- **迁移脚本**: `scripts/run-migration-manual.mjs` (绕过shadow DB问题)

### 🔥 论坛二级分类结构
- **ForumCategory自引用关系**: parent/children (CategoryHierarchy)
- **6个父分类 + 24个子分类**:
  - 综合讨论区 → 新手入门/AI资讯/观点讨论
  - AI工具 → 聊天写作/图像创作/视频音频/代码编程/效率办公/数据分析/教育学习
  - 开源技能 → LLM框架/Agent框架/RAG技术/模型训练/部署推理/多模态/数据工程
  - 技术深度 → 算法原理/模型评测/安全对齐/硬件加速
  - 教程与分享 → 入门教程/实战项目/最佳实践
  - 社区互动 → 求助问答/求职招聘/闲聊灌水/反馈建议
- **修复脚本**: `scripts/fix-forum-categories.mjs` (修正孤立子分类parentId)
- `/community` 首页更新为显示二级分类结构

### 🆕 会员个人空间
- `/user/[id]` — 会员空间页面（资料/统计/话题/评论）
- **分享功能**: `ShareButton` 组件（原生API/Twitter/QQ/复制链接）
- **bio字段**: 用户个人简介，支持编辑（最多500字符）
- `/user` 页面新增bio编辑区域

### 🔧 技术修复
- 修复所有旧等级引用 (BRONZE → LV01)
- 修复 ShareButton 构建错误 (Twitter图标 → Link图标)
- 修复 LevelProgress 动态颜色逻辑 (基于等级数字计算)
- 数据库迁移标记为已应用: `20260525000000_expand_user_levels`

---

## 2026-05-24 会员功能优化 + 追光会论坛上线

### 🆕 积分体系
- **PointsHistory** 数据模型 — 记录所有积分变动，含原因/详情/关联信息
- **4级会员系统**: 青铜🥉(0分) → 白银🥈(100分) → 黄金🥇(500分) → 铂金💎(2000分)
- **积分规则**: 评论+5/被赞+2/发帖+10/回复+5/评价+8，含每日上限防刷分
- `src/lib/level-config.ts` — 客户端安全等级配置（无 Prisma 依赖）
- `src/lib/points-reward.ts` — 积分奖励引擎（rewardPoints / getUserStats / getUserPointsHistory）
- `/api/user/points` — 积分统计 + 历史查询 API

### 🆕 追光会（论坛）
- **3个新页面**: /community（首页）、/community/[category]（板块）、/community/topic/[id]（话题详情）
- **8个论坛板块**: 综合讨论/AI工具推荐/技能分享/技术探讨/教程指南/反馈建议/求职招聘/闲聊灌水
- **5个论坛API**: 分类/话题(CRUD)/回复(CRUD) 共10个端点
- **4个论坛组件**: ForumBoard / ForumTopicCard / ForumEditor / NotificationBell
- **种子脚本**: `scripts/seed-forum-categories.mjs`

### 🆕 评论系统(全新实现)
- `/api/comments` — GET获取（含用户等级/积分）+ POST创建（自动积分奖励+通知）
- `/api/comments/[id]/like` — 点赞/取消点赞（切换模式，+2分+通知）
- `CommentCard` — 评论卡片（等级徽章/评分/点赞/嵌套回复）
- `CommentThread` — 评论列表（分页/排序/回复面板）

### 🆕 通知系统
- `/api/notifications` — GET获取（含未读数）+ PUT标记已读
- `NotificationBell` — 导航栏通知铃铛（红点/下拉面板/自动已读）
- 自动触发: 评论回复/评论点赞/话题回复

### 🆕 会员UI组件
- `MemberBadge` — 等级徽章（3种尺寸，支持显示/隐藏积分）
- `LevelProgress` — 等级进度条（当前等级/下一级/进度百分比）

### 🔧 技术改进
- **NextAuth 类型扩展** (`src/types/next-auth.d.ts`) — Session/User/JWT 包含 level/points
- **auth.ts 增强** — JWT/Session回调包含 level/points
- **客户端安全架构** — level-config.ts 与 points-reward.ts 分离，避免客户端打包Node.js原生模块
- **Header 增强** — 新增社区导航链接 + 通知铃铛 + 会员等级徽章
- **/user 页面增强** — 积分进度条/积分明细/统计卡片

### 修复
- ForumPost 新增 `isAnswer` 字段（标记最佳回答）
- Prisma schema 日期默认值修正 `@default(now)` → `@default(now())`
- 迁移兼容问题处理（`prisma db push` 同步）

### 统计数据（本次新增）
- **新增文件**: 15个
- **新增API端点**: 15个
- **新增页面**: 3个
- **新增组件**: 8个
- **新增数据模型**: 1个（PointsHistory）

---

## 2026-05-24 全面技术文档生成
（详见历史 CHANGELOG 记录）