Files
rainblogweb/AGENTS.md
T

7.9 KiB
Raw Blame History

AGENTS.md

RainWeb 个人云平台(博客 + 论坛 + 密码管理器 + 管理面板聚合)。Node.js 22+(推荐 22 LTS)、CommonJS、Express 4、better-sqlite3(原生 SQLite)。前端 React + Vite + React Router(前台原生样式 Material Design 3,后台 MUI 独立应用)。无测试、无 lint——前端改动进 frontend/src/,构建产物 public/dist/gitignored)由 server 静态服务,部署必须 npm run build

常用命令

npm start            # 生产:node server.jsserve 构建产物 + /api
npm run dev          # 开发:vite dev server5173/api 与 /uploads 代理到 3101
npm run build        # 构建 React 前端 → public/dist/index.html + admin.html + assets
npm run preview      # 预览构建产物
node cli.js <cmd>    # status | health | db-check | start | stop | restart | port [N] | password | captcha | config | backup | upgrade
  • 端口:.env.jsongitignored{"port": N} 或环境变量 PORT,默认 3001vite 代理目标硬编码 3101vite.config.js),后端端口改了就同步改。
  • CLIstatushealthdb-checkconfigbackup list 支持 --jsonhealth/db-check 检查失败返回非 0。backup prune 必须明确 --keep N,默认只预览,只有 --yes 才删除;backup restore <file> 必须服务停止并带 --yes,不会默认覆盖。
  • CLI 的 start/stop/restart 只操作经过 cwd 与命令行双重校验、确认属于本项目 server.js 的 PID,停止会先优雅等待。upgrade 仅供自托管机器本地执行:升级前备份,要求 git 工作区干净,执行 git pull --ff-onlynpm installnpm run build,服务原本运行时重启并健康检查;失败返回非 0。
  • CLI 密码命令默认交互输入;config 对密码、secret、token、JWT、私钥和 API key 等敏感配置统一脱敏。验证码参数需使用受支持的类型和值。
  • 验证方式:后端改动启动后 curl 接口;前端改动 npm run dev 热更新,或 npm run build 后刷新验证(需强刷一次,见下)。
  • 部署后浏览器必须拿新 HTMLserveIndex 响应带 Cache-Control: no-store;构建产物 assets 文件名带 hash,经 /assets 挂载长期缓存(immutable)。若用户白屏且 console 报 "MIME type text/html",先查是否 npm run build 缺失/旧产物。
  • 首次启动自动建库播种:管理员 admin / admin123,并写入示例博文/论坛帖子;/setup.html 初始化向导(POST /api/setup/completesetup_complete 门禁,非 adminOnly——新装无 token)。

数据层(db.js

  • better-sqlite3 是原生 SQLitedata/rainweb.db 单文件持久化,写操作经事务落盘。CLI 与 server 并发写库会等待(busy_timeout 5s)而非互相覆盖,但建议不要同时执行写操作。
  • 建表在 initTables();列迁移用 try/catch 包裹 ALTER TABLE ... ADD COLUMN(幂等、静默失败)确保列存在。新增列必须沿用此模式,否则旧库会崩。版本化迁移在 migrateSchema()PRAGMA user_version 记录 schema 版本,migrations 数组按 version 升序执行(current < m.version 才运行并推进版本号)——新迁移写进 migrations 数组,不要散落 try/catch
  • 站点设置存 site_settingskey/value),通过 db.getSetting / setSetting 读写。
  • cli.js 与 server.js 统一使用 db.js 的 data/rainweb.db;旧版 data.db 已由 server.js 首次启动时迁移为 data/rainweb.db(旧文件改名 data.db.bak)。

