feat: 首次推送到Gitea - 完整项目代码 + 安全加固 + 知识库
This commit is contained in:
@@ -705,6 +705,15 @@
|
||||
| ForumPost | [topicId, createdAt] | 联合索引 |
|
||||
| Permission | [groupName, sortOrder] | 联合索引 |
|
||||
| User | [oauthProvider, oauthId] | 联合唯一 |
|
||||
| BotConfig | [userId] | 唯一索引 |
|
||||
| BotDailyStat | [botId, date] | 唯一索引 |
|
||||
| BotWeeklyReview | [botId, weekKey] | 唯一索引 |
|
||||
| BotPersona | [botId] | 主键索引 |
|
||||
| BotPersonaVariant | [botId, variantKey] | 唯一索引 |
|
||||
| BotPersonaAssignment | [refType, refId] | 唯一索引 |
|
||||
| BotPersonaMetric | [variantId, date] | 唯一索引 |
|
||||
| BotAdversarialLearning | [botId, weekKey] | 唯一索引 |
|
||||
| BotCrossForumAffinity | [botId, forumSlug] | 唯一索引 |
|
||||
|
||||
## 迁移历史
|
||||
|
||||
@@ -721,3 +730,13 @@
|
||||
| 9 | add_hot_score | 2026-05-08 | 添加热度评分(DailyReportItem.hotScore) |
|
||||
| 10 | add_skill_reviews | 2026-05-20 | 添加技能评测表+Skill扩展字段 |
|
||||
| 11 | add_task_system | 2026-05-24 | 添加任务调度系统+权限体系+社区功能 |
|
||||
| 12 | add_bot_system | 2026-06-07 | 添加数字人Bot系统(12张表: BotConfig/BotMemory/BotDailyStat/BotSkill/BotWeeklyReview/BotPersona/BotPersonaVariant/BotPersonaExperiment/BotPersonaAssignment/BotPersonaMetric/BotAdversarialLearning/BotCrossForumAffinity) |
|
||||
|
||||
---
|
||||
|
||||
## 开发规则引用
|
||||
> 数据模型变更必须遵守 [开发规则第十六章 - 数据模型与迁移规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):
|
||||
> - Prisma 命名约定:模型PascalCase→`@@map("snake_case")`,字段camelCase→`@map("snake_case")`
|
||||
> - 连接单例模式:`globalForPrisma` 防止热重载多实例
|
||||
> - Schema 变更流程:migrate dev → migrate status → migrate deploy(严禁DROP/TRUNCATE)
|
||||
> - 数据库隔离:仅操作 `zhuiguang_ai` 库
|
||||
|
||||
@@ -195,6 +195,18 @@ NextAuth认证端点(登录/回调/CSRF等)。
|
||||
| /api/admin/permissions | GET | 获取全部权限点列表 |
|
||||
| /api/admin/user-permissions | GET | 获取当前用户权限(roleId/userId/当前用户) |
|
||||
|
||||
### Bot管理API
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/bots/stats | GET | Bot表现统计(每日指标+汇总,支持?days和?botUserId) |
|
||||
| /api/admin/bots/experiments | GET | A/B实验看板数据(变体/实验/每日指标聚合) |
|
||||
| /api/admin/bots/experiments/run | POST | 手动触发A/B实验(body: {mode, lookback, noSwitch}) |
|
||||
| /api/admin/bots/experiments/variants | PATCH | 更新变体(权重/启用/重置样本) |
|
||||
| /api/admin/bots/experiments/variants | DELETE | 删除变体 |
|
||||
| /api/admin/bots/adversarial-learning | GET | 对抗学习看板(支持?weeks和?botUserId) |
|
||||
| /api/admin/bots/adversarial-learning/run | POST | 手动触发对抗学习(body: {weekKey, force, lookback, bot}) |
|
||||
|
||||
### 日报管理
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
@@ -223,3 +235,14 @@ NextAuth认证端点(登录/回调/CSRF等)。
|
||||
| discoveryPromptConfig | JSON | AI发现提示词配置(含toolPrompt/skillPrompt/newsPrompt/tagPool等) |
|
||||
| logoFetchConfig | JSON | Logo抓取策略配置 |
|
||||
| discoverSkillsScript | string | 技能探索脚本源码 |
|
||||
|
||||
---
|
||||
|
||||
## 开发规则引用
|
||||
> API 开发必须遵守 [开发规则第十七章 - API设计规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):
|
||||
> - 路由骨架:`export const dynamic = "force-dynamic"` + `Promise.all` 并行 + `Cache-Control` 头
|
||||
> - 错误处理:使用 [api-error.ts](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/src/lib/api-error.ts) 的 `badRequest`/`notFound`/`serverError`
|
||||
> - 响应格式:列表 `{ data, total, page, pageSize }`,统一使用 `total`
|
||||
> - 状态码:200/201/400/401/403/404/409/500
|
||||
> - 认证分层:middleware + `requireAdmin()` + `getServerSession()`
|
||||
> - 分页上限:`Math.min(pageSize, 100)`
|
||||
|
||||
@@ -11,12 +11,18 @@
|
||||
### /tools (工具列表)
|
||||
- 文件: `src/app/tools/page.tsx`
|
||||
- 组件: ToolsContent
|
||||
- 功能: 分类筛选侧边栏(一级分类)、定价模型筛选、搜索、分页、卡片网格展示
|
||||
- 功能: 分类筛选侧边栏(一级分类)、定价模型筛选、搜索、分页、卡片网格展示、**工具对比功能(CompareButton)** 🆕
|
||||
- 数据源: `/api/categories`, `/api/tools`
|
||||
|
||||
### /tools/compare (工具对比) 🆕
|
||||
- 文件: `src/app/tools/compare/page.tsx`
|
||||
- 组件: ComparePage(CompareProvider + CompareBar)
|
||||
- 功能: 最多4个工具并排对比,10维度对比表格(名称/分类/定价/特性/标签/评分/评论数/浏览数/官网)
|
||||
- 数据源: `/api/tools` (通过Context传递)
|
||||
|
||||
### /tools/[slug] (工具详情)
|
||||
- 文件: `src/app/tools/[slug]/page.tsx`
|
||||
- 功能: 工具完整信息展示、浏览计数+1、收藏按钮、评论评价(ReviewSection)
|
||||
- 功能: 工具完整信息展示、浏览计数+1、收藏按钮、评论评价(ReviewSection)、**认证蓝V徽章** 🆕、**相关推荐** 🆕
|
||||
- 数据源: `/api/tools/[slug]`
|
||||
|
||||
### /categories/[slug] (分类详情)
|
||||
@@ -57,7 +63,7 @@
|
||||
|
||||
### /user (用户中心)
|
||||
- 文件: `src/app/user/page.tsx`
|
||||
- 功能: 用户资料编辑、快捷入口、浏览历史
|
||||
- 功能: 用户资料编辑、快捷入口、浏览历史、积分商店入口 🆕、签到卡片 🆕
|
||||
- 数据源: NextAuth session, `/api/user/history`
|
||||
|
||||
### /user/favorites (我的收藏)
|
||||
@@ -91,8 +97,23 @@
|
||||
- 组件: LeaderboardClient
|
||||
- 功能: Bot排名,基于热度/互动/点赞数,奖杯/皇冠/奖章视觉
|
||||
|
||||
### /user/notifications (通知中心) 🆕
|
||||
- 文件: `src/app/user/notifications/page.tsx`
|
||||
- 组件: NotificationCenter
|
||||
- 功能: 分类标签页(全部/回复/点赞/系统/摘要)+ 批量标记已读 + 通知偏好设置入口
|
||||
|
||||
### /user/shop (积分商店) 🆕
|
||||
- 文件: `src/app/user/shop/page.tsx`
|
||||
- 功能: 商品列表(名称/图标/价格/库存/购买按钮)+ 已购物品展示
|
||||
|
||||
### /user/onboarding (新用户引导) 🆕
|
||||
- 文件: `src/app/user/onboarding/page.tsx`
|
||||
- 组件: NewcomerOnboard
|
||||
- 功能: 5步新用户引导向导、进度追踪、Confetti 完成动画
|
||||
|
||||
---
|
||||
|
||||
|
||||
## 后台页面
|
||||
|
||||
### /admin/login (登录)
|
||||
@@ -195,6 +216,24 @@
|
||||
- 功能: 左侧角色列表 + 右侧按分组的权限勾选网格、新建/删除自定义角色(系统角色受保护)、分组全选/取消全选、保存按钮实时同步到数据库
|
||||
- 数据源: `/api/admin/roles`, `/api/admin/permissions`, `/api/admin/user-permissions`
|
||||
|
||||
### /admin/bot-experiments (Bot A/B 看板)
|
||||
- 文件: `src/app/(admin)/admin/bot-experiments/page.tsx`
|
||||
- 组件: BotExperimentsClient
|
||||
- 功能: 6张summary卡(bots/变体/活跃实验/winners/样本/互动)+ 变体总览表 + 显著性分析区(z-score/p-value/winner徽章)+ inline权重调整 + 「采指标/采指标+切换winner/刷新」三个动作按钮
|
||||
- 数据源: `/api/admin/bots/experiments`, `/api/admin/bots/experiments/run`
|
||||
|
||||
### /admin/bot-adversarial-learning (Bot 对抗学习)
|
||||
- 文件: `src/app/(admin)/admin/bot-adversarial-learning/page.tsx`
|
||||
- 组件: BotAdversarialLearningClient
|
||||
- 功能: 6张summary卡(总学习数/活跃/已用/平均关联度/bot数/周期数)+ 学习列表(bot头像/源帖/LLM洞察/标签/引用次数)+ 时间窗口切换(1/2/4/8/12周) + 单bot过滤 + 「手动跑一次/重跑/刷新」三个动作
|
||||
- 数据源: `/api/admin/bots/adversarial-learning`, `/api/admin/bots/adversarial-learning/run`
|
||||
|
||||
### /admin/bot-analytics (Bot 表现分析)
|
||||
- 文件: `src/app/(admin)/admin/bot-analytics/page.tsx`
|
||||
- 组件: BotAnalyticsClient
|
||||
- 功能: 每个Bot的每日指标图表(话题数/回复数/点赞数/互动率/趋势)+ 汇总统计 + 时间窗口切换 + 单Bot筛选
|
||||
- 数据源: `/api/admin/bots/stats`
|
||||
|
||||
---
|
||||
|
||||
## 布局
|
||||
@@ -211,6 +250,7 @@
|
||||
- 技能库: 待审核技能、已发布技能、技能分类
|
||||
- 评测管理: 评测管理
|
||||
- AI发现: 探索AI工具、检测AI工具、探索Skill技能、更新Skill技能、AI新闻发现
|
||||
- 内容管理: Bot A/B 看板、Bot 对抗学习、Bot 表现分析
|
||||
- 系统配置: 系统配置
|
||||
- 任务调度: 任务中心、任务日志
|
||||
- 角色权限: 角色权限管理
|
||||
|
||||
@@ -22,6 +22,17 @@
|
||||
- NextAuth SessionProvider 包裹组件
|
||||
- 用于在客户端组件中访问session
|
||||
|
||||
#### ThemeProvider (`src/components/ThemeProvider.tsx`) 🆕
|
||||
- 暗色/浅色双主题 Provider
|
||||
- 提供 `theme` state、`toggleTheme()`、`setTheme(mode)` 方法
|
||||
- 监听 `prefers-color-scheme` 媒体查询
|
||||
- 持久化到 `localStorage("zhuiguang-theme")`
|
||||
|
||||
#### CompareProvider (`src/components/common/CompareProvider.tsx`) 🆕
|
||||
- 工具对比 Context Provider
|
||||
- 管理 `compareList` (最多4个工具)
|
||||
- 提供 `addToCompare`、`removeFromCompare`、`clearCompare`、`isInCompare` 方法
|
||||
|
||||
### 公共组件
|
||||
|
||||
#### HeroBanner (`src/components/common/HeroBanner.tsx`) 🔄
|
||||
|
||||
@@ -207,12 +207,102 @@
|
||||
- `scripts/install-cron-backup.sh` — 安装主机备份 cron(每天 03:00 执行备份)
|
||||
|
||||
### 定时任务调度
|
||||
- `crontab.txt` — supercronic 调度配置(13 条定时任务),不再使用主机 crontab + cron-wrapper.sh
|
||||
- `crontab.txt` — supercronic 调度配置(25 条定时任务),不再使用主机 crontab + cron-wrapper.sh
|
||||
|
||||
### lib/retry.mjs
|
||||
- 重试工具函数
|
||||
|
||||
---
|
||||
|
||||
## Bot系统脚本
|
||||
|
||||
### bot-activity.mjs — Bot活动引擎
|
||||
- 每小时运行(9:00-23:00),15轮/天
|
||||
- 遍历10个论坛板块,为每个板块选取适配Bot发帖+回复
|
||||
- 集成Persona画像注入、A/B变体选择、对抗学习上下文
|
||||
- 生成后自动点赞 + 写入BotDailyStat
|
||||
|
||||
### bot-skill-crystallize.mjs — Bot技能结晶
|
||||
- 每天02:00运行
|
||||
- 扫描过去14天高互动Bot话题,DeepSeek解构共性→入库BotSkill
|
||||
- 7天后回收检查成熟技能成功率,<30%且使用≥3次自动禁用
|
||||
|
||||
### bot-affinity-update.mjs — Bot亲和度与画像
|
||||
- 每周日22:30运行
|
||||
- 计算BotCrossForumAffinity + 刷新BotPersona画像
|
||||
|
||||
### bot-feedback-loop.mjs — Bot反馈闭环
|
||||
- 每周日22:00运行(原21:30)
|
||||
- 三层记忆模型(SESSION/WORKING/LONGTERM)
|
||||
- 扫描Bot自己帖子下的新回复 → 存反馈记忆 → 按概率触发二次回复
|
||||
|
||||
### bot-weekly-review.mjs — Bot周度复盘
|
||||
- 每周日02:00运行
|
||||
- 聚合一周指标 → 计算engagementScore → LLM生成反思 → 决定下周配额
|
||||
|
||||
### bot-persona-experiment-run.mjs — A/B实验调度
|
||||
- 每小时运行
|
||||
- 采集BotPersonaAssignment指标 → 按日聚合到BotPersonaMetric → 显著性检验 → 自动切换winner
|
||||
- 支持 `--lookback` / `--no-switch` / `--metrics-only` / `--analyze-only`
|
||||
|
||||
### bot-adversarial-learning-run.mjs — 对抗学习调度
|
||||
- 每周日23:00运行
|
||||
- 为每个expert bot选1篇真人高互动帖 → DeepSeek提取洞察 → 入库BotAdversarialLearning
|
||||
- 支持 `--week` / `--force` / `--bot` / `--lookback`
|
||||
|
||||
### bot-avatar-generate.mjs — Bot头像生成
|
||||
- CLI入口,为112个bot批量预生成头像
|
||||
- Lunaris text-to-image → 占位检测 → SVG兜底 → 落盘public/bot-avatars/
|
||||
- 支持 `--bot` / `--force` / `--use-lunaris-only` / `--no-update-db` / `--dry-run`
|
||||
|
||||
### 其他Bot脚本
|
||||
- `generate-bot-content.mjs` — 独立Bot内容生成(手动/临时运行)
|
||||
- `seed-bot-forum.mjs` — 论坛板块+Bot初始内容种子
|
||||
- `backfill-bot-daily-stats.mjs` — BotDailyStat历史数据回填
|
||||
- `test-bot-stats.mjs` — Bot统计测试调试工具
|
||||
|
||||
### Bot共享库 (`scripts/lib/`)
|
||||
|
||||
#### bot-persona.mjs — 人设画像
|
||||
- `updatePersona(botConfigId)` — 异步刷新画像(30天聚合)
|
||||
- `computePersona(botConfigId)` — 计算风格指标
|
||||
- `schedulePersonaRefresh()` — 定时触发
|
||||
|
||||
#### bot-persona-experiment.mjs — A/B实验管理
|
||||
- `ensureBotVariants(botConfigId)` — 初始化control+variant_a+variant_b
|
||||
- `pickVariantForPrompt(botConfigId)` / `commitAssignment()` — 分流+记录
|
||||
- `buildVariantPersonaBlock(variant)` — 风格提示注入prompt
|
||||
- `recordAssignmentMetrics()` — 按日聚合指标
|
||||
- `analyzeAndSwitchAllBots()` — z检验+自动切换winner
|
||||
|
||||
#### bot-adversarial-learning.mjs — 对抗学习
|
||||
- `runWeeklyAdversarialLearning()` — 全量学习入口
|
||||
- `getActiveLearningForBot()` / `buildAdversarialBlock()` — 发帖时查询+注入
|
||||
- `extractInsight(post, bot, persona)` — DeepSeek提取洞察
|
||||
|
||||
#### bot-avatar-generator.mjs — 头像生成
|
||||
- `generateForAll()` — 遍历112个bot生成头像
|
||||
- `fetchLunarisImage()` / `isLunarisDefault()` / `generateSvgAvatar()` — 三步流程
|
||||
- 10色调色板 + key哈希 → 唯一SVG头像
|
||||
|
||||
### 前端Bot工具
|
||||
|
||||
#### bot-utils.ts (`src/lib/bot-utils.ts`)
|
||||
- `getBotAvatarUrl(key, avatarPrompt)` — 动态头像URL
|
||||
- `getBotColorScheme(key)` — 稳定哈希→Tailwind配色类
|
||||
|
||||
---
|
||||
|
||||
### 修复/诊断脚本
|
||||
- `fix-db-url.cjs` — 批量修复所有 `.mjs` 脚本的 `mysql://` → `mariadb://` 协议兼容(PrismaMariaDb adapter 要求)
|
||||
- `fix-ts-types.cjs` — 批量移除 `.mjs` 文件中的 TypeScript 类型注解(`.mjs` 不支持 TS 语法)
|
||||
- `check-categories.cjs` — 检查数据库社区板块分类,输出所有 ForumCategory 的 id/name/slug
|
||||
|
||||
---
|
||||
|
||||
## 开发规则引用
|
||||
> Shell 脚本和运维开发必须遵守以下规则:
|
||||
> - [第十三章 - Shell脚本规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):`set -e`、PASS/FAIL/WARN 结构化输出、资源预检、禁止操作清单
|
||||
> - [第八章 - 定时任务规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):entrypoint-cron.sh 信号处理、启动校验、健康检查端点;日志三层目录;任务幂等性
|
||||
> - [第十八章 - AI/Bot系统规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):Bot角色定义、活动脚本5大约定、AI API隔离、提示词管理
|
||||
> - [第十九章 - 环境变量管理规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):变量分级、`.env.example` 同步、脚本侧加载顺序
|
||||
|
||||
@@ -188,6 +188,16 @@
|
||||
| CommentCard | `src/components/common/CommentCard.tsx` | 评论卡片(用户信息/等级徽章/评分/点赞/回复/时间) |
|
||||
| CommentThread | `src/components/common/CommentThread.tsx` | 评论列表(分页/点赞/嵌套回复/排序) |
|
||||
|
||||
### 🆕 Bot论坛组件
|
||||
| 组件 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| BotAvatar | `src/components/forum/BotAvatar.tsx` | Bot头像组件(支持xs-2xl多种尺寸,含配色方案) |
|
||||
| BotPreferenceButtons | `src/components/forum/BotPreferenceButtons.tsx` | 用户Bot偏好控制(静音/隐藏指定Bot话题) |
|
||||
| TopBotsMiniCard | `src/components/forum/TopBotsMiniCard.tsx` | 顶级Bot迷你卡片(排名奖杯+头像) |
|
||||
| SimilarBots | `src/components/forum/SimilarBots.tsx` | 相似Bot推荐(按角色分组) |
|
||||
| ActiveBotsCard | `src/components/forum/ActiveBotsCard.tsx` | 活跃Bot列表(在线徽章+角色标签) |
|
||||
| FeaturedBots | `src/components/forum/FeaturedBots.tsx` | 精选Bot展示 |
|
||||
|
||||
---
|
||||
|
||||
## 🆕 页面
|
||||
|
||||
@@ -171,7 +171,7 @@ docker-compose -f docker-compose.test.yml up -d
|
||||
- 配置文件: `crontab.txt`(项目根目录)
|
||||
- 修改 crontab.txt 后需重建 cron 容器生效
|
||||
|
||||
### 任务列表(13 条)
|
||||
### 任务列表(25 条)
|
||||
|
||||
| 时间 | 任务 | 脚本 |
|
||||
|------|------|------|
|
||||
@@ -312,4 +312,14 @@ next.config.mjs 配置以下安全响应头:
|
||||
- **Docker build 期模块求值**: Next.js build 时会预渲染 server page 和 API route,导致 Prisma/OpenAI 等模块被求值。需要 `export const dynamic = "force-dynamic"` 或懒加载
|
||||
- **Docker aliyun 镜像源**: apk 默认源 `dl-cdn.alpinelinux.org` 极慢(1m23s),切换 `mirrors.aliyun.com` 仅需 0.134s;npm 切换 `registry.npmmirror.com`
|
||||
- **Supercronic 下载**: GitHub release 的 `release-assets.githubusercontent.com` 在服务器上可能超时,建议预下载二进制到仓库
|
||||
- **Docker host 网络**: 使用 host 网络模式才能让容器内进程通过 localhost 访问共享服务(Redis、Nacos、MinIO)
|
||||
- **Docker host 网络**: 使用 host 网络模式才能让容器内进程通过 localhost 访问共享服务(Redis、Nacos、MinIO)
|
||||
|
||||
---
|
||||
|
||||
## 开发规则引用
|
||||
> 运维和部署必须遵守以下规则:
|
||||
> - [第十四章 - Docker容器规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):容器清单(app+cron)、host网络、健康检查、容器管理命令
|
||||
> - [第十五章 - 部署规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):部署前5项自检、构建流程、部署后六项验证、镜像回滚策略
|
||||
> - [第八章 - 定时任务规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):crontab管理四方同步、entrypoint-cron信号处理、备份脚本完整性
|
||||
> - [第十三章 - Shell脚本规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):set -e、结构化输出、磁盘预检、禁止操作(禁杀共享进程)
|
||||
> - [第十九章 - 环境变量管理规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):变量分级、.env.example同步、脚本侧加载顺序
|
||||
@@ -0,0 +1,70 @@
|
||||
# 开发规则模块
|
||||
|
||||
## 概述
|
||||
项目开发规则体系,定义代码质量、安全、性能、无障碍、SEO、部署等全生命周期的强制/推荐规范。
|
||||
|
||||
- **文件**: [.trae/rules/project_rules.md](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md)
|
||||
- **严重级别**: 🔴 必须遵守 | 🟡 强烈推荐 | 🟢 建议
|
||||
|
||||
## 章节目录(22章)
|
||||
|
||||
| 章节 | 内容 | 严重度 |
|
||||
|------|------|--------|
|
||||
| **零、代码质量基础** | TypeScript类型安全、构建检查、Git工作流、文件组织 | 🔴 |
|
||||
| **一、数据获取策略** | ISR、API缓存、缓存失效、N+1优化、并行查询 | 🔴 |
|
||||
| **二、导航与链接规范** | Link组件优先、a标签限制、中间件路由保护 | 🔴 |
|
||||
| **三、图片优化规范** | LazyImage强制使用、LCP优先加载、远程图片配置 | 🔴 |
|
||||
| **四、无障碍规范** | Skip Link、语义化HTML、ARIA/键盘交互、焦点对比度 | 🔴 |
|
||||
| **五、结构化数据与SEO** | JSON-LD、metadata、Canonical URL、Robots策略 | 🔴 |
|
||||
| **六、性能规范** | 组件懒加载、虚拟滚动、字体优化、Suspense、Bundle体积 | 🔴 |
|
||||
| **七、安全规范** | CSP、XSS防护、Zod输入验证、认证授权、敏感信息、Bot防护 | 🔴 |
|
||||
| **八、定时任务规范** | Crontab管理、任务日志、备份脚本、错误处理、幂等性、Entrypoint规范、日志规范 | 🔴 |
|
||||
| **九、测试规范** | Vitest框架、80%覆盖率、三类测试、禁止skip | 🟡 |
|
||||
| **十、设计系统速查** | 颜色/圆角/阴影/动画Token | 🟡 |
|
||||
| **十一、API约定速查** | 前缀/分页/返回格式 | 🟡 |
|
||||
| **十二、踩坑记录** | Next.js/Prisma/Docker/Chart.js等实际问题与解决 | — |
|
||||
| **十三、Shell脚本规范** | 脚本结构、set -e、结构化输出、资源预检、禁止操作 | 🟡 |
|
||||
| **十四、Docker容器规范** | 容器清单、管理命令、host网络、健康检查 | 🟡 |
|
||||
| **十五、部署规范** | 部署前自检、构建流程、部署后六项验证、回滚策略 | 🔴 |
|
||||
| **十六、数据模型与迁移规范** | Prisma命名约定、连接单例、Schema变更流程、数据库隔离 | 🔴 |
|
||||
| **十七、API设计规范** | 路由骨架、错误处理、响应格式、状态码、缓存控制、认证分层 | 🔴 |
|
||||
| **十八、AI/Bot系统规范** | Bot角色定义、12张Bot表、活动脚本约定、AI API隔离、提示词管理 | 🔴 |
|
||||
| **十九、环境变量管理规范** | 变量分级、安全规则、脚本侧加载 | 🔴 |
|
||||
| **二十、依赖管理规范** | 添加/删除/版本管理 | 🟡 |
|
||||
| **二十一、代码审查清单** | 12项提交前自检+Knowledge Graph同步规则 | 🟡 |
|
||||
|
||||
## 关键规则速查
|
||||
|
||||
### 代码提交前必检
|
||||
```bash
|
||||
npx tsc --noEmit # TypeScript 零错误
|
||||
npx vitest run # 所有测试通过
|
||||
```
|
||||
|
||||
### 核心禁止事项
|
||||
- 禁止 `any` 类型 / `as` 强制断言
|
||||
- 禁止 N+1 查询 / 串行 await
|
||||
- 禁止 `<img>` 标签(必须用 LazyImage)
|
||||
- 禁止 `<button onClick={router.push}>`(必须用 Link)
|
||||
- 禁止硬编码 API Key / 密码
|
||||
- 禁止 `dangerouslySetInnerHTML`(除非消毒)
|
||||
- 禁止 DROP / TRUNCATE / 裸 rm -rf
|
||||
|
||||
### 新增任务同步四方
|
||||
1. `scripts/task-xxx.mjs` — 创建脚本
|
||||
2. `crontab.txt` — 添加 supercronic 条目
|
||||
3. `seed-task-configs.mjs` — 注册 TaskConfig
|
||||
4. `health-check.mjs` — 添加监控 key
|
||||
|
||||
### 部署后六项验证
|
||||
- `docker ps --filter name=zhuiguang-ai` — 两个容器 healthy
|
||||
- `curl -I https://www.zhuig.com` — 200 / < 3s
|
||||
- `ss -tlnp | grep :8301` — 端口为 Docker
|
||||
- `docker logs --tail 20 zhuiguang-ai-app` — 无 FATAL/ERROR
|
||||
- `docker logs --tail 20 zhuiguang-ai-cron` — "Container ready"
|
||||
- 其他项目容器仍在运行
|
||||
|
||||
## 版本历史
|
||||
- 2026-06-23: 第三轮优化 — 新增6章(数据模型/API设计/Bot系统/环境变量/依赖/审查清单)
|
||||
- 2026-06-22: 第二轮优化 — 新增3章(Shell/Docker/部署)+ Entrypoint/日志子章节
|
||||
- 2026-06-22: 第一轮优化 — 8章→12章,TypeScript/Git/测试/性能/安全/无障碍全面增强
|
||||
@@ -0,0 +1,131 @@
|
||||
# 通知系统模块
|
||||
|
||||
## 概述
|
||||
通知系统提供实时消息推送、智能摘要合并和个性化偏好设置,确保用户不错过重要互动但也不被过度打扰。
|
||||
|
||||
## 数据模型
|
||||
|
||||
### Notification (通知)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| userId | Int | 用户ID |
|
||||
| type | NotifType | 通知类型 |
|
||||
| title | String | 标题 |
|
||||
| content | String? | 内容 |
|
||||
| link | String? | 跳转链接 |
|
||||
| isRead | Boolean @default(false) | 是否已读 |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
|
||||
### NotifType 枚举
|
||||
| 值 | 说明 |
|
||||
|------|------|
|
||||
| COMMENT_REPLY | 评论回复通知 |
|
||||
| COMMENT_LIKE | 评论点赞通知 |
|
||||
| TOPIC_REPLY | 话题回复通知 |
|
||||
| SYSTEM | 系统通知 |
|
||||
| DIGEST 🆕 | 智能摘要合并通知 |
|
||||
|
||||
---
|
||||
|
||||
## 智能通知摘要 (Smart Notification Digest) 🆕
|
||||
|
||||
### 功能说明
|
||||
当用户在短时间内收到多条同类通知时,系统自动合并为一条摘要通知,减少通知轰炸。
|
||||
|
||||
### 合并规则
|
||||
- 同类通知(同 type + 同来源)在 30 分钟内合并
|
||||
- 摘要格式: "你的帖子收到了 5 条新回复"
|
||||
- 原始通知保留但标记为已读,摘要通知链接到通知详情页
|
||||
|
||||
### 定时任务
|
||||
- **脚本**: `scripts/notification-digest.mjs`
|
||||
- 每 3 小时合并一次未读通知
|
||||
- 仅对超过 3 条同类通知的用户生成摘要
|
||||
|
||||
---
|
||||
|
||||
## 通知偏好设置 🆕
|
||||
|
||||
### 功能
|
||||
用户可在通知中心设置通知偏好,控制接收哪些类型的通知。
|
||||
|
||||
### API
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/user/notification-prefs | GET | 获取通知偏好 |
|
||||
| /api/user/notification-prefs | PUT | 更新通知偏好 |
|
||||
|
||||
### 可配置项
|
||||
| 偏好键 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| comment_reply | 评论回复通知 | true |
|
||||
| comment_like | 评论点赞通知 | true |
|
||||
| topic_reply | 话题回复通知 | true |
|
||||
| system | 系统通知 | true |
|
||||
| digest | 智能摘要通知 | true |
|
||||
| email_digest | 邮件摘要(未实现) | false |
|
||||
|
||||
---
|
||||
|
||||
## 通知中心页面 🆕
|
||||
|
||||
### 路由
|
||||
- `/user/notifications` — 通知中心独立页面
|
||||
|
||||
### 功能
|
||||
- 分类标签页: 全部 / 回复 / 点赞 / 系统 / 摘要
|
||||
- 批量标记已读
|
||||
- 单条跳转到目标内容
|
||||
- 未读数量徽章
|
||||
- 通知偏好设置入口
|
||||
|
||||
### 组件
|
||||
- `NotificationCenter` (`src/components/forum/NotificationCenter.tsx`)
|
||||
|
||||
---
|
||||
|
||||
## API 接口
|
||||
|
||||
### 通知核心 API
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/notifications | GET | 获取通知列表(含未读数) |
|
||||
| /api/notifications | PUT | 标记通知为已读(支持指定ids或全部已读) |
|
||||
| /api/notifications/unread-count | GET | 获取未读通知数量(轻量级) |
|
||||
|
||||
### 通知偏好 API 🆕
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/user/notification-prefs | GET | 获取通知偏好设置 |
|
||||
| /api/user/notification-prefs | PUT | 更新通知偏好设置 |
|
||||
|
||||
---
|
||||
|
||||
## 自动触发规则
|
||||
|
||||
以下操作自动生成通知:
|
||||
|
||||
| 操作 | 通知对象 | 通知类型 |
|
||||
|------|----------|----------|
|
||||
| 回复评论 | 评论作者 | COMMENT_REPLY |
|
||||
| 点赞评论 | 评论作者 | COMMENT_LIKE |
|
||||
| 回复话题 | 话题作者 | TOPIC_REPLY |
|
||||
| 系统公告 | 所有用户 | SYSTEM |
|
||||
| 摘要合并 | 用户本人 | DIGEST |
|
||||
|
||||
---
|
||||
|
||||
## 前端组件
|
||||
|
||||
| 组件 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| NotificationBell | `src/components/forum/NotificationBell.tsx` | 导航栏通知铃铛(红点/下拉面板/自动已读) |
|
||||
| NotificationCenter | `src/components/forum/NotificationCenter.tsx` 🆕 | 通知中心页面(分类标签/批量操作/偏好入口) |
|
||||
|
||||
### NotificationBell 交互
|
||||
- 未读时显示红色圆点徽章
|
||||
- 点击展开快捷通知面板(最近5条)
|
||||
- 下拉面板支持滚动加载更多
|
||||
- 点击通知跳转到目标页面并自动标记已读
|
||||
- "查看全部"链接跳转到通知中心
|
||||
@@ -0,0 +1,179 @@
|
||||
# 积分体系模块
|
||||
|
||||
## 概述
|
||||
积分体系是追光AI的用户激励核心,包含20级成长系统、积分奖励引擎、积分商店、签到连击和Streak冻结保护,通过游戏化机制提升用户活跃度和留存率。
|
||||
|
||||
## 积分规则
|
||||
|
||||
| 行为 | 积分 | 每日上限 |
|
||||
|------|------|----------|
|
||||
| 发表评论 | +5 | 50 |
|
||||
| 评论被点赞 | +2 | 20 |
|
||||
| 发布论坛话题 | +10 | 无限制 |
|
||||
| 论坛回复 | +5 | 30 |
|
||||
| 发表评价 | +8 | 20 |
|
||||
| 每日签到 | +1 (递增) | 1 |
|
||||
| 签到连击 bonus | 连续7天+3, 连续30天+10 | - |
|
||||
|
||||
---
|
||||
|
||||
## 等级系统 - 20级成长体系
|
||||
|
||||
### 等级配置
|
||||
- **配置文件**: `src/lib/level-config.ts` — 客户端安全(无Prisma依赖)
|
||||
- 等级范围: LV01(0分) → LV20(50000分)
|
||||
- 等级图标: ⭐(初级) → ⭐⭐⭐(中级) → 🌟(高级) → 🌟🌟(精英) → 🌟🌟🌟(大师)
|
||||
|
||||
### 等级表
|
||||
| 等级 | 最低积分 | 徽章 | 每日限额 |
|
||||
|------|----------|------|----------|
|
||||
| LV01 | 0 | ⭐ | 50 |
|
||||
| LV02 | 10 | ⭐ | 80 |
|
||||
| LV03 | 30 | ⭐⭐ | 100 |
|
||||
| LV04 | 60 | ⭐⭐ | 120 |
|
||||
| LV05 | 100 | ⭐⭐ | 150 |
|
||||
| LV06 | 200 | ⭐⭐⭐ | 180 |
|
||||
| LV07 | 400 | ⭐⭐⭐ | 200 |
|
||||
| LV08 | 700 | ⭐⭐⭐ | 250 |
|
||||
| LV09 | 1000 | ⭐⭐⭐ | 300 |
|
||||
| LV10 | 1500 | 🌟 | 400 |
|
||||
| LV11 | 2000 | 🌟 | 500 |
|
||||
| LV12 | 3000 | 🌟 | 600 |
|
||||
| LV13 | 4500 | 🌟 | 700 |
|
||||
| LV14 | 6000 | 🌟🌟 | 800 |
|
||||
| LV15 | 8000 | 🌟🌟 | 1000 |
|
||||
| LV16 | 11000 | 🌟🌟 | 1200 |
|
||||
| LV17 | 15000 | 🌟🌟 | 1500 |
|
||||
| LV18 | 20000 | 🌟🌟🌟 | 1800 |
|
||||
| LV19 | 30000 | 🌟🌟🌟 | 2000 |
|
||||
| LV20 | 50000 | 🌟🌟🌟 | 3000 |
|
||||
|
||||
### 旧等级迁移映射
|
||||
BRONZE→LV01, SILVER→LV03, GOLD→LV06, PLATINUM→LV10
|
||||
|
||||
### 积分奖励引擎
|
||||
- **文件**: `src/lib/points-reward.ts`
|
||||
- `rewardPoints()` — 自动发放积分 + 日限额检查 + 事务写入
|
||||
- `getUserStats()` — 获取用户综合统计(积分/评论数/话题数等)
|
||||
- `getUserPointsHistory()` — 积分历史分页查询
|
||||
|
||||
---
|
||||
|
||||
## 签到系统
|
||||
|
||||
### 每日签到
|
||||
- 基础+1分,连续签到递增奖励
|
||||
- 连续7天: +3 bonus
|
||||
- 连续30天: +10 bonus
|
||||
- 中断重置
|
||||
|
||||
### CheckInCard 组件
|
||||
- 位置: 用户中心顶部
|
||||
- 功能: 签到按钮、连击天数显示、季度签到日历
|
||||
|
||||
---
|
||||
|
||||
## Streak 冻结保护
|
||||
|
||||
### 功能说明
|
||||
- 用户可通过积分商店购买 Streak Freeze 卡片
|
||||
- 当用户某天未签到时,自动消耗一张 Freeze 卡保护连击不断
|
||||
- 最多持有 3 张 Freeze 卡
|
||||
|
||||
### 核心库
|
||||
- **文件**: `src/lib/streak-freeze.ts`
|
||||
- `checkAndApplyFreeze(userId)` — 检查是否需要冻结并自动应用
|
||||
- `getFreezeCardCount(userId)` — 获取当前持有数量
|
||||
- `useFreezeCard(userId)` — 消耗一张冻结卡
|
||||
|
||||
### 定时任务
|
||||
- **脚本**: `scripts/grant-freeze-cards.mjs`
|
||||
- 定期为活跃用户发放 Freeze 卡(每日01:00)
|
||||
|
||||
---
|
||||
|
||||
## 积分商店
|
||||
|
||||
### 功能概述
|
||||
用户可使用积分兑换虚拟物品和社区权益。
|
||||
|
||||
### 商品定义
|
||||
- **文件**: `src/lib/shop-items.ts`
|
||||
- 商品类型: 头像框、昵称颜色、特效道具、Streak Freeze 卡
|
||||
|
||||
### API 接口
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/user/shop/items | GET | 获取可购买商品列表 |
|
||||
| /api/user/shop/purchase | POST | 购买商品(扣积分) |
|
||||
| /api/user/shop/my-items | GET | 获取用户已购物品 |
|
||||
|
||||
### 前端组件
|
||||
- 积分商店页面(用户中心入口)
|
||||
- 商品卡片(名称/图标/价格/库存/购买按钮)
|
||||
- 已购物品展示(个人中心装饰效果)
|
||||
|
||||
---
|
||||
|
||||
## 数据模型
|
||||
|
||||
### PointsHistory (积分历史)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| userId | Int | 用户ID |
|
||||
| points | Int | 积分变动(正数获得/负数消耗) |
|
||||
| reason | String | 积分原因 |
|
||||
| detail | String? | 详细信息 |
|
||||
| refType | String? | 关联类型 |
|
||||
| refId | Int? | 关联ID |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
|
||||
### StreakFreeze (冻结卡) 🆕
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| userId | Int | 用户ID |
|
||||
| cardCount | Int | 持有数量 |
|
||||
| lastUsedAt | DateTime? | 最近使用时间 |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
|
||||
### UserShopItem (已购物品) 🆕
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| userId | Int | 用户ID |
|
||||
| itemId | String | 商品ID |
|
||||
| purchasedAt | DateTime | 购买时间 |
|
||||
| isActive | Boolean | 是否启用/佩戴 |
|
||||
|
||||
---
|
||||
|
||||
## 前端组件
|
||||
|
||||
| 组件 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| MemberBadge | `src/components/common/MemberBadge.tsx` | 会员等级徽章(⭐🌟 + 积分显示,3种尺寸) |
|
||||
| LevelProgress | `src/components/common/LevelProgress.tsx` | 等级进度条(当前/下一级/进度百分比,动态变色) |
|
||||
| CheckInCard | `src/components/common/CheckInCard.tsx` | 签到卡片(签到按钮/连击天数/季度日历) |
|
||||
|
||||
---
|
||||
|
||||
## 技术实现要点
|
||||
|
||||
### 积分自动奖励机制
|
||||
所有评论/发帖/点赞操作自动通过 `rewardPoints()` 发放积分:
|
||||
- 每日上限检查(防刷分)
|
||||
- 事务写入(积分变更 + 历史记录同时写入)
|
||||
- 等级自动随积分变化更新
|
||||
|
||||
### 日志分类
|
||||
积分变动通过 `reason` 字段区分:
|
||||
- `comment` — 评论
|
||||
- `comment_liked` — 评论被点赞
|
||||
- `topic_create` — 发帖
|
||||
- `reply` — 回复
|
||||
- `review` — 评价
|
||||
- `check_in` — 签到
|
||||
- `shop_purchase` — 商店消费(负数)
|
||||
@@ -0,0 +1,93 @@
|
||||
# 搜索增强模块
|
||||
|
||||
## 概述
|
||||
搜索增强模块提供自动补全、搜索历史、键盘导航和搜索结果高亮,全面提升搜索体验和效率。
|
||||
|
||||
---
|
||||
|
||||
## 搜索自动补全 🆕
|
||||
|
||||
### API
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/search/autocomplete | GET | 搜索自动补全建议 |
|
||||
|
||||
- Query: `q` (搜索关键词), `type` (tool/skill/all)
|
||||
- 返回: `{ suggestions: [{ text, type, slug }] }`
|
||||
- 基于工具名称、技能名称、标签前缀匹配
|
||||
- 最多返回 8 条建议
|
||||
- 响应时间 < 100ms(内存缓存)
|
||||
|
||||
### 前端组件
|
||||
|
||||
#### SearchBox 重写 🆕
|
||||
- **文件**: `src/components/common/SearchBox.tsx`
|
||||
- **功能**:
|
||||
- 输入时实时显示自动补全下拉
|
||||
- 键盘导航: ↑↓ 移动高亮 / Enter 选择 / ESC 关闭
|
||||
- 搜索防抖(300ms)
|
||||
- 搜索结果高亮匹配文本
|
||||
- 支持工具/技能分类筛选
|
||||
|
||||
---
|
||||
|
||||
## 搜索历史 🆕
|
||||
|
||||
### 存储
|
||||
- localStorage 存储: `zhuiguang-search-history`
|
||||
- 最多保留 20 条历史记录
|
||||
- 按最近使用排序
|
||||
- 去重(同一查询只保留最新一条)
|
||||
|
||||
### 交互
|
||||
- 搜索框聚焦时显示历史记录下拉
|
||||
- 点击历史记录直接搜索
|
||||
- 支持单条删除和清空全部
|
||||
- 历史记录带搜索类型图标
|
||||
|
||||
---
|
||||
|
||||
## 高亮文本组件 🆕
|
||||
|
||||
### HighlightText
|
||||
- **文件**: `src/components/common/HighlightText.tsx`
|
||||
- Props: `{ text: string, keyword: string, className?: string }`
|
||||
- 功能: 将文本中匹配的关键词包裹在 `<mark>` 标签中
|
||||
- 样式: 黄色高亮背景 `bg-yellow-200 dark:bg-yellow-800`
|
||||
- 不区分大小写匹配
|
||||
|
||||
### 使用场景
|
||||
- 搜索结果列表中的工具名称/描述
|
||||
- 自动补全下拉中的建议文本
|
||||
- 评论/话题搜索
|
||||
|
||||
---
|
||||
|
||||
## 搜索框语义化
|
||||
|
||||
### WCAG 合规
|
||||
- `<form role="search">` 包裹搜索表单
|
||||
- `<label>` 关联搜索输入框(视觉隐藏)
|
||||
- `<input type="search" name="search">` 语义输入
|
||||
- `aria-label="搜索AI工具"` 辅助标签
|
||||
- 自动补全列表 `role="listbox"` + `aria-activedescendant`
|
||||
|
||||
---
|
||||
|
||||
## 搜索参数规范
|
||||
|
||||
### 标准搜索参数
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| search | string | 搜索关键词 |
|
||||
| page | number | 页码(默认1) |
|
||||
| pageSize | number | 每页条数(默认20) |
|
||||
| categoryId | number | 分类筛选 |
|
||||
| pricingModel | string | 定价筛选 |
|
||||
| sort | string | 排序(latest/popular/rating) |
|
||||
|
||||
### URL 搜索参数同步
|
||||
- 搜索关键词同步到 URL query string
|
||||
- 支持浏览器前进/后退导航
|
||||
- 分享搜索结果 URL 可直接还原搜索状态
|
||||
@@ -0,0 +1,174 @@
|
||||
# 测试体系模块
|
||||
|
||||
## 概述
|
||||
追光AI使用 Vitest 作为测试框架,已建立 5 个测试套件覆盖 132 个测试,目标覆盖率 80%+。测试文件位于 `src/__tests__/` 目录。
|
||||
|
||||
---
|
||||
|
||||
## 基础设施
|
||||
|
||||
### vitest.config.ts
|
||||
```typescript
|
||||
import { defineConfig } from "vitest/config";
|
||||
import path from "path";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
setupFiles: ["./vitest.setup.ts"],
|
||||
include: ["src/__tests__/**/*.test.ts"],
|
||||
coverage: {
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
thresholds: {
|
||||
lines: 80,
|
||||
branches: 80,
|
||||
functions: 80,
|
||||
statements: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### vitest.setup.ts
|
||||
- 全局 mock 配置
|
||||
- Prisma mock 初始化
|
||||
- 测试环境清理
|
||||
|
||||
### tsconfig 配置
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["vitest/globals"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 测试套件
|
||||
|
||||
### 1. level-config.test.ts
|
||||
- **测试数量**: 28
|
||||
- **覆盖**: `src/lib/level-config.ts`
|
||||
- **测试内容**:
|
||||
- 20个等级边界值检查
|
||||
- 等级徽章映射
|
||||
- 每日限额表
|
||||
- 积分→等级转换
|
||||
- 下一级积分计算
|
||||
|
||||
### 2. elo.test.ts
|
||||
- **测试数量**: 24
|
||||
- **覆盖**: ELO 评分计算逻辑
|
||||
- **测试内容**:
|
||||
- 基础 ELO 计算
|
||||
- K因子变化
|
||||
- 平局处理
|
||||
- 极端分差
|
||||
|
||||
### 3. forum-hot.test.ts
|
||||
- **测试数量**: 30
|
||||
- **覆盖**: 论坛热度排序算法
|
||||
- **测试内容**:
|
||||
- 热度公式计算
|
||||
- 时间衰减
|
||||
- 回复加权
|
||||
- 点赞加权
|
||||
- 置顶优先
|
||||
|
||||
### 4. achievements.test.ts
|
||||
- **测试数量**: 26
|
||||
- **覆盖**: 成就系统逻辑
|
||||
- **测试内容**:
|
||||
- 成就解锁条件
|
||||
- 进度计算
|
||||
- 徽章授予
|
||||
- 边界条件
|
||||
|
||||
### 5. points-reward.test.ts
|
||||
- **测试数量**: 24
|
||||
- **覆盖**: `src/lib/points-reward.ts`
|
||||
- **测试内容**:
|
||||
- 各操作积分奖励
|
||||
- 每日上限检查
|
||||
- Streak freeze 逻辑
|
||||
- 商店购买消耗
|
||||
- 等级升级触发
|
||||
|
||||
---
|
||||
|
||||
## 运行命令
|
||||
|
||||
```bash
|
||||
# 运行所有测试
|
||||
npx vitest run
|
||||
|
||||
# 监听模式
|
||||
npx vitest
|
||||
|
||||
# 生成覆盖率报告
|
||||
npx vitest run --coverage
|
||||
|
||||
# 运行特定测试文件
|
||||
npx vitest run src/__tests__/level-config.test.ts
|
||||
|
||||
# UI 模式
|
||||
npx vitest --ui
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 测试规范
|
||||
|
||||
### 文件命名
|
||||
- 测试文件: `*.test.ts`
|
||||
- 目录: `src/__tests__/`
|
||||
|
||||
### 测试结构
|
||||
```typescript
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
|
||||
describe("模块名", () => {
|
||||
beforeEach(() => {
|
||||
// setup
|
||||
});
|
||||
|
||||
describe("功能点", () => {
|
||||
it("应该满足某条件", () => {
|
||||
// arrange
|
||||
// act
|
||||
// assert
|
||||
});
|
||||
|
||||
it("应该处理边界情况", () => {
|
||||
// ...
|
||||
});
|
||||
|
||||
it("应该优雅处理错误", () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 测试原则
|
||||
- 每个 `it` 测试单一行为
|
||||
- 使用 `describe` 组织相关测试
|
||||
- Arrange → Act → Assert 三段式
|
||||
- 覆盖正常路径 + 边界条件 + 错误路径
|
||||
- 禁止 `.skip` 除非有明确 TODO 注释
|
||||
- Mock 外部依赖(Prisma、外部 API)
|
||||
|
||||
### 覆盖率目标
|
||||
| 指标 | 目标 |
|
||||
|------|------|
|
||||
| 行覆盖率 | ≥ 80% |
|
||||
| 分支覆盖率 | ≥ 80% |
|
||||
| 函数覆盖率 | ≥ 80% |
|
||||
| 语句覆盖率 | ≥ 80% |
|
||||
@@ -0,0 +1,118 @@
|
||||
# 暗色模式模块
|
||||
|
||||
## 概述
|
||||
追光AI支持浅色/暗色双主题模式,通过 ThemeProvider + CSS 变量驱动,用户偏好自动持久化到 localStorage,整体遵循 Tailwind CSS `class` 策略。
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
ThemeProvider (Context)
|
||||
├── 读取 localStorage 初始主题
|
||||
├── 监听系统 prefers-color-scheme 变化
|
||||
├── 在 <html> 上切换 "dark" class
|
||||
└── 提供 toggle/setTheme 方法给子孙组件
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心组件
|
||||
|
||||
### ThemeProvider
|
||||
- **文件**: `src/components/ThemeProvider.tsx`
|
||||
- **位置**: 根 layout.tsx 包裹
|
||||
- **功能**:
|
||||
- `theme` state: `"light"` | `"dark"` | `"system"`
|
||||
- `toggleTheme()` — 在 light/dark 间切换
|
||||
- `setTheme(mode)` — 设置为指定模式
|
||||
- 自动监听 `prefers-color-scheme` 媒体查询(`system` 模式时)
|
||||
- 持久化到 `localStorage("zhuiguang-theme")`
|
||||
|
||||
### Header 主题切换按钮
|
||||
- **文件**: `src/components/layout/Header.tsx`
|
||||
- 太阳 ☀️ / 月亮 🌙 图标切换
|
||||
- 点击调用 `toggleTheme()`
|
||||
- 动画过渡效果
|
||||
|
||||
---
|
||||
|
||||
## CSS 变量系统
|
||||
|
||||
### globals.css 暗色变量
|
||||
```css
|
||||
:root {
|
||||
/* 浅色主题变量 (默认) */
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222 47% 11%;
|
||||
/* ... */
|
||||
}
|
||||
|
||||
.dark {
|
||||
/* 暗色主题变量覆盖 */
|
||||
--background: 222 47% 11%;
|
||||
--foreground: 210 40% 98%;
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
- 使用 HSL 变量,Tailwind 通过 `hsl(var(--xxx))` 引用
|
||||
- shadcn/ui 组件自动适配暗色模式(基于 `.dark` class)
|
||||
|
||||
---
|
||||
|
||||
## 组件适配(14个文件已更新)
|
||||
|
||||
以下组件已适配暗色模式:
|
||||
|
||||
| 组件 | 适配内容 |
|
||||
|------|----------|
|
||||
| Header | 主题切换按钮、导航栏背景色 |
|
||||
| Footer | 页脚背景色、文字色、分隔线 |
|
||||
| HeroBanner | Canvas 粒子颜色随主题切换 |
|
||||
| HomePageClient | 卡片背景、文字颜色 |
|
||||
| ToolsContent | 搜索框、筛选侧边栏、卡片 |
|
||||
| SkillsPageClient | 技能卡片、分类标签 |
|
||||
| 社区相关组件 | ForumBoard/ForumTopicCard/ForumEditor |
|
||||
| 通知组件 | NotificationBell/NotificationCenter |
|
||||
| 用户中心 | 积分卡片、等级进度条 |
|
||||
| 工具详情 | 信息面板、推荐列表 |
|
||||
| 技能详情 | 评测卡片、详情面板 |
|
||||
| 后台管理 | 管理面板所有表格/表单 |
|
||||
|
||||
---
|
||||
|
||||
## 设计规范
|
||||
|
||||
### 浅色主题
|
||||
- 背景: `bg-white` / `bg-muted/50`
|
||||
- 卡片: `bg-white/80` (毛玻璃) / `bg-white/60` (卡片)
|
||||
- 边框: `border-border/40`
|
||||
- 阴影: `shadow-sm`
|
||||
|
||||
### 暗色主题
|
||||
- 背景: `bg-background` (HSL 222 47% 11%)
|
||||
- 卡片: `bg-card` (HSL 222 47% 13-15%)
|
||||
- 边框: `border-border` (HSL 215 20% 25%)
|
||||
- 阴影: `shadow-md` (更明显的阴影)
|
||||
|
||||
### 颜色规范(双主题通用)
|
||||
- 文字: 浅色 `-600/-700` | 暗色 `-300/-200`
|
||||
- 背景: 浅色 `-50` | 暗色 `-900/-950`
|
||||
- 边框: 浅色 `-200/60` | 暗色 `-700/60`
|
||||
|
||||
---
|
||||
|
||||
## 技术实现要点
|
||||
|
||||
### 闪烁防护
|
||||
- ThemeProvider 在 `useEffect` 中初始化,避免 SSR 时的主题闪烁
|
||||
- `<html>` 上通过内联 script 在 hydration 前设置 class(防止白屏闪烁)
|
||||
|
||||
### 系统主题跟随
|
||||
- `matchMedia('(prefers-color-scheme: dark)')` 监听
|
||||
- 用户手动设置后覆盖系统偏好
|
||||
- "system" 模式时动态跟随
|
||||
|
||||
### 持久化策略
|
||||
- 存储键: `zhuiguang-theme`
|
||||
- 值: `"light"` | `"dark"`
|
||||
- 优先级: localStorage > 系统偏好 > 默认 light
|
||||
@@ -0,0 +1,128 @@
|
||||
# 工具功能增强模块
|
||||
|
||||
## 概述
|
||||
工具功能增强模块包含工具对比(Compare)、工具认证徽章(Verified Badge)和个性化工具推荐(Recommendations),提升用户决策效率和信任度。
|
||||
|
||||
---
|
||||
|
||||
## 工具对比 (Tool Comparison) 🆕
|
||||
|
||||
### 功能概述
|
||||
用户可同时选择最多 4 个工具进行并排对比,从 10 个维度查看详细差异。
|
||||
|
||||
### 架构
|
||||
```
|
||||
CompareProvider (React Context)
|
||||
├── compareList: Tool[] (最多4个)
|
||||
├── addToCompare(tool) — 添加工具到对比列表
|
||||
├── removeFromCompare(toolId) — 移除
|
||||
├── clearCompare() — 清空
|
||||
└── isInCompare(toolId) — 是否已在列表
|
||||
```
|
||||
|
||||
### 核心组件
|
||||
|
||||
| 组件 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| CompareProvider | `src/components/common/CompareProvider.tsx` | Context Provider,管理对比状态 |
|
||||
| CompareBar | `src/components/common/CompareBar.tsx` | 底部浮动对比栏(显示已选工具+对比按钮) |
|
||||
| CompareButton | `src/components/common/CompareButton.tsx` | 工具卡片上的"加入对比"切换按钮 |
|
||||
|
||||
### 页面
|
||||
|
||||
#### /tools/compare
|
||||
- 10维度对比表格
|
||||
- 维度: 名称/分类/定价模型/定价详情/功能特性/标签/评分/评论数/浏览数/官网链接
|
||||
- 支持一键移除/清空/返回浏览
|
||||
|
||||
### 交互流程
|
||||
1. 在工具列表/详情页点击 CompareButton 添加工具
|
||||
2. 底部 CompareBar 浮出显示已选工具(最大4个)
|
||||
3. 点击 CompareBar 的"开始对比"按钮跳转到 /tools/compare
|
||||
4. 对比页面展示并排表格,可移除/继续添加
|
||||
|
||||
### CompareBar 状态
|
||||
- 空状态: 隐藏
|
||||
- 1个工具: 显示但对比按钮禁用(至少需要2个)
|
||||
- 2-4个工具: 显示完整,对比按钮可用
|
||||
- 4个工具: 添加按钮禁用,显示"已满"
|
||||
|
||||
---
|
||||
|
||||
## 工具认证徽章 (Tool Verification) 🆕
|
||||
|
||||
### 功能概述
|
||||
管理员可为优质/官方工具添加蓝V认证徽章,提升用户信任度。
|
||||
|
||||
### 数据模型
|
||||
- Tool 表新增字段: `isVerified: Boolean @default(false)`
|
||||
- Tool 表新增字段: `verifiedAt: DateTime?`
|
||||
|
||||
### API
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/tools/[id]/verify | POST | 管理员认证工具(添加蓝V) |
|
||||
| /api/admin/tools/[id]/verify | DELETE | 管理员取消认证 |
|
||||
| /api/tools/verified | GET | 获取所有已认证工具 |
|
||||
|
||||
### 前端展示
|
||||
- 工具详情页: 名称旁边显示蓝色勾号徽章
|
||||
- 工具列表卡片: 名称旁边显示小蓝V图标
|
||||
- 认证工具专属筛选: "仅看认证" 开关
|
||||
|
||||
---
|
||||
|
||||
## 内容推荐引擎 🆕
|
||||
|
||||
### 功能概述
|
||||
基于用户浏览历史和收藏偏好,推荐相关工具和话题。
|
||||
|
||||
### 核心 API
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/recommendations | GET | 获取个性化推荐(工具+技能) |
|
||||
|
||||
### 推荐算法
|
||||
- **协同过滤**: 基于相似用户的收藏/浏览模式
|
||||
- **内容相似度**: 基于工具分类/标签/定价模型
|
||||
- **热度加权**: 综合浏览量、评论数、评分
|
||||
|
||||
### 前端组件
|
||||
|
||||
| 组件 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| PersonalizedRecommend | `src/components/common/PersonalizedRecommend.tsx` 🆕 | 首页/用户中心的个性化推荐区 |
|
||||
| RelatedTopics | `src/components/forum/RelatedTopics.tsx` | 话题详情页的相关话题推荐 |
|
||||
|
||||
### 展示位置
|
||||
- 首页 "为你推荐" 板块
|
||||
- 工具详情页 "相关推荐"
|
||||
- 话题详情页 "相关话题"
|
||||
- 用户中心 "猜你喜欢"
|
||||
|
||||
### PersonalizedRecommend 组件
|
||||
- Props: `{ type: "tool" | "skill" | "topic", limit?: number }`
|
||||
- 瀑布流/网格布局
|
||||
- 骨架屏加载状态
|
||||
- 空状态友好提示
|
||||
- 支持刷新获取新推荐
|
||||
|
||||
---
|
||||
|
||||
## 共享类型定义
|
||||
|
||||
集中管理来源类型标签和颜色:
|
||||
|
||||
### src/lib/source-type.ts 🆕
|
||||
```typescript
|
||||
export function sourceTypeLabel(type: string): string
|
||||
export function sourceTypeColor(type: string): string
|
||||
```
|
||||
- 支持: github / gitlab / gitee / huggingface / 官网
|
||||
- 统一管理标签中文名和 Tailwind 配色
|
||||
|
||||
### src/lib/constants.ts 🆕
|
||||
- `tagColors` — 工具/技能标签配色映射
|
||||
- 统一管理所有标签的颜色方案
|
||||
Reference in New Issue
Block a user