| 内容 | 位置 | 是否上传 GitHub |
|---|---|---|
| 前端代码 | app/ |
✅ |
| 后端代码 | server/ |
✅ |
| 公开文档 | docs/、根目录 *.md |
✅ |
| 密钥/证书 | local/keys/、local/wg-*.conf |
❌ |
| 用户数据与分析 | local/my_data/、local/analysis/、local/console/ |
❌ |
| 开发日志 | local/log.md |
❌ |
| 版本快照 | local/Version/ |
❌ |
| 历史备份 bundle | local/*.bundle |
❌ |
| 环境真实值对照(域名 / IP / 部署根 / 服务名) | local/ENV.md |
❌ |
| 部署参数(SSH 主机 / 密钥 / 远端目录 / 服务名) | local/stage.env.ps1 |
❌ |
铁律:真实服务器地址、密钥、用户数据、VPN 配置一律只放 local/(已被 .gitignore 整体排除)。部署文档只用占位符。
公开文档统一占位符:{DOMAIN}/{BETA_HOST} 域名、{HK_IP} 服务器 IP、{HOST_ROOT} 部署父目录、{PROD_ROOT}/{BETA_ROOT} 部署根、{BACKUP_DIR} 备份目录、{SSH_USER} 服务器用户;
提交前对改动文件做敏感词扫描(真实域名 / IP / 密钥模式不得出现在跟踪文件中)。
CI 另有 privacy-guard job(.github/workflows/ci.yml)硬性拦截真实基础设施痕迹(服务器 IP / 私钥文件名 / 部署根路径 / 真实微信 AppID),命中即构建失败。
模式清单:
.github/privacy-banned.txt——只放模式、一行一条,文件内不得写注释或空行 (git grep -f会把注释行也当成模式,导致命中一切)。job 扫描时排除该文件自身, 且ci.yml内不得出现任何真实值字面量(模式用字符类写法,如/home/[q]bao),否则 job 会命中自己而恒失败。 新增/修改模式后本地自测(期望:无输出、退出码 1):git grep -n -E -f .github/privacy-banned.txt -- . ':(exclude).github/privacy-banned.txt'备份归档约定:任何含.env、私钥或数据库 dump 的备份一律放local/backups/(local/与backups/均已在 .gitignore)。 根级backups/曾因未忽略而濒临被git add -A提交(内含私钥与生产库 dump),勿在该位置存放任何备份。
Qbao/
├── app/ # 前端 SPA(Vue 3 + Vite + Pinia,源码 src/,构建产物 dist/,网页与桌面共用)
├── desktop/ # Electron 桌面壳(main/preload/updater,配置见 desktop/README)
├── server/ # Node.js 后端
│ ├── src/ # routes/ providers/ 中间件
│ ├── sql/ # 数据库迁移
│ ├── scripts/ # 诊断/迁移/引导脚本(run_migration.js、bootstrap_admin.js)
│ ├── deploy/ # systemd 单元 + prepare_dirs.sh + 部署说明
│ └── init.sql # 建库脚本
├── docs/ # 架构/部署/开发文档(公开)
├── tools/ # 一次性维护脚本(默认不上传,见 tools/README)
├── local/ # 【本地专用】隐私文件,永不上传
├── CHANGELOG.md # 公开版本日志
└── README.md
# 后端
cd server
npm install
cp .env.example .env # 配置数据库与 JWT_SECRET
npm run dev # node --watch,改动自动重启
# 前端(Vue 3 + Vite 工程)
cd app
npm install
npm run dev # Vite dev server(HMR,默认 http://localhost:5173)
npm run build # 构建 singlefile 产物到 app/dist/
# 桌面端(Electron)
cd desktop
npm install
npm run dev # 加载 Vite dev server;未启动时自动回退 app/dist/index.html
# 生产静态服务(Caddy 指向 app/dist/,配置见 docs/DEPLOY.md §4)
git commit -m "feat: 描述";发布提交带版本号:v3.25: ...。local/Version/Qbao_vX.Y.Z_<主题>/ 留存。CHANGELOG.md(公开摘要),开发细节写 local/log.md(不公开)。# 直接测 ECNU 出题(流式/非流式 + response_format 组合)
node server/scripts/diagnose_ai.js <api_key> [model]
# 端到端测 /api/v1/ai/generate(需本地后端跑在 3001)
node server/scripts/diagnose_api.js <api_key> [model] [jwt_token]
cd server && npx vitest run --pool=forks --poolOptions.forks.maxForks=2(fake pool 不依赖真实数据库;forks+maxForks=2 为稳定性参数,CI 已固定)。cd app && npx vitest run。cd app && npm run build(Vite singlefile → dist/index.html,含 CSP;CI 冒烟校验)。.github/workflows/ci.yml):gitleaks 密钥扫描 → 公开脱敏扫描(privacy-guard,§1 护栏)→ 后端语法+测试 → 前端构建冒烟+单测 → 双方 npm audit(高危告警不阻断)。.gitleaks.toml 已登记的形状(sk-test-key-* / test-secret-*)。写成 sk-live-…、another-secret-… 这类「看起来像真的」的字面量会让 gitleaks 当成泄漏 —— 该 job 在推送范围内扫描,所以只有代码提交会红、纯文档提交不会红,容易被误判成偶发。server 的 npm run lint 是 eslint .,覆盖 test/;vitest 注入的全局变量清单写在 server/eslint.config.cjs,用到新的全局(如 test/beforeAll)必须先登记,否则 no-undef 直接以 error 让 CI 变红(本地只跑 npx eslint src 是看不出来的)。server/sql/,命名 NNN_描述.sql(序号递增),SQL 保持幂等(IF NOT EXISTS)。cd server && node scripts/run_migration.js(自动应用未执行项并记入 schema_migrations)。node scripts/run_migration.js --list;旧库手工迁移过:先 node scripts/run_migration.js --mark-applied。新表/字段变更:在 server/sql/ 新增 migration_vX.Y.sql(幂等写法:ALTER TABLE ... IF NOT EXISTS 或先判断),新装环境按文件名顺序执行即可。