Files
zhuiguang-ai/.trae/specs/modules/07-lib-and-scripts.md
T

9.8 KiB
Raw Blame History

工具库与脚本模块

工具库 (src/lib/)

prisma.ts - 数据库客户端

  • Prisma单例模式,防止开发环境热重载创建多实例
  • 使用PrismaMariaDb adapter
  • 连接池配置(connection_limit=20, pool_timeout=30)
  • 日志: 开发环境warn/error,生产环境error
  • 环境变量校验: DATABASE_URL 未设置时抛出明确错误(移除硬编码默认连接串)

auth.ts - 认证配置

  • NextAuth配置导出
  • Credentials Provider(用户邮箱密码)
  • GitHub OAuth Provider
  • JWT策略
  • 登录频率限制(7次/分钟)
  • 导出GET/POST handler

admin-auth.ts - 管理员API认证

  • 导出 getAdminSession() — 获取当前会话(带缓存)
  • 导出 requireAdmin() — 管理员权限验证中间件
  • 导出 requirePermission(key) — 细粒度权限点校验
  • 导出 getAllUserPermissions() — 获取当前用户全部权限
  • 导出 getUserPermissionKeys(userId) — 获取用户权限键集合
  • 验证session中角色和权限
  • 返回401/403错误响应

utils.ts - 工具函数

  • cn(...inputs) — 合并clsx + tailwind-merge的className工具
  • extractJSON(str) — JSON提取工具,支持markdown代码块包裹、花括号/方括号容错

validation.ts - 数据验证

  • Zod验证schemas
  • 包含: registerSchema, loginSchema, paginationSchema, toolImportSchema(max(100)), skillImportSchema(max(100)), newsImportSchema(max(50)), checkTypeSchema(max(50)), profileUpdateSchema, favoriteSchema, historySchema, taskRunSchema, roleCreateSchema, categoryCreateSchema, skillCategoryCreateSchema, systemConfigUpdateSchema
  • 批量导入数组均有数量上限,防止一次请求导入过多数据

deepseek.ts - DeepSeek评测生成

  • 依赖: openai (兼容OpenAI接口)
  • 认证: process.env.DEEPSEEK_API_KEY
  • baseURL: https://api.deepseek.com/v1
  • 模型: 环境变量 DEEPSEEK_MODEL(默认 deepseek-v4-pro)
  • 客户端配置: timeout: 120000, maxRetries: 2
  • generateReview(repoName, description, stars, license, readme): 调用DeepSeek生成五维评测
  • 综合分校验: 自动计算五维均分,偏差>0.3时修正
  • JSON提取: 兼容markdown代码块包裹的响应

github.ts - GitHub数据采集

  • 依赖: octokit
  • 认证: process.env.GITHUB_TOKEN (推荐设置,提升限流60→5000次/小时)
  • Octokit配置: request.timeout: 30000
  • withRetry: 指数退避重试(最多3次),403/404/422 不重试直接抛
  • searchHotRepos(query, minStars, maxResults): 搜索热门仓库,按Star降序(带重试)
  • getRepoReadme(owner, repo): 获取仓库README内容(base64解码)(带重试+错误日志)
  • GitHubRepo 接口: id, full_name, html_url, description, stargazers_count, forks_count, language, license, topics, updated_at, readme

logo-fetcher.ts - Logo抓取引擎

  • 导出 fetchLogo(websiteUrl, html?): Promise<string> — 返回Logo URL
  • 导出 fetchLogoWithMethod(websiteUrl, html?): Promise<LogoFetchResult> — 返回 {url, method}
  • 10种抓取策略按优先级执行
  • 支持从SystemConfig读取配置
  • 每种成功方法返回中文名称
  • 所有 catch 块均添加 console.warn 日志(9处)

