Files
Neo-ZQYY/docs/deployment/LAUNCH-CHECKLIST.md

719 lines
26 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 微信小程序上线清单
> 最后更新2026-02-20
> 本文档合并自 ENV-MANAGEMENT.md、MINIPROGRAM-RELEASE.md、PRE-TEST-VERIFICATION.md 及补充建议。
> 按优先级从高到低排列,同时兼顾依赖关系(后续步骤依赖前置步骤完成)。
> 每项完成后在状态栏标注完成日期。
---
## 阅读指南
- 状态标记:待办 = 空框,已完成 = 日期
- 优先级P0 = 不做就上不了线P1 = 上线前必须做P2 = 可上线后迭代
- 依赖关系用箭头标注,如 "依赖 1.1" 表示需要先完成第 1.1 项
---
## 第一阶段基础设施P0 - 一切的前提)
所有后续步骤都建立在"三个环境能跑起来"的基础上。
### 1.1 服务器环境初始化
| 状态 | 项目 |
|------|------|
| 20260220 | 在 Windows Server 上创建目录结构 |
| 20260220 | 克隆仓库并切换分支 |
| | 配置环境变量文件 |
| | 安装 Python 依赖 |
| | 运行 `setup-server-git.py` 配置 Git 排除规则 |
| | 运行 `init-server-env.ps1` 删除排除文件 + 创建 export 目录 |
在 Windows Server 上执行:
```powershell
# 创建目录(日志统一放在 repo/export/ 下,随 .env 配置走)
New-Item -ItemType Directory -Path D:\NeoZQYY\test\repo -Force
New-Item -ItemType Directory -Path D:\NeoZQYY\prod\repo -Force
New-Item -ItemType Directory -Path D:\NeoZQYY\scripts -Force
```
> 旧方案在 repo 外单独建 `logs/` 目录,现已废弃。
> 所有运行时输出日志、JSON 导出、报告)统一放在 `repo/export/` 下,
> 路径由 `.env` 中的 `LOG_ROOT`、`EXPORT_ROOT` 等变量控制。
> 详见 [`docs/deployment/EXPORT-PATHS.md`](EXPORT-PATHS.md)。
```powershell
# 克隆仓库
cd D:\NeoZQYY\test
git clone https://git.langlangzhuoqiu.cn/root/Neo-ZQYY.git repo
cd repo
git checkout test
cd D:\NeoZQYY\prod
git clone https://git.langlangzhuoqiu.cn/root/Neo-ZQYY.git repo
cd repo
git checkout master
```
环境变量文件(不从 Git 同步,手动创建):
测试环境 `D:\NeoZQYY\test\repo\.env`
```env
DB_HOST=100.64.0.4
DB_PORT=5432
DB_USER=local-Python
DB_PASSWORD=<密码>
APP_DB_NAME=test_zqyy_app
ETL_DB_NAME=test_etl_feiqiu
PG_DSN=postgresql://<用户>:<密码>@<主机>:5432/test_etl_feiqiu
APP_DB_DSN=postgresql://<用户>:<密码>@<主机>:5432/test_zqyy_app
LOG_LEVEL=DEBUG
# 输出路径(统一放在 repo/export/ 下)
EXPORT_ROOT=D:/NeoZQYY/test/repo/export/ETL-Connectors/feiqiu/JSON
LOG_ROOT=D:/NeoZQYY/test/repo/export/ETL-Connectors/feiqiu/LOGS
FETCH_ROOT=D:/NeoZQYY/test/repo/export/ETL-Connectors/feiqiu/JSON
ETL_REPORT_ROOT=D:/NeoZQYY/test/repo/export/ETL-Connectors/feiqiu/REPORTS
SYSTEM_ANALYZE_ROOT=D:/NeoZQYY/test/repo/export/SYSTEM/REPORTS/dataflow_analysis
BACKEND_LOG_ROOT=D:/NeoZQYY/test/repo/export/BACKEND/LOGS
```
正式环境 `D:\NeoZQYY\prod\repo\.env`
```env
DB_HOST=100.64.0.4
DB_PORT=5432
DB_USER=prod-Python
DB_PASSWORD=<正式密码>
APP_DB_NAME=zqyy_app
ETL_DB_NAME=etl_feiqiu
PG_DSN=postgresql://<用户>:<密码>@<主机>:5432/etl_feiqiu
APP_DB_DSN=postgresql://<用户>:<密码>@<主机>:5432/zqyy_app
LOG_LEVEL=INFO
# 输出路径(统一放在 repo/export/ 下)
EXPORT_ROOT=D:/NeoZQYY/prod/repo/export/ETL-Connectors/feiqiu/JSON
LOG_ROOT=D:/NeoZQYY/prod/repo/export/ETL-Connectors/feiqiu/LOGS
FETCH_ROOT=D:/NeoZQYY/prod/repo/export/ETL-Connectors/feiqiu/JSON
ETL_REPORT_ROOT=D:/NeoZQYY/prod/repo/export/ETL-Connectors/feiqiu/REPORTS
SYSTEM_ANALYZE_ROOT=D:/NeoZQYY/prod/repo/export/SYSTEM/REPORTS/dataflow_analysis
BACKEND_LOG_ROOT=D:/NeoZQYY/prod/repo/export/BACKEND/LOGS
```
> 正式环境建议使用独立的数据库用户(如 `prod-Python`),权限最小化。
```powershell
# 安装依赖(每个环境各自执行)
cd D:\NeoZQYY\test\repo
uv sync --all-packages
cd D:\NeoZQYY\prod\repo
uv sync --all-packages
```
```powershell
# 配置服务器 Git 排除规则(每个环境各执行一次)
# 跳过 export/、.env 等开发机留存文件,避免占用服务器磁盘
cd D:\NeoZQYY\test\repo
python scripts/server/setup-server-git.py
cd D:\NeoZQYY\prod\repo
python scripts/server/setup-server-git.py
```
```powershell
# 删除排除文件 + 创建 export 目录树test + prod 一次搞定)
cd D:\NeoZQYY
.\test\repo\scripts\server\init-server-env.ps1
# 也可以只初始化单个环境
.\test\repo\scripts\server\init-server-env.ps1 -Envs test
.\prod\repo\scripts\server\init-server-env.ps1 -Envs prod
```
Git 排除方案说明(统一 .gitignore + skip-worktree
三个分支dev / test / master共用同一份 `.gitignore`(宽松版,允许 `.env``export/` 等留存文件提交)。
服务器上通过 `setup-server-git.py` 一次性配置,不需要每个分支维护不同的 `.gitignore`
工作原理:
1. 脚本将 `scripts/server/server-exclude.txt` 复制到 `.git/info/exclude`(本地排除,不影响仓库)
2. 对已 track 但服务器不需要的文件设置 `git update-index --skip-worktree`
3. 后续 `git pull` 不会还原这些文件,可安全删除释放磁盘空间
被排除的内容(完整列表见 `scripts/server/server-exclude.txt`
- `.env` / `.env.local` -- 服务器有自己的环境配置
- `export/` -- ETL 导出数据(仅开发机留存)
- `docs/` -- 全部文档部署、PRD、H5 原型、审计、架构等)
- `apps/miniprogram/` -- 小程序源码(服务器不编译小程序)
- `apps/admin-web/src/` -- 管理后台源码(保留 dist/
- `tests/``.hypothesis/` -- 测试相关
- `samples/``infra/` -- 示例数据和基础设施文档
- `scripts/ops/``scripts/audit/``scripts/migrate/` -- 开发用脚本
- `.kiro/` -- Kiro 配置
- 根目录截图(`*.png`)、`.code-workspace`
优点:
- merge 零冲突(三个分支 `.gitignore` 完全一致)
- 服务器首次 clone 后运行一次脚本即可,后续 `git pull` 正常工作
- 开发机的留存文件正常提交到 Git不受影响
环境总览:
| 环境 | 位置 | Git 分支 | 数据库 | 用途 |
|------|------|----------|--------|------|
| 开发 | 本机 `C:\NeoZQYY` | `dev` | `test_etl_feiqiu` / `test_zqyy_app` | 日常开发 |
| 测试 | 服务器 `D:\NeoZQYY\test\repo` | `test` | `test_etl_feiqiu` / `test_zqyy_app` | 集成测试 + 小程序体验版 |
| 正式 | 服务器 `D:\NeoZQYY\prod\repo` | `master` | `etl_feiqiu` / `zqyy_app` | 生产环境 + 小程序正式版 |
### 1.2 后端服务管理 - bat 脚本(依赖 1.1
| 状态 | 项目 |
|------|------|
| | 将 bat 脚本放到服务器 `D:\NeoZQYY\scripts\` |
| | 登录服务器手动运行对应脚本启动服务 |
> 后续将由监控系统(见 7.2)统一管理所有服务的启停和状态监控。
> 在监控系统上线之前,登录 Windows Server 手动双击 bat 脚本启动。
端口分配:
| 服务 | 测试环境 | 正式环境 |
|------|----------|----------|
| FastAPI 后端 | 8001 | 8000 |
启动脚本 `D:\NeoZQYY\scripts\start-test-api.bat`
```bat
@echo off
title NeoZQYY Test API (port 8001)
cd /d D:\NeoZQYY\test\repo\apps\backend
D:\NeoZQYY\test\repo\.venv\Scripts\uvicorn.exe app.main:app --host 0.0.0.0 --port 8001
pause
```
启动脚本 `D:\NeoZQYY\scripts\start-prod-api.bat`
```bat
@echo off
title NeoZQYY Prod API (port 8000)
cd /d D:\NeoZQYY\prod\repo\apps\backend
D:\NeoZQYY\prod\repo\.venv\Scripts\uvicorn.exe app.main:app --host 0.0.0.0 --port 8000
pause
```
一键全部启动 `D:\NeoZQYY\scripts\start-all.bat`
```bat
@echo off
echo 启动测试环境后端...
start "NeoZQYY Test API" cmd /c "D:\NeoZQYY\scripts\start-test-api.bat"
echo 启动正式环境后端...
start "NeoZQYY Prod API" cmd /c "D:\NeoZQYY\scripts\start-prod-api.bat"
echo 全部已启动。
pause
```
> 每个 bat 会打开一个独立的 cmd 窗口,窗口标题显示服务名称,方便识别。
> 关闭窗口即停止服务。服务器重启后需要重新手动运行。
### 1.3 跳板机 Nginx 反代(依赖 1.2
| 状态 | 项目 |
|------|------|
| 已完成 | 跳板机已配置好(用户确认) |
| 已完成 | Tailscale 内网已配置DB_HOST=100.64.0.4 |
| | 确认 Nginx 将 `api.langlangzhuoqiu.cn` 反代到 Tailscale IP:8000正式 |
| | 确认 Nginx 将测试环境反代到 Tailscale IP:8001如需区分域名 |
| | 确认 SSL 证书有效且自动续期 |
> 跳板机本身已配好,这里只需确认反代规则指向了正确的后端端口。
> 如果测试和正式共用 `api.langlangzhuoqiu.cn`,则体验版和正式版会打到同一个后端。
> 建议至少在初期区分:`test-api.langlangzhuoqiu.cn` 指向 8001`api.langlangzhuoqiu.cn` 指向 8000。
### 1.4 数据库备份方案(依赖 1.1
| 状态 | 项目 |
|------|------|
| | 编写 pg_dump 备份脚本 |
| | 配置 Windows 计划任务定时执行 |
| | 执行一次恢复演练验证备份可用 |
> 你的 Windows Server 是单点,正式库 `etl_feiqiu` 和 `zqyy_app` 丢了不可逆。
> 建议每天凌晨自动 pg_dump保留最近 7 天。备份文件可以同步到跳板机或其他位置做异地冗余。
示例备份脚本(放 `D:\NeoZQYY\scripts\backup-db.ps1`
```powershell
$date = Get-Date -Format "yyyy-MM-dd"
$backupDir = "D:\NeoZQYY\backups"
New-Item -ItemType Directory -Path $backupDir -Force
# 正式 ETL 库
pg_dump -h 100.64.0.4 -U prod-Python -d etl_feiqiu -F c -f "$backupDir\etl_feiqiu_$date.dump"
# 正式业务库
pg_dump -h 100.64.0.4 -U prod-Python -d zqyy_app -F c -f "$backupDir\zqyy_app_$date.dump"
# 清理 7 天前的备份
Get-ChildItem $backupDir -Filter "*.dump" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item
```
用 Windows 计划任务每天凌晨 3:00 执行此脚本。
---
## 第二阶段微信侧配置P0 - 小程序能跑的前提)
这些是微信平台的硬性要求,缺任何一项小程序都无法在真机上正常运行或通过审核。
### 2.1 合法域名 + HTTPS
| 状态 | 项目 |
|------|------|
| 已完成 | request 合法域名:`https://api.langlangzhuoqiu.cn` |
| 已完成 | socket 合法域名:`wss://socket.langlangzhuoqiu.cn` |
| 已完成 | uploadFile 合法域名:`https://file.langlangzhuoqiu.cn` |
| 已完成 | downloadFile 合法域名:`https://file.langlangzhuoqiu.cn` |
> 已在微信公众平台后台配置完成。
### 2.2 消息推送配置(依赖 1.2 + 1.3
| 状态 | 项目 |
|------|------|
| 已完成 | 后端接口 `GET/POST /api/wx/callback` 已实现(`wx_callback.py` |
| | 在 `apps/backend/.env.local` 中配置 `WX_CALLBACK_TOKEN` |
| | 服务器上部署最新代码并重启后端 |
| | 微信后台填写消息推送配置并提交验证 |
> 消息推送配置必须在服务器后端已启动、跳板机反代已就绪之后才能操作。
> 微信会向你的 URL 发 GET 请求验签,后端必须在线才能通过。
微信后台配置(开发 - 开发管理 - 消息推送):
| 字段 | 值 |
|------|------|
| URL | `https://api.langlangzhuoqiu.cn/api/wx/callback` |
| Token | `LLZQwx2026push`(和 .env.local 里一致,可自定义) |
| EncodingAESKey | 点"随机生成" |
| 消息加解密方式 | 先选"明文模式"(跑通后再切安全模式) |
| 数据格式 | JSON |
点"提交"后微信发 GET 验证。如果失败,最常见原因:
- 服务器后端未启动
- Nginx 反代未指向正确端口
- Token 两边不一致
### 2.3 隐私协议 / 用户隐私保护指引
| 状态 | 项目 |
|------|------|
| | 在微信后台填写用户隐私保护指引 |
操作路径:微信后台 - 设置 - 基本设置 - 服务内容声明 - 用户隐私保护指引。
需要声明你收集了哪些用户信息:
- 微信昵称、头像(如果用到 `wx.getUserProfile`
- 用户标识openid`wx.login` 必然涉及)
- 设备信息(如果用到 `wx.getSystemInfo`
> 2023 年 9 月起微信强制要求。不填写的话,调用 `wx.login` 等隐私相关 API 会直接报错。
> 即使你当前只用了 `wx.login`,也需要声明"用户标识"这一项。
### 2.4 小程序基本信息
| 状态 | 项目 |
|------|------|
| 已完成 | AppID 已配置:`wx7c07793d82732921` |
| | 确认小程序名称、图标、简介已填写完整 |
| | 确认小程序类目已选择(建议"工具 - 企业管理"或"生活服务" |
> 审核时会检查这些基本信息。类目选择需注意:部分类目需要上传营业执照等资质文件,提前确认。
### 2.5 体验成员配置
| 状态 | 项目 |
|------|------|
| | 在微信后台添加体验成员(成员管理 - 添加体验成员) |
> 体验版只有体验成员能扫码访问,最多 100 人。内部测试阶段必须配置。
---
## 第三阶段后端核心功能P0 - 上线的硬前提)
没有这些功能,小程序即使能打开也无法提供真实服务。
### 3.1 微信登录接口(依赖 2.2
| 状态 | 项目 |
|------|------|
| | 后端实现 `POST /api/auth/wechat_login` |
| | 在 `.env.local` 中配置 `WX_APP_ID``WX_APP_SECRET` |
| | 小程序端 `app.ts` 改造:`wx.login` 拿 code 后调后端换 JWT |
| | 后续请求统一带 Authorization header |
当前状态:
- 后端 JWT 框架已有(`app/auth/jwt.py`,签发/验证/刷新)
- 管理后台登录已实现(`POST /api/auth/login`
- 小程序端 `app.ts``wx.login` 只是 `console.log(res.code)`,未发给后端
需要实现的完整链路:
```
小程序 wx.login() 拿到 code
--> POST /api/auth/wechat_login { code: "xxx" }
--> 后端调微信 jscode2session 换 openid + session_key
--> 查 users 表,不存在则创建
--> 签发 JWTaccess_token + refresh_token
--> 小程序存储 token后续请求带上
```
> `WX_APP_SECRET` 从微信后台获取(开发 - 开发管理 - 开发设置 - AppSecret
> 这个值绝对不能出现在前端代码或 Git 仓库里,只放在服务器的 `.env.local` 中。
### 3.2 权限中间件(依赖 3.1
| 状态 | 项目 |
|------|------|
| | 实现权限中间件(基于 JWT 中的 site_id + role 校验) |
| | 需要鉴权的路由挂上 `Depends(get_current_user)` |
当前状态:
- RBAC 的 DDL 已定义roles / permissions / user_roles / role_permissions 表)
- `app/auth/dependencies.py``get_current_user` 但未实际使用
- `app/middleware/__init__.py` 为空,无鉴权逻辑
- 后端 API 目前全部裸奔,任何人可调用任何接口
> 这是安全底线。涉及多门店、多角色、财务数据的场景,没有权限校验等于公开数据库。
### 3.3 小程序业务页面(依赖 3.1
| 状态 | 项目 |
|------|------|
| 已完成 | MVP 全链路验证页面(`pages/mvp/mvp`,显示 "t91" |
| | 至少一个有实际功能的首页(审核要求) |
| | 清理调试代码(`console.log` 等) |
当前状态:
- 只有 mvp 测试页、默认 index 和 logs 页
- `app.ts` 里有 `console.log(res.code)` 调试输出
- 提交审核时需要有实际功能的页面,否则大概率被拒
> 小程序的 API 地址已通过 `utils/config.ts` 实现环境自动切换:
> develop开发版指向本机trial体验版和 release正式版指向线上域名。
### 3.4 密钥配置到后端
| 状态 | 项目 |
|------|------|
| 已完成 | `WX_CALLBACK_TOKEN` 已写入 `.env.local` |
| | `WX_APP_ID` 写入服务器 `.env.local` |
| | `WX_APP_SECRET` 写入服务器 `.env.local` |
| | 确认 `JWT_SECRET_KEY` 已配置(不要用默认值) |
> `.env.template` 中已有这些配置项的模板,复制到 `.env.local` 后填入实际值。
> 正式环境的 `JWT_SECRET_KEY` 必须是一个随机强密码,不能和测试环境相同。
---
## 第四阶段部署与发布流程P0 - 让代码流动起来)
### 4.1 日常部署流程
开发到测试:
```
1. 本机 dev 分支开发完成push 到远程
2. 本机合并 dev 到 testgit checkout test && git merge dev && git push
3. 服务器测试环境拉取cd D:\NeoZQYY\test\repo && git pull
4. 如有依赖变更uv sync --all-packages
5. 关闭测试环境后端窗口,重新运行 start-test-api.bat
6. 微信开发者工具上传体验版(指向测试环境 API
```
测试到正式:
```
1. 测试通过后,合并 test 到 mastergit checkout master && git merge test && git push
2. 服务器正式环境拉取cd D:\NeoZQYY\prod\repo && git pull
3. 如有依赖变更uv sync --all-packages
4. 关闭正式环境后端窗口,重新运行 start-prod-api.bat
5. 微信小程序提交审核 --> 发布
```
### 4.2 小程序版本与发布
版本类型:
| 版本 | 对应环境 | 谁能访问 | 用途 |
|------|----------|----------|------|
| 开发版 | 本机 dev | 开发者自己(微信开发者工具) | 日常开发调试 |
| 体验版 | 服务器 test | 体验成员(最多 100 人) | 内部测试 |
| 正式版 | 服务器 prod | 所有用户 | 线上运营 |
完整发布流水线:
```
本机开发(开发版)
| 微信开发者工具"上传"
v
体验版(指向测试环境 API
| 测试通过
v
微信后台"提交审核"
| 审核通过(通常 1-3 个工作日,快的几小时)
v
微信后台"发布"
v
正式版(指向正式环境 API
```
开发版操作:
1. 微信开发者工具打开 `apps/miniprogram/`
2. 勾选"详情 - 本地设置 - 不校验合法域名"(仅开发阶段)
3. 编译预览,确认功能正常
上传体验版:
1. 微信开发者工具点右上角"上传"
2. 填写版本号(如 `0.1.0`)和项目备注
3. 微信后台 - 开发管理 - 开发版本 - 点"选为体验版"
4. 体验版会生成二维码,扫码即可体验
提交审核:
1. 微信后台 - 开发管理 - 开发版本 - 点"提交审核"
2. 填写功能页面截图、类目、功能介绍
3. 如有登录功能,提供测试账号密码
4. 等待审核(预留至少一周缓冲期)
发布上线:
1. 审核通过后,微信后台 - 开发管理 - 审核版本 - 点"发布"
2. 可选全量发布或灰度发布(建议先 10% 观察)
版本号规范(语义化):
- `0.1.0` -- MVP 验证
- `0.2.0` -- 新增登录功能
- `0.2.1` -- 修复 bug
- `1.0.0` -- 正式上线第一版
### 4.3 紧急回滚
后端回滚:
```powershell
cd D:\NeoZQYY\prod\repo
git log --oneline -5 # 查看最近提交
git reset --hard <commit-id> # 回退到指定版本
# 关闭正式环境后端窗口,重新运行 start-prod-api.bat
```
小程序回滚:
1. 微信后台 - 开发管理 - 线上版本 - 点"版本回退"
2. 回退即时生效,用户下次打开加载旧版本
3. 注意:只能回退一个版本,不要连续发布多个有问题的版本
### 4.4 发布检查清单
每次发布前确认:
- [ ] API 地址指向正确环境
- [ ] 服务器后端已部署最新代码并重启
- [ ] 数据库迁移已执行(如有)
- [ ] 关键功能手动测试通过
- [ ] 无 console.log 调试信息残留
- [ ] 版本号已更新
- [ ] 备注中写明本次变更内容
---
## 第五阶段安全与审计P1 - 上线前必须做)
这些不会阻止小程序"能用",但不做会导致可预期的安全事故或管理问题。
### 5.1 用户申请/审核流
| 状态 | 项目 |
|------|------|
| | 创建 `user_application`DDL + 迁移脚本) |
| | 实现审核 API`POST /api/applications``POST /api/applications/{id}/approve` |
| | 状态机pending / approved / rejected / disabled |
> `users` 表 DDL 已有(`db/zqyy_app/schemas/init.sql`),但缺少申请表和审核接口。
### 5.2 审计日志
| 状态 | 项目 |
|------|------|
| | 创建 `audit_log` 表 |
| | 实现审计中间件(关键写操作自动记录) |
> 涉及工资/财务场景,"谁在何时改了什么"必须可追溯。
> 至少记录审批操作、xlsx 导入、口径裁决、工资重算。
### 5.3 后端结构化日志
| 状态 | 项目 |
|------|------|
| | 后端接入结构化日志(替代 uvicorn 默认日志) |
当前状态:
- ETL 有完整日志体系(`logging_utils.py`
- 后端仅 uvicorn 默认日志,排查问题困难
### 5.4 安全加固
| 状态 | 项目 |
|------|------|
| | 确认服务器防火墙只允许 Tailscale 网卡入站到 API 端口 |
| | 确认 PostgreSQL 只监听内网/本机,不对公网开放 |
| | 确认 pg_hba.conf 配置合理 |
| | 消息推送从明文模式切换到安全模式AES 加解密) |
---
## 第六阶段审核准备P1 - 提交审核前)
### 6.1 审核材料准备
| 状态 | 项目 |
|------|------|
| | 准备主要页面功能截图 |
| | 准备测试账号(如有登录功能) |
| | 确认类目资质文件(营业执照等,视类目要求) |
| | 撰写功能介绍文案 |
> 首次审核通常 1-3 个工作日,快的几小时。被拒后修改重新提交。
> 建议预留至少一周的审核缓冲期。
---
## 第七阶段可上线后迭代P2
这些可以在小程序上线后逐步补齐。
### 7.1 xlsx 导入/导出
| 状态 | 项目 |
|------|------|
| | 后端实现上传、解析、校验、落库、错误报告接口 |
> ETL 层已有 openpyxl 依赖,但后端无上传接口。
### 7.2 运维监控系统(将取代 bat 脚本手动管理)
| 状态 | 项目 |
|------|------|
| | 需求与 spec 编写 |
| | 后端采集器 + 监控 API |
| | 前端监控面板(管理后台新页面) |
| | 告警推送(企业微信机器人 webhook |
| | 上线后取代 bat 脚本,接管服务启停 |
规划方案BS 架构,集成到现有管理后台):
技术选型:
- 后端FastAPI 定时任务采集指标,写入 PostgreSQL `monitor` schema
- 前端:`apps/admin-web/` 新增 Monitor 页面Ant Design Charts 可视化
- 告警:企业微信机器人 webhook 推送
监控维度:
| 维度 | 数据来源 | 复杂度 |
|------|----------|--------|
| 服务器载荷CPU/内存/磁盘) | `psutil` 采集 | 低 |
| 服务状态(后端进程存活) | `/health` 探活 | 低 |
| 网络上下行 | `psutil.net_io_counters` | 低 |
| 数据库状态(连接数/慢查询/表大小) | `pg_stat_*` 系统视图 | 中 |
| ETL 连接器字段漂移检测 | ETL `meta` 层运行元数据 | 中 |
代码落点:
```
apps/backend/app/
routers/monitor.py # 监控数据 API
services/monitor_collector.py # 采集器(定时任务)
apps/admin-web/src/pages/
Monitor.tsx # 监控面板页面
db/zqyy_app/migrations/
YYYYMMDD_create_monitor_tables.sql
```
功能目标:
- 数据可视化:实时仪表盘 + 历史趋势图
- 告警分级:按信息紧急程度分 INFO / WARNING / CRITICAL
- 服务管理:上线后可通过面板启停服务,取代手动 bat 脚本
> 优先级 P2建议在小程序上线稳定后再启动开发。
> 到时候用一个 spec 来拆解需求和实现计划。
### 7.3 租户模型
| 状态 | 项目 |
|------|------|
| | tenant 层实现(当前单租户场景可暂缓) |
| | RLS Policy DDL 落库(当前 ETL 只读连接已设置 `app.current_site_id` |
### 7.4 ETL SDK 抽象
| 状态 | 项目 |
|------|------|
| | 将飞球 Connector 抽象为通用连接器基类 |
> 当前飞球 Connector 结构清晰,但未抽象为通用 SDK。多球房扩展时需要。
### 7.5 自动化测试
| 状态 | 项目 |
|------|------|
| | 后端 API 集成测试 |
| | 小程序端自动化测试 |
---
## 已完成项摘要
| 完成日期 | 项目 | 说明 |
|----------|------|------|
| 2026-02-19 | MVP 全链路验证 | 小程序 - FastAPI - PostgreSQL 通路已跑通,`GET /api/xcx-test` 返回 `{"ti": "t91"}` |
| 2026-02-19 | 后端 MVP 页面 | `pages/mvp/mvp` 已创建并注册为首页,从 API 读取数据并显示 |
| 2026-02-19 | 环境管理方案 | 服务器目录结构、Git 流程、bat 脚本服务管理方案已输出 |
| 2026-02-19 | PRE-TEST 验证报告 | 逐项对照 8 大板块标注完成度,已合并到本文档 |
| 2026-02-19 | 合法域名 + HTTPS | 微信后台已配置 request/socket/upload/download 合法域名 |
| 2026-02-19 | 消息推送后端接口 | `GET/POST /api/wx/callback` 已实现(`wx_callback.py`),支持验签和消息接收 |
| 2026-02-19 | 小程序环境配置 | `utils/config.ts` 已创建,根据运行环境自动切换 API 地址 |
| 2026-02-19 | 版本与发布流程文档 | 已合并到本文档第四阶段 |
| 已有 | JWT 认证框架 | `app/auth/jwt.py` 已实现签发/验证/刷新 |
| 已有 | 管理后台登录 | `POST /api/auth/login` 已实现 |
| 已有 | 健康检查 | `GET /health` 已实现 |
| 已有 | CORS 配置 | 已配置,支持环境变量覆盖 |
| 已有 | OpenAPI 文档 | `/docs`Swagger`/redoc` 已启用 |
| 已有 | 数据分层架构 | ODS/DWD/DWS/Core/Meta/App 六层 schema 已建立 |
| 已有 | Monorepo + Steering | 单仓库统一管理Steering 规则已配置 |
| 已有 | Git 三分支 | dev/test/master 已建立 |
| 已有 | RBAC DDL | roles/permissions/user_roles/role_permissions 表已定义 |
| 已有 | site_id 贯穿 | 所有业务表均有 site_id 字段 |
| 已有 | 跳板机 + Tailscale | 内外网分层已配置 |
---
## 数据库环境隔离速查
| 数据库 | 用途 | 备注 |
|--------|------|------|
| `test_etl_feiqiu` | 开发 + 测试 ETL 数据 | 可随时重建 |
| `test_zqyy_app` | 开发 + 测试业务数据 | 可随时重建 |
| `etl_feiqiu` | 正式 ETL 数据 | 需备份 |
| `zqyy_app` | 正式业务数据 | 需备份 |
---
## 风险提醒
| 风险 | 级别 | 当前缓解 | 是否充分 |
|------|------|----------|----------|
| 数据越权/串账 | P0 | site_id 已贯穿ETL 只读连接有 RLS | 后端 API 无权限中间件,需尽快补齐 |
| 财务口径不可追溯 | P0 | ETL 有 meta 层记录运行元数据 | 后端无 audit_log需补齐 |
| 单点故障 | P0 | 无 | 无备份/恢复方案,需尽快建立 |
| 密钥泄露 | P1 | .env 已 gitignore | AppSecret 需确认只在服务端 |
| ETL 扩展维护 | P1 | 飞球 Connector 结构清晰 | 未抽象为通用 SDK |
| 联调回归成本 | P2 | Steering + Hooks 已配置 | 缺自动化集成测试 |