路由(server.js

  • 集中挂载所有 /api/*auth、admin-links、announcements、forum、blog、passwords、settings、email、profile、captcha、upload、setup、proxy、import)。新路由必须在此挂载——后面有 SPA catch-all:非 /api/ 一律回 dist/index.html。
  • 挂载顺序关键serveIndex('/')/assetsdist/assetsimmutable)→ static(public) → /uploads/api/*/admin*dist/admin.html)→ SSR 区(/blog/:id 等)→ catch-all。新路由注意别被 catch-all 吞掉。
  • middleware/auth.jsBearer JWTSECRET = process.env.JWT_SECRET无硬编码回退——server.js 启动时若 .env.jsonjwt_secret 则随机生成写入并设置环境变量);adminOnly 会查库复查角色(用户被删/降权立即失效)。
  • routes/setup.js/completesetup_complete 门禁('1' 后 403),新密码禁止等于默认 admin123
  • routes/proxy.js:面板嵌入代理——支持 Authorization header 或 ?token= queryiframe 无法带 header);有内网地址拦截(SSRF)。
  • 验证码:内置 SVG + reCAPTCHA/Turnstile 第三方,服务端统一 resolveCaptcha 校验(builtin 走 proof JWT,第三方走 siteverify)。

前端(React + Vite

  • 源码在 frontend/src/main.jsx(前台入口)、src/App.jsx(前台布局 Layout + 路由表)、src/pages/(前台页面)、src/components/Layout/MarkdownRenderer/CaptchaModal/MusicEmbed/BlogSidebar)、src/admin/后台独立应用 MUImain.jsx + AdminLayout + pages/)、src/api/(按模块封装的 fetch 层,client.js 管 token)、src/lib/utils.jssrc/theme.jsx
  • 前后台是两个独立入口(Vite 多入口),仅通过整页跳转连接:前台导航「管理后台」=<a href="/admin">(后台路由 basename /admin)。
  • 路由保持 v1 的 .html 后缀路径(/blog.html/forum.html 等),SPA fallback 已支持,链接不用改。
  • frontend/index.html${site_name} / ${site_description} / ${site_favicon} 占位符,构建后由 server.js serveIndex 按 site_settings 运行时替换(务必保留这 3 个占位符)。
  • 主题:data-theme="dark" 属性在 <html> 上(public/css/style.css[data-theme="dark"] 选择器),非 .dark 类,非 prefers-color-scheme。切换逻辑在 src/theme.jsx
  • 主题颜色:frontend/src/themeTokens.js 是前后台共享的 Token 派生入口;前台通过 applyThemeTokens 写入 CSS 变量,后台 admin/theme.js 通过 buildThemeTokens 生成 MUI palette。主题设置保存后使用 rainweb:theme-update 事件和 localStorage storage 事件同步;颜色、玻璃透明度和主题策略由 routes/settings.js 校验。
  • 构建:npm run buildpublic/dist/gitignored,不入库)。生产部署必须构建,否则页面 500/白屏。
  • 博文/帖子内容中的 [image:文件名] / [file:文件名] 标签:前台由 MarkdownRenderermarked + DOMPurify 净化)、SEO 页由 ssr.js 渲染为 /uploads/ 链接。所有 markdown 渲染必须过 DOMPurify
  • 登录态:token 存 localStoragekey token),变更通过 authchange 事件通知 Layout 刷新(api/client.jsnotifyAuthChange)。

SSR 与 SEO

  • ssr.js/blog/:id/forum/:id/sitemap.xmlrobots.txt 的域名取自 site_url 设置)。SSR 页引用 /css/style.csspublic/css 保留,勿删)。
  • 已发布博文(published=1)才会 SSR 渲染,未发布返回 404。

版本与更新

  • 版本号在根目录 VERSION 文件,与 package.json 的 version 需同步。
  • Web 更新接口已移除P0 删除 /api/update/check/api/update/run,无 RCE 面)。升级只走自托管机器本地的 cli.js upgrade:升级前备份、检查干净工作区、git pull --ff-only(本地 origingit.rainnya.asia 镜像)+ npm install + npm run build + 服务重启/健康检查。
  • 上传附件在 uploads/gitignored,头像在 uploads/avatars/,白名单扩展名),壁纸在 public/wallpaper/(仅 .gitkeep 入库)。

约定

  • UI 文案、代码注释、commit message 均为中文,保持一致。
  • 不要提交:node_modules/data/*uploads/*.env.jsonserver.pidreleases/public/dist/