438 lines
29 KiB
Markdown
438 lines
29 KiB
Markdown
# 追光AI 项目开发规则
|
||
|
||
> **本文件是 L2 工程标准层**(四层结构索引见 [README.md](README.md))。其他层:
|
||
> - L0 方法论:[../ai_coding_knowledge.json](../ai_coding_knowledge.json)(AI 编程效率方法库,机器可解析)
|
||
> - L1 协作规则:[ai_agent_rules.md](ai_agent_rules.md)(启动加载)· [ai_collaboration.md](ai_collaboration.md)(Plan-first + 自动记录)
|
||
> - L3 项目事实:[../knowledge_graph.jsonl](../knowledge_graph.jsonl)(知识图谱)· [../knowledge/](../knowledge/)(能力/过程/成果自动记录)
|
||
|
||
## 端口规范
|
||
- 应用端口范围: **8301-8310**(预留扩展)
|
||
- 默认端口: **8301**
|
||
- 重启脚本仅扫描8301-8310范围
|
||
- **强制要求:本项目端口必须锁定在8301-8310区间内,禁止使用其他端口,因为本服务器同时运行其他产品**
|
||
|
||
## 服务器连接信息(重要!总是需要)
|
||
- **IP地址**: 119.45.242.239
|
||
- **登录用户**: ubuntu
|
||
- **SSH密钥**: `C:\SSH\zhuiguang-ai\zg.pem`(2026-10-02 校正;旧值 `E:\0.Center-S2\S890-V3\pem\zg.pem` 已迁移)
|
||
- **SSH命令**: `ssh -i "C:\SSH\zhuiguang-ai\zg.pem" ubuntu@119.45.242.239`
|
||
- **SCP示例**: `scp -i "C:\SSH\zhuiguang-ai\zg.pem" localfile ubuntu@119.45.242.239:/home/ubuntu/zhuiguang-ai/`
|
||
|
||
## 服务器与基础设施
|
||
- **域名**: www.zhuig.com (HTTPS,SSL证书自动续期)
|
||
- **部署目录**: /home/ubuntu/zhuiguang-ai
|
||
- **访问地址**: https://www.zhuig.com (HTTP自动跳转HTTPS)
|
||
- **数据库**: 阿里云RDS MySQL — rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306
|
||
- **Redis**: 云服务器上已有(Docker容器redis-cache:6379),与其他项目共用,有密码认证
|
||
- **工作区/开发目录**: `E:\KF_7\ZhuiGuangAI\zhuiguang-ai`(master,当前唯一活跃工作副本)
|
||
- **本地裸仓镜像(备份入口)**: `K:\git-repos\zhuiguang-ai.git`(bare,2026-10-01 新建。源仓库 remote 需指向它才能持续备份)
|
||
- **已停用副本**: `E:\ZG_Dev\ZhuiGuangAI\zhuiguang-ai`(停在 2026-05-23,无 remote)与 `K:\git-repos\zhuiguang-ai`(非裸仓旧工作副本,同样停在 2026-05-23)
|
||
- **远端现状**: 源仓库 remote `local` 仍指向已不存在的 `c:\gitbf\zhuiguang-ai.git`;云端 Gitea(119.45.242.239:3000)无本项目仓库
|
||
- **Docker管理**: `docker ps` / `docker logs zhuiguang-ai-app` / `docker restart zhuiguang-ai-app`
|
||
|
||
### ⚠️ 多项目共存服务器(更新/部署铁律)
|
||
|
||
服务器 119.45.242.239 上**同时运行多个项目**和**多个共享服务**,任何代码更新、部署、运维操作必须严格隔离,绝不能影响其他项目。
|
||
|
||
#### 当前服务器实际部署清单(2026-06-10 巡检)
|
||
|
||
| 项目 | 路径 | 占用端口 | 进程 |
|
||
|------|------|----------|------|
|
||
| **zhuiguang-ai(我们)** | /home/ubuntu/zhuiguang-ai | 8301 (next-server) | Docker: zhuiguang-ai-app + zhuiguang-ai-cron |
|
||
| zhuiguang-ai-backup | /home/ubuntu/zhuiguang-ai-backup | — | 静态备份 |
|
||
| zhuiguang-quant | /home/ubuntu/zhuiguang-quant | 8701 / 8802 (java) | 独立 java 进程 |
|
||
| zhenfang | /home/ubuntu/zhenfang | — | — |
|
||
| snowy-fgt | /home/ubuntu/snowy-fgt | 7001 (gunicorn) | 独立 gunicorn |
|
||
| agent-system | /home/ubuntu/agent-system | — | — |
|
||
| nacos | /home/ubuntu/nacos | 8601 / 8602 (java) | 独立 java 进程 |
|
||
|
||
#### 共享服务(绝对不能动)
|
||
|
||
| 服务 | 端口 | 容器名 | 共享给 |
|
||
|------|------|--------|--------|
|
||
| Redis | 6379 | redis-cache (Docker) | 所有项目 |
|
||
| Nacos | 8848 / 9848 | nacos (Docker) | 注册中心 |
|
||
| MinIO | 9000 / 9001 | minio (Docker) | 文件存储 |
|
||
| nginx | 80 / 443 / 8720 / 8801 | 系统 nginx | 反向代理多域名 |
|
||
|
||
#### 铁律(更新/部署前必读)
|
||
|
||
1. **端口锁定 8301-8310**:本项目所有 HTTP/WS 服务只能使用 8301-8310 区间。禁止占用 80/443/8601-8802/8848/9000-9001/6379/7001 等任何其他端口。Docker 容器启动时若发现目标端口被占,**先排查是哪个项目在用**,绝不能 kill 别人的进程。
|
||
2. **进程隔离**:禁止 `pkill -f node` / `pkill -f java` / `pkill -f nginx` / `pkill -f docker` 等全局杀进程。重启本项目**只能重启 Docker 容器**(`docker restart zhuiguang-ai-app`)或 8301-8310 端口上的进程。
|
||
3. **禁止修改其他项目目录**:`/home/ubuntu/{zhuiguang-quant,zhenfang,snowy-fgt,agent-system,nacos}` 及其子目录**只读**,不要 `cd` 进去 `git pull` / `npm install` / 改文件。
|
||
4. **禁止修改共享服务配置**:
|
||
- 不动 Redis(6379)—— 别人可能正在用我们的 key 以外的数据
|
||
- 不动 Nacos(8848)—— 注册中心是全局的
|
||
- 不动 MinIO(9000)—— 文件存储多项目共用
|
||
- 不动 nginx 主配置 / sites-enabled 下的其他站点 —— 我们的反代规则放在独立文件,文件名带 `zhuiguang` 前缀
|
||
- 不 `docker restart` / `docker stop` / `docker rm` 任何邻居容器(本项目容器名以 `zhuiguang-ai` 开头)
|
||
5. **数据库隔离**:阿里云 RDS 上的数据库是本项目专用(`zhuiguang_ai`),但**严禁 `DROP DATABASE` / `TRUNCATE` 全表 / 删 migration 文件**。改 schema 必须 `prisma migrate dev` 生成新 migration 走前向变更。绝不执行任何会清空数据的脚本。
|
||
6. **Crontab 隔离**:本项目定时任务已全部迁移到容器内 supercronic 调度(`zhuiguang-ai-cron` 容器),主机 crontab 已清空。**禁止在主机 crontab 中添加本项目定时任务**,所有定时任务通过更新 `crontab.txt` 并重建 cron 容器完成。也禁止 `crontab -r` 清空(可能影响邻居项目)。
|
||
7. **磁盘隔离**:`/home/ubuntu/zhuiguang-ai/logs/` 是本项目日志目录;`/home/ubuntu/logs/` 是其他项目的,**不要混淆**。本项目备份只放 `/home/ubuntu/zhuiguang-ai-backup/`。
|
||
8. **环境变量隔离**:只读 `/home/ubuntu/zhuiguang-ai/.env`。**不要改 `~/.bashrc` / `/etc/environment` / `/etc/profile`** 等全局环境文件,全局变量可能影响其他项目。
|
||
9. **部署前自检清单**(强制):
|
||
- [ ] `docker ps --filter name=zhuiguang-ai` —— 确认当前运行的容器
|
||
- [ ] `ss -tlnp | grep :8301` —— 确认 8301 是容器进程
|
||
- [ ] `git status` —— 确认本地代码只动本项目文件
|
||
- [ ] `npx tsc --noEmit` —— 零错误
|
||
- [ ] **不动** `/home/ubuntu/` 下其他项目目录
|
||
- **不动** Redis/Nacos/MinIO 容器
|
||
- **不动** nginx/sites-enabled 下非 zhuiguang 开头的文件
|
||
- **不动** 全局 crontab(本项目已用 supercronic 容器)
|
||
10. **部署后自检清单**(强制):
|
||
- [ ] `docker ps` —— zhuiguang-ai-app 和 zhuiguang-ai-cron 状态 healthy
|
||
- [ ] `curl -I https://www.zhuig.com` —— 200,且响应时间 < 3s
|
||
- [ ] `ss -tlnp | grep :8301` —— 进程为 Docker 容器内 next-server
|
||
- [ ] `docker logs --tail 20 zhuiguang-ai-app` —— 无 ERROR
|
||
- [ ] 其他项目(zhuiguang-quant/zhenfang/snowy-fgt/nacos 等)的进程仍在、状态正常
|
||
|
||
#### 反例(禁止操作)
|
||
|
||
```bash
|
||
# ❌ 禁止 —— 全局杀进程
|
||
pkill -f node
|
||
pkill -f java
|
||
kill -9 $(pgrep node)
|
||
systemctl restart nginx
|
||
|
||
# ❌ 禁止 —— 改其他项目
|
||
cd /home/ubuntu/zhuiguang-quant && git pull
|
||
rm -rf /home/ubuntu/zhenfang
|
||
docker restart redis-cache
|
||
docker stop nacos
|
||
vi /etc/nginx/nginx.conf
|
||
crontab -r
|
||
|
||
# ❌ 禁止 —— 改共享服务
|
||
redis-cli FLUSHALL
|
||
mysql -e "DROP DATABASE ..."
|
||
```
|
||
|
||
#### 正例(本项目更新/部署的标准做法)
|
||
|
||
```bash
|
||
# ✅ 只动本项目
|
||
cd /home/ubuntu/zhuiguang-ai
|
||
git pull
|
||
docker build -t zhuiguang-ai:latest .
|
||
docker stop zhuiguang-ai-app zhuiguang-ai-cron
|
||
docker rm zhuiguang-ai-app zhuiguang-ai-cron
|
||
# 然后重新 docker run(参考 docker-compose.yml 或 CONTAINERIZATION.md)
|
||
|
||
# ✅ 查看状态时不漏看其他项目
|
||
docker ps --filter name=zhuiguang-ai # 看本项目容器状态
|
||
ss -tlnp | grep -E ':(8301|8601|8701|8802)' # 看我们的端口 + 邻居项目的端口
|
||
|
||
# ✅ 日志查看
|
||
docker logs --tail 50 zhuiguang-ai-app # APP 容器日志
|
||
docker logs --tail 50 zhuiguang-ai-cron # Cron 容器日志
|
||
```
|
||
|
||
|
||
|
||
## 技术栈
|
||
- Next.js 14 (App Router) + TypeScript
|
||
- Tailwind CSS + shadcn/ui
|
||
- Prisma 7.8 + MySQL (阿里云RDS)
|
||
- NextAuth.js v4 (Credentials Provider)
|
||
- DeepSeek API (deepseek-v4-pro) — 用于技能五维评测生成(服务端脚本调用)
|
||
|
||
## 代码风格
|
||
- 不添加注释(除非明确要求)
|
||
- 使用中文作为UI文案和提示词语言
|
||
- TypeScript严格模式,零编译错误
|
||
- 组件使用 `"use client"` 标记客户端组件
|
||
- 路径别名: `@/*` → `./src/*`
|
||
- **禁止在代码中硬编码任何AI API Key**
|
||
- **禁止在代码中调用任何外部AI API(DeepSeek、OpenAI等)** — 前台/后台页面代码中禁止调用;服务端脚本(scripts/)中允许通过环境变量调用DeepSeek API和GitHub API
|
||
- 所有发现/导入功能通过页面提示词+JSON粘贴方式完成,不调用外部接口
|
||
|
||
## 构建与检查
|
||
- 修改代码后必须运行 `npx tsc --noEmit` 确认零错误
|
||
- 修改代码后必须运行 `npx vitest run` 确认所有测试通过
|
||
- 本地开发服务器: `npm run dev` (端口8301)
|
||
- 生产构建: `docker build -t zhuiguang-ai:latest .`
|
||
- 部署: `docker stop/rm` 旧容器 → `docker run` 新容器
|
||
- **打包分析**: `ANALYZE=true npm run build` 启用 `@next/bundle-analyzer` 分析包体积
|
||
|
||
## 测试规范
|
||
- 测试框架: Vitest
|
||
- 配置文件: `vitest.config.ts` + `vitest.setup.ts`
|
||
- 测试目录: `src/__tests__/`,文件名匹配 `*.test.ts`
|
||
- 覆盖率目标: **80%+**(行/分支/函数/语句)
|
||
- tsconfig 需包含 `"types": ["vitest/globals"]` 以启用全局 test/expect/describe
|
||
- 测试类别:
|
||
- 工具函数单元测试(lib 目录下的纯函数)
|
||
- API 路由集成测试
|
||
- 组件渲染测试(配合 @testing-library/react)
|
||
- 禁止跳过测试(`.skip`)除非有明确的 TODO 注释说明原因
|
||
|
||
## 图片优化规范
|
||
- **强制使用 LazyImage 组件** (`src/components/ui/LazyImage.tsx`),禁止使用原生 `<img>` 标签
|
||
- LazyImage 特性:
|
||
- 基于 next/image 的懒加载包装器
|
||
- 内置骨架屏加载状态(Skeleton loading state)
|
||
- 错误回退占位图(Error fallback)
|
||
- 支持 `referrerPolicy` 属性(用于跨域图片场景)
|
||
- 支持 `width`/`height` 或 `fill` 模式
|
||
- 用法示例:
|
||
```tsx
|
||
import LazyImage from "@/components/ui/LazyImage";
|
||
// 固定尺寸
|
||
<LazyImage src={url} alt="描述" width={32} height={32} />
|
||
// 响应式
|
||
<LazyImage src={url} alt="描述" fill className="object-cover" />
|
||
// 跨域图片
|
||
<LazyImage src={url} alt="描述" width={48} height={48} referrerPolicy="no-referrer" />
|
||
```
|
||
- 必须提供有意义的 `alt` 文本
|
||
- 装饰性图片使用 `alt=""` 配合 `role="presentation"`
|
||
|
||
## 导航规范(Link vs router.push)
|
||
- 所有静态页面内导航必须使用 Next.js `<Link>` 组件
|
||
- 禁止使用 `<button onClick={() => router.push(...)}>` 进行页面跳转
|
||
- 适用场景:
|
||
- 分页按钮 → `<Link>`
|
||
- 侧边栏筛选 → `<Link>`(含查询参数)
|
||
- 面包屑 → `<Link>`
|
||
- 卡片/列表项 → `<Link>`
|
||
- "清除筛选"按钮 → `<Link href="/base-path">`
|
||
- 仅外部链接使用 `<a>`(需加 `target="_blank" rel="noopener noreferrer"`)
|
||
|
||
## API 响应格式规范
|
||
- 列表接口统一使用 `total`(不是 `totalCount`)表示总数
|
||
- 返回格式: `{ data, total, page, pageSize }` 或 `{ success, error }`
|
||
- 前端消费端也同步使用 `total` 字段
|
||
- 已统一接口: `/api/notifications`, `/api/forum/topics`, `/api/comments`, `/api/user/points`
|
||
|
||
## 并行查询规范
|
||
- 多个独立的 Prisma 查询必须使用 `Promise.all` 并行执行
|
||
- 严禁串行 await 多个无依赖的数据库查询
|
||
```typescript
|
||
// ✅ 正确:并行查询
|
||
const [tool, relatedTools, reviewCount] = await Promise.all([
|
||
prisma.tool.findUnique({ where: { slug } }),
|
||
prisma.tool.findMany({ where: { categoryId }, take: 6 }),
|
||
prisma.review.count({ where: { toolId } }),
|
||
]);
|
||
```
|
||
|
||
## 无障碍规范(WCAG 2.1)
|
||
- 所有交互元素(div onClick)必须添加 `role` + `aria-*` 属性 + 键盘事件(`onKeyDown`)
|
||
- 搜索输入框必须添加 `aria-label` 属性
|
||
- 装饰性图片添加 `role="presentation"`(不暴露给屏幕阅读器)
|
||
- 根布局必须提供跳过导航链接(Skip-link)
|
||
- 主内容区域使用 `<main id="main-content" tabIndex={-1}>`
|
||
|
||
## TypeScript 类型规范
|
||
- 禁止使用 `any` 类型
|
||
- 泛型函数使用 `<T>` 约束(参考 `src/lib/cache.ts` 的 `cachedResponse<T>`)
|
||
- API 回调函数使用明确的参数类型
|
||
- 内联对象类型使用 interface 而非匿名类型字面量
|
||
- `src/lib/admin-auth.ts`: 使用 Prisma 严格类型,id 字段统一为 `number`
|
||
|
||
## 数据库
|
||
- 云数据库: 阿里云RDS MySQL
|
||
- 连接: `mysql://mohe001:***@rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306/zhuiguang_ai`
|
||
- Prisma单例模式防止热重载多实例
|
||
- 修改Schema后: `npx prisma migrate dev --name <描述>`
|
||
|
||
## 认证
|
||
- 管理员: admin@zhuiguang.ai / admin123
|
||
- JWT Session策略
|
||
- middleware.ts保护/admin路由(跳过/admin/login)
|
||
- 后台API需requireAdmin中间件验证(src/lib/admin-auth.ts)
|
||
- 用户注册/登录: NextAuth Credentials Provider,支持邮箱+密码
|
||
|
||
## API约定
|
||
- 前台API: `/api/` 前缀,无需认证
|
||
- 后台API: `/api/admin/` 前缀,需NextAuth认证
|
||
- 分页参数: `page`(默认1), `pageSize`(默认20)
|
||
- 返回格式: `{ data, total, page, pageSize }` 或 `{ success, error }`
|
||
- 批量操作: body中传 `ids` 数组
|
||
|
||
## 页面路由
|
||
- 前台: `/`, `/tools`, `/tools/[slug]`, `/categories/[slug]`, `/skills`, `/skills/[slug]`, `/login`, `/user`, `/user/favorites`, `/user/[id]`(会员空间), `/user/collections`, `/daily`, `/reviews`, `/community`, `/community/[category]`, `/community/topic/[id]`, `/community/bots`, `/community/bots/leaderboard`
|
||
- 后台: `/admin/login`, `/admin/pending`, `/admin/pending-skills`, `/admin/tools`, `/admin/skills`, `/admin/categories`, `/admin/skill-categories`, `/admin/discover-tools`, `/admin/check-tools`, `/admin/discover-skills`, `/admin/update-skills`, `/admin/discover-news`, `/admin/system-config`, `/admin/tasks`, `/admin/tasks/logs`, `/admin/tasks/[taskKey]`, `/admin/reviews`, `/admin/roles`, `/admin/bot-experiments`, `/admin/bot-adversarial-learning`, `/admin/bot-analytics`
|
||
|
||
## 五大操作指令
|
||
|
||
用户使用以下五个命令时,必须跳转到对应页面理解流程并按流程执行。
|
||
所有页面均为"提示词+JSON粘贴导入"模式,不调用任何外部AI API。
|
||
|
||
### 探索AI工具
|
||
- 页面: `/admin/discover-tools`
|
||
- 流程: 选分类 → 复制提示词发给AI → 粘贴JSON → 导入审核列表 → 抓取Logo
|
||
- 导入API: POST `/api/admin/discover-tools` body: `{ tools: [...], categoryId }`
|
||
- API接收前端提交的工具JSON数组,自动去重导入待审核列表
|
||
- Logo抓取API: POST `/api/admin/pending/fetch-logos`
|
||
- 工具分类(20个): 文本生成(165), 图像生成(174), 视频生成(183), 音频与语音(191), 代码开发(199), AI Agent(208), 办公效率(216), 设计与创意(224), 营销与SEO(231), 数据分析(238), 教育与学习(245), 搜索与信息(252), 安全与合规(258), 医疗健康(264), 金融与法律(270), 电商与零售(276), 3D与游戏(282), 科学研究(288), 模型与框架(294), 聊天机器人(302)
|
||
|
||
### 检测AI工具
|
||
- 页面: `/admin/check-tools`
|
||
- 流程: 选择范围(已发布/待审核) → 一键检测+抓取Logo → 处理失效工具
|
||
- 检测API: POST `/api/admin/check-tools` body: `{ type: "published" | "pending" }`
|
||
- 系统自动逐一GET请求检测网站可访问性,同时自动抓取缺失Logo并记录成功方法名
|
||
- 删除API: DELETE `/api/admin/tools/{id}` / `/api/admin/pending/{id}`
|
||
|
||
### 探索AI技能
|
||
- 页面: `/admin/discover-skills`
|
||
- 流程: 选分类 → 复制提示词发给AI → 粘贴JSON → 导入审核列表
|
||
- 导入API: POST `/api/admin/discover-skills` body: `{ skills: [...], categoryId }`
|
||
- API接收前端提交的技能JSON数组,自动去重导入待审核列表
|
||
- 技能分类(20个父分类): 代码生成(1), 测试(10), 代码质量与分析(20), 安全(29), 文档(36), 架构与设计(43), 需求工程(49), DevOps与部署(56), 调试与错误处理(62), 形式化验证(69), 维护与重构(76), 版本控制与协作(82), 开发工具(86), UI/UX设计(91), 科学研究(95), 金融(103), 云服务(109), 移动开发(115), AI/ML工程(120), 营销与增长(127)
|
||
|
||
### 更新Skill技能
|
||
- 页面: `/admin/update-skills`
|
||
- 流程: 选择范围(已发布/待审核) → 一键更新 → 自动同步星级
|
||
- 更新API: POST `/api/admin/update-stars` body: `{ type: "published" | "pending" }`
|
||
- 系统自动从GitHub/Gitee/GitCode API获取最新星级评分并写入数据库
|
||
|
||
### AI新闻发现
|
||
- 页面: `/admin/discover-news`
|
||
- 流程: 复制提示词发给AI → 粘贴JSON → 导入今日新闻
|
||
- 导入API: POST `/api/admin/discover-news` body: `{ items: [...] }`
|
||
- API接收前端提交的新闻JSON数组,自动生成今日AI日报
|
||
- 新闻分类: 产品发布/融资投资/技术突破/政策法规/开源项目/行业事件
|
||
|
||
### 通用执行规则
|
||
1. **禁止调用任何外部AI API**,所有发现/导入功能通过页面提示词+JSON粘贴方式完成
|
||
2. 页面提供提示词模板(含排除列表),用户复制发给AI助手获取JSON,粘贴到页面导入
|
||
3. 导入API接收JSON数组,自动去重(名称+网址),导入待审核列表
|
||
4. 导入工具后建议执行Logo抓取,确保所有工具有图标
|
||
5. 所有提示词要求: 优先推荐国产AI工具/技能,国内可直连,中文友好
|
||
6. 检测工具时:系统自动GET请求检测网站可访问性,同时抓取缺失Logo
|
||
7. 更新技能时:系统自动从GitHub/Gitee/GitCode API获取最新星级
|
||
|
||
## 设计系统
|
||
- 浅色主题,HSL CSS变量
|
||
- 圆角: rounded-xl / rounded-2xl
|
||
- 边框: border-border/40 (40%透明度)
|
||
- 背景: bg-white/80 (毛玻璃) / bg-white/60 (卡片) / bg-muted/50 (输入框)
|
||
- 阴影: shadow-sm (卡片) / shadow-md (悬浮)
|
||
- 动画: transition-all duration-200
|
||
- 自定义工具类: .glow-sm, .gradient-text, .glass, .card-shine, .dot-grid, .animate-fade-in
|
||
- 颜色规范: 文字用 -600/-700 (非-400),背景用 -50 (非-500/10),边框用 -200/60 (非-500/20)
|
||
- 输入框: bg-muted/50 focus:bg-white focus:ring-2 focus:ring-primary/10
|
||
|
||
## 环境变量
|
||
- GITHUB_TOKEN: GitHub Personal Access Token(可选,提升API限流从60→5000次/小时)
|
||
- DEEPSEEK_API_KEY: DeepSeek API Key(用于技能评测生成脚本、AI日报整理)
|
||
- OPENAI_API_KEY: OpenAI API Key(Bot活动引擎使用,生成论坛内容)
|
||
|
||
## 数字人Bot系统
|
||
- **角色定义文件**: `data/bot-characters.json` — 当前 **6 个**「行业情报官」角色(cb_intel / fi_ins_intel / fi_stock_intel / brand_intel / ai_intel / ct_intel);旧 112 角色「模拟真人互刷」体系已于 2026-09-05 退役
|
||
- **Bot头像目录**: `public/bot-avatars/` — SVG 头像 178 个(含历史角色头像)
|
||
- **会员头像库**: `public/avatars/` — SVG 头像 530 个,会员可在个人中心选择或自定义上传
|
||
- **头像生成脚本**: `scripts/generate-avatar-library.mjs` — 批量生成头像库,支持按性别/主题/数量筛选
|
||
- **头像上传目录**: `public/uploads/avatars/` — 用户自定义上传头像存储
|
||
- **Bot用户标记**: User表中 `isBot: true` 标识Bot用户,与真人的互动数据分别统计
|
||
- **Bot活动时段**: 旧「模拟真人互刷」体系已停用(`bot-activity` 等任务在 `crontab.txt` 中已注释,2026-09-05 退役);现由行业情报官引擎承担
|
||
- **Bot数据库**: 12张Bot专用表(BotConfig/BotMemory/BotDailyStat/BotSkill/BotWeeklyReview/BotPersona/BotPersonaVariant/BotPersonaExperiment/BotPersonaAssignment/BotPersonaMetric/BotAdversarialLearning/BotCrossForumAffinity)
|
||
|
||
## 定时任务调度系统
|
||
- **后台管理**: `/admin/tasks`(任务中心)、`/admin/tasks/logs`(执行日志)、`/admin/tasks/[taskKey]`(单任务详情+统计)
|
||
- **数据模型**: TaskConfig(任务配置,含enabled/cronExpr/config)、TaskLog(执行历史,含status/duration/result/error)
|
||
- **种子数据**: `scripts/seed-task-configs.mjs` 初始化 29 个任务配置(含已停用任务,与 `crontab.txt` 存在漂移,见下)
|
||
- **手动触发**: `/admin/tasks` 页支持每个任务运行,也可通过 POST `/api/admin/tasks/run` 触发
|
||
- **API**:
|
||
- `GET/PUT /api/admin/tasks/configs` — 任务配置查询/更新
|
||
- `GET /api/admin/tasks/logs` — 任务执行日志(分页+按taskKey筛选)
|
||
- `POST /api/admin/tasks/run` — 手动触发任务执行
|
||
|
||
### 定时任务(Supercronic 容器调度)
|
||
所有定时任务由 `zhuiguang-ai-cron` 容器内的 supercronic 调度,配置文件 `crontab.txt`(**唯一准绳**)。不再使用主机 crontab。
|
||
|
||
> ⚠️ supercronic 在容器内按 **UTC** 执行(TZ 环境变量不生效),下表时刻均为 UTC,括号外已换算为北京时间(UTC + 8h)。
|
||
> ⚠️ 2026-10-01 巡检确认:`crontab.txt` 已注释停用大量 Bot/行业情报 AI 任务,但 `scripts/seed-task-configs.mjs` 仍写 `enabled: true`、`scripts/health-check.mjs` 仍把它们列入期望键 —— **三方漂移会产生误告警**,新增/停用任务时必须同步这三处。
|
||
|
||
**启用中(19 个)**
|
||
|
||
| UTC | 北京时间 | 任务 | 脚本 | TaskKey |
|
||
|-----|---------|------|------|---------|
|
||
| 0 1 | 09:00 | Task5 更新星值 | `scripts/task5-update-stars.mjs` | task5-update-stars |
|
||
| 0 3 | 11:00 | Task3 工具巡检 | `scripts/task3-check-tools.mjs` | task3-check-tools |
|
||
| 0 4 | 12:00 | Task6 评测热门 | `scripts/task6-review-hot.mjs` | task6-review-hot |
|
||
| 0 4 * * 0 | 周日 12:00 | 工具数据补全 | `scripts/enrich-tool-data.mjs` | enrich-tool-data |
|
||
| 30 4 | 12:30 | 日志清理 | `scripts/cleanup-logs.mjs` | cleanup-logs |
|
||
| 0 5 | 13:00 | Task4 发现技能 | `scripts/daily-discover.mjs` | task4-discover-skills |
|
||
| 0 6 | 14:00 | Task1 发现工具 | `scripts/task1-discover-tools.mjs` | task1-discover-tools |
|
||
| 30 6 | 14:30 | task_log 清理 | `scripts/cleanup-task-logs.mjs` | cleanup-task-logs |
|
||
| 30 7 | 15:30 | AI 日报 | `scripts/daily-news.mjs` | daily-news |
|
||
| 0 8 | 16:00 | Task7 新闻推社区 | `scripts/task7-news-to-community.mjs` | task7-news-to-community |
|
||
| 0 8 1 * * | 每月 1 日 16:00 | 断签保护卡发放 | `scripts/grant-freeze-cards.mjs` | grant-freeze-cards |
|
||
| 30 8 | 16:30 | 任务健康检查 | `scripts/health-check.mjs` | health-check |
|
||
| 0 9 | 17:00 | 通知摘要生成 | `scripts/notification-digest.mjs` | notification-digest |
|
||
| 0 9 * * 1 | 周一 17:00 | 竞品工具数监测 | `scripts/competitor-monitor.mjs` | competitor-monitor |
|
||
| 0 10 | 18:00 | 行业趋势监测 | `scripts/trend-alert.mjs` | trend-alert |
|
||
| 0 10 * * 1 | 周一 18:00 | 周刊生成 | `scripts/newsletter-generate.mjs` | newsletter-generate |
|
||
| 30 10 * * 1 | 周一 18:30 | 每周推荐邮件 | `scripts/weekly-recommend-email.mjs` | weekly-recommend-email |
|
||
| 15 */6 | 每 6 小时 | 点赞计数对账 | `scripts/reconcile-like-counts.mjs` | reconcile-like-counts |
|
||
| 5 23,3,7,11,15 | 每日 7/11/15/19/23 点 | 行业素材采集 | `scripts/industry-thinktank.mjs collect --all` | industry-thinktank |
|
||
|
||
**已注释停用**:`bot-activity`、`bot-skill-crystallize`、`bot-affinity-update`、`bot-weekly-review`、`bot-feedback-loop`、`bot-adversarial-learning-run`、`bot-persona-experiment-run`、`bot-roundtable`、`industry-thinktank weekly/respond`、`industry-daily daily/respond`
|
||
(原因:2026-09-05 旧 Bot「模拟真人互刷」体系退役;2026-09-26 按要求关闭全部 AI 生成功能,行业情报改为需登录访问)
|
||
|
||
- 调度配置: `crontab.txt`(supercronic 格式),修改后需重建 cron 容器生效
|
||
- 日志目录: 容器内 `/app/logs/`;实际 Docker 卷名为 `zhuiguang-ai_bot-logs`(旧文档写 `zhuiguang_ai_bot_logs`,已过时)
|
||
- 定时任务脚本从 `scripts/` 目录直接执行,环境变量由容器 entrypoint 注入
|
||
- **新增任务必须同步四处**:`crontab.txt` + `scripts/<task>.mjs` + `scripts/seed-task-configs.mjs` + `scripts/health-check.mjs`
|
||
|
||
## AI日报新闻源
|
||
- **36kr** RSS (https://36kr.com/feed) — 国内科技资讯
|
||
- **IT之家** RSS (https://www.ithome.com/rss/) — 国内科技资讯
|
||
- **开源中国** RSS (https://www.oschina.net/news/rss) — 开源动态
|
||
- **HackerNews** API — 海外AI/技术热点
|
||
- **Google News** RSS — 海外新闻(国内服务器可能无法访问)
|
||
- 流程: 搜索真实新闻 → AI关键词过滤 → 近2天筛选 → DeepSeek整理格式 → 入库发布
|
||
- **严禁让DeepSeek直接生成新闻内容**(会编造假新闻),必须基于真实新闻素材整理
|
||
|
||
## 踩坑记录
|
||
- Next.js 14不支持useActionState,登录页用原生表单POST
|
||
- Prisma MariaDB adapter需要连接字符串方式初始化
|
||
- 图片域名需在next.config.mjs中配置remotePatterns
|
||
- 热重载后需清除.next缓存: 删除.next目录后重启
|
||
- Chart.js组件需用dynamic import + ssr: false,不支持服务端渲染
|
||
- Prisma 7.8需通过PrismaMariaDb适配器初始化,不能直接new PrismaClient()
|
||
- 服务器环境SSL证书问题: 运行脚本需设置$env:NODE_TLS_REJECT_UNAUTHORIZED="0"
|
||
- **crontab env 隔离**: 本项目已迁移到容器内 supercronic 调度,不再依赖主机 crontab
|
||
- **Supercronic 环境变量**: entrypoint-cron.sh 中 `set -a; . /app/.env; set +a` 注入环境变量到 supercronic 子进程
|
||
- **Prisma 7 datasource.url**: 必须放在 `prisma.config.ts` 中,不能在 `schema.prisma` 的 datasource 块里写 `url`
|
||
- **Docker build 期 Next.js 模块求值**: server page 和 API route 在 build 时会被求值,如果依赖 env 变量(如 DATABASE_URL、API_KEY),需加 `export const dynamic = "force-dynamic"` 或懒加载
|
||
- **Docker 多阶段构建**: deps → builder → runner,利用 layer cache 加速重复构建
|
||
|
||
### 6. 安全原则
|
||
- 敏感信息(密钥、密码、Token)必须使用环境变量,禁止硬编码
|
||
- `.env` 文件已被加入 `.gitignore`,仅 `.env.example` 模板可提交
|
||
- HTTP 响应必须包含安全头:CSP、HSTS、X-Content-Type-Options、X-Frame-Options
|
||
- CSP 的 `script-src` 必须包含 `'unsafe-inline'`(Next.js App Router 水合依赖内联 `self.__next_f` 脚本),禁止 `'unsafe-eval'`;详见 workspace 规则 7.1
|
||
- 文件上传/下载必须限制大小(最大 5MB)和类型,SVG 内容需消毒 script/iframe/on-event 标签
|
||
- Logo 文件名使用 SHA256 哈希(不使用 MD5)
|
||
- VIP 用户不能访问管理后台(/admin/* 和 /api/admin/*)
|
||
- **后台写操作 API 必须使用 requireAdmin 中间件**(全部 25 个 POST 接口已验证)
|
||
- **数据库外键回退值禁止硬编码**:凡涉及 FK 字段(如 categoryId)必须先查库取有效 ID,再做回退(参考 `category.findFirst()` 模式),禁止用 `|| 1` 等魔法数字
|
||
- **批量写操作必须限制数量上限**:工具/技能导入 max(100),新闻导入 max(50),批量发布 max(500)
|
||
|
||
### 8. Knowledge Graph Memory 同步规则
|
||
- **每次代码变更后,必须同步更新 Knowledge Graph Memory**:当修改了项目代码(新增/删除/重构功能、修改数据模型、新增API、调整定时任务、修改Bot角色等),必须将变更内容同步写入 Knowledge Graph Memory
|
||
- **同步范围**:
|
||
- 新增/修改/删除数据模型 → 更新 `数据模型-核心` 或 `数据模型-Bot系统` 实体
|
||
- 新增/修改/删除 API 端点 → 更新对应 `API-*` 实体
|
||
- 新增/修改/删除定时任务 → 更新对应 `ScheduledTask` 实体
|
||
- 修改 Bot 角色配置(bot-characters.json) → 更新对应 `BotCharacter` 实体
|
||
- 新增/修改/删除论坛板块 → 更新对应 `ForumCategory` 实体
|
||
- 修改项目架构/技术栈/部署配置 → 更新 `追光AI` 或对应 `Module` 实体
|
||
- 新增/修改实体间关系 → 更新 Knowledge Graph 关系
|
||
- **同步时机**:在代码修改完成并通过检查后、提交代码前执行同步
|
||
- **图谱存储**:`.trae/knowledge_graph.jsonl`(MCP 源文件,JSONL,一行一实体/关系);`.trae/knowledge_graph.json` 为渲染版(`project` / `version` / `updated_at` / `entities` / `relations`)
|
||
- **MCP 配置**:`.trae/mcp.json` 注册 `Knowledge Graph Memory` 服务(`npx -y @itseasy21/mcp-knowledge-graph`,`MEMORY_FILE_PATH=.trae/knowledge_graph.jsonl`)
|
||
- **同步方法**:优先使用 `create_entities` / `add_observations` / `update_entities` / `create_relations` / `delete_entities` 等工具;若 MCP 未挂载,直接维护 `.trae/knowledge_graph.jsonl`
|
||
- **查询优先**:在开始任何开发任务前,先通过 `search_nodes` / `open_nodes` 查询图谱,利用已有知识加速开发
|
||
|
||
### 7. 可靠性原则
|
||
- 所有外部 API 调用(GitHub、DeepSeek 等)必须设置超时和重试
|
||
- OpenAI/DeepSeek 客户端配置:`timeout: 120000`, `maxRetries: 2`
|
||
- Octokit 配置:`request.timeout: 30000`,配合 withRetry 指数退避重试
|
||
- 定时脚本启动时必须验证必需环境变量(DEEPSEEK_API_KEY、DATABASE_URL)
|
||
- DeepSeek 模型名使用环境变量 `DEEPSEEK_MODEL`(默认 `deepseek-v4-pro`)
|
||
- OAuth 用户创建需处理 P2002 唯一约束冲突竞态 |