logo-storage.ts - Logo本地存储

  • 导出 downloadLogo(url, filename): Promise<string>
  • 下载远程Logo到 /public/logos/ 目录
  • 返回本地路径如 /logos/filename.png
  • 安全: 最大文件大小 5MB
  • 安全: SVG 内容自动消毒 script/iframe/on-event 标签
  • 哈希算法: 使用 SHA256 生成文件名(不再使用 MD5)

rate-limit.ts - 频率限制

  • rateLimit(ip, maxRequests, windowMs) — IP频率限制
  • 内存存储(Map)
  • 默认: 10次/分钟
  • 自动清理: 每5分钟自动清理过期IP记录,防止内存无限增长

use-permission.ts - 前端权限Hook

  • 客户端Hook
  • 获取当前用户权限
  • 提供 can(key), canAny(keys), canAll(keys) 方法

脚本 (scripts/)

定时任务脚本(6个 + 1个日报 + 1个新闻推社区,均含TaskLog记录)

task1-discover-tools.mjs — Task1 发现AI工具

  • 每天06:00由Crontab触发
  • 从36kr/IT之家/开源中国RSS抓取新闻,调用DeepSeek提取AI工具信息
  • 去重后入库PendingTool,含checkWebsiteOk/checkLogoOk等巡检结果
  • 结果写入TaskLog(taskKey: task1-discover-tools)

task3-check-tools.mjs — Task3 工具巡检

  • 每天03:00由Crontab触发
  • 检查所有已发布Tool网站可访问性+Logo有效性,更新websiteOk/logoOk字段
  • 对PendingTool逐一检查,四项检查全部通过则自动发布为正式Tool
  • FK回退: categoryId为NULL时动态取数据库第一个有效分类(不再硬编码 || 1)
  • 结果写入TaskLog(taskKey: task3-check-tools),含websiteFails/logoFails/autoPublished统计

task4 daily-discover.mjs — Task4 发现AI技能

  • 每天05:00由Crontab触发
  • GitHub搜索AI相关项目(stars≥1000,日上限30)
  • DeepSeek预评测后入库PendingSkill(不是直接创建Skill)
  • 去重检查: skill表 + pendingSkill表
  • 仓库内容质量过滤(isValidAIProject): 排除文档/教程/面试题/书单类Repo
  • 结果写入TaskLog(taskKey: task4-discover-skills),含discovered/skipped/reviewed/failed统计

task5-update-stars.mjs — Task5 更新技能星值

  • 每天01:00由Crontab触发
  • 查询所有sourceUrl含github.com的Skill
  • 通过Octokit API获取最新stargazers_count
  • 更新githubStars/starsChangeDay/starsChangeWeek/starsChangeMonth
  • 维护githubStarsHistory数组(保留最近90天)
  • 结果写入TaskLog(taskKey: task5-update-stars),含updated/failed/skipped统计

task6-review-hot.mjs — Task6 评测热门技能

  • 每天04:00由Crontab触发
  • 查找2个已发布但无SkillReview的最热门GitHub技能(按githubStars/viewCount排序)
  • 获取GitHub README,调用DeepSeek API生成五维评测
  • 创建SkillReview(status: PUBLISHED),更新Skill.lastReviewedAt
  • 结果写入TaskLog(taskKey: task6-review-hot),含reviewed/failed统计

daily-news.mjs — AI日报生成

  • 每天07:30由Crontab触发
  • 多源搜索: 36kr RSS + IT之家 RSS + 开源中国 RSS + HackerNews API + Google News RSS
  • 新闻过滤: 发布日期近2天内 + AI关键词匹配
  • DeepSeek整理格式生成中文日报(标题+摘要+条目)
  • 入库DailyReport表
  • 结果写入TaskLog(taskKey: daily-news),含reportId/itemCount/title统计

task7-news-to-community.mjs — Task7 新闻推社区

  • 每天08:00由Crontab触发
  • 查询今日(或昨天)已发布日报 → 按新闻category映射到社区板块
  • 映射规则: product→ai-tools / business→ai-news / model→tech / opensource→tech / policy→ai-news / insight→discuss
  • 以admin用户身份创建ForumTopic,去重(按标题),更新板块topicCount
  • 结果写入TaskLog(taskKey: task7-news-to-community),含created/skipped统计

seed-task-configs.mjs — 任务配置种子数据

  • 一次性运行(幂等,创建或更新)
  • 初始化7个TaskConfig记录(task1/3/4/5/6/7 + daily-news)
  • 含默认cronExpr、enabled=true、description

其他脚本

auto-review.mjs (自动化评测脚本 — 已被Task4/Task6替代)

  • 依赖: @prisma/client, @prisma/adapter-mariadb, octokit, openai
  • 流程: GitHub搜索→README获取→DeepSeek评测→Skill入库→SkillReview入库→日志记录
  • 配置: SEARCH_QUERIES(4个关键词), MIN_STARS(500→已被Task4提升为1000), DAILY_LIMIT(8→已有Task4用的30)
  • 运行: $env:NODE_TLS_REJECT_UNAUTHORIZED="0"; node scripts/auto-review.mjs

publish-reviews.mjs (发布评测脚本)

  • 将DRAFT状态SkillReview改为PUBLISHED
  • 将对应draft状态Skill改为published
  • 注: Task6-review-hot.mjs 创建的SkillReview直接为PUBLISHED,无需此脚本

generate-review-content.mjs (生成评测内容)

  • 调用DeepSeek生成评测长文、视频脚本、社交卡片
  • 用于已评测技能的内容生成

organize-content.mjs (内容整理脚本)

  • 整理和归类内容

test-github.mjs (GitHub API测试)

  • 测试searchHotRepos和getRepoReadme功能
  • 运行: $env:NODE_TLS_REJECT_UNAUTHORIZED="0"; node -r dotenv/config scripts/test-github.mjs

test-deepseek.mjs (DeepSeek API测试)

  • 测试generateReview功能,使用langflow作为测试用例
  • 运行: $env:NODE_TLS_REJECT_UNAUTHORIZED="0"; node scripts/test-deepseek.mjs

test-content-generation.mjs (内容生成测试)

  • 测试评测内容生成管线

debug-json.mjs (JSON解析调试)

  • 调试JSON解析逻辑

delete-drafts.mjs (删除草稿)

  • 批量删除草稿数据

cleanup-non-ai.mjs (清理非AI项目)

  • 清理误入库的非AI技能数据
  • 使用isValidAIProject过滤

db-status.mjs (数据库状态)

  • 检查数据库连接和数据状态

seed-permissions.mjs (权限种子数据)

  • 初始化全部权限点+角色
  • 幂等运行

migrate-logos.mjs (Logo迁移)

  • 迁移Logo到本地存储

运维脚本

restart.ps1 - 服务重启

  • PowerShell脚本
  • 扫描8301-8310端口
  • 杀死占用进程
  • 执行 npm run dev 启动服务(端口8301)
  • 运行: pwsh -ExecutionPolicy Bypass -File restart.ps1

temp_clear.mjs - 临时清理

  • 清空pending_tools表

cron脚本 (shell)

  • cron-wrapper.sh — 定时任务统一执行入口,自动 source .env + set -a/set +a 加载环境变量,创建日志目录,记录执行结果
  • install-cron.sh — 一键安装/更新 crontab(7个任务+日报+新闻推社区,全部通过wrapper执行)
  • fix-db-url.sh — 旧版数据库URL修复脚本(已被 fix-db-url.cjs 取代)

lib/retry.mjs

  • 重试工具函数

修复/诊断脚本

  • fix-db-url.cjs — 批量修复所有 .mjs 脚本的 mysql:// → mariadb:// 协议兼容(PrismaMariaDb adapter 要求)
  • fix-ts-types.cjs — 批量移除 .mjs 文件中的 TypeScript 类型注解(.mjs 不支持 TS 语法)
  • check-categories.cjs — 检查数据库社区板块分类,输出所有 ForumCategory 的 id/name/slug