docs: 新增开发手册(流程/准则/技术红线/手册),修正 README 文档索引

- doc/DEVELOPMENT.md:开发流程与 git 工作流(所有 git 操作需确认)、
  环境说明、技术红线(绝不 kill-server/断开IP:5555 等)、本地开发手册、常见开发任务
- README 修正错误的 Windows 绝对路径为相对路径,目录结构补充 monitor.js
This commit is contained in:
2026-08-08 21:17:25 +08:00
parent 6d3cc10bca
commit e3afa5d36f
2 changed files with 228 additions and 6 deletions
+10 -6
View File
@@ -113,7 +113,8 @@ platform-tools/
│ └── login.html # 登录页 │ └── login.html # 登录页
│ │
├── static/admin/ ├── static/admin/
│ └── custom.css # 自定义样式 │ ├── custom.css # 自定义样式
│ └── monitor.js # 前端 JS(已从 monitor.html 拆分)
│ │
├── data/ # 运行时数据 ├── data/ # 运行时数据
│ ├── users.db # SQLite(用户/分组/任务/自定义动作/APK记录) │ ├── users.db # SQLite(用户/分组/任务/自定义动作/APK记录)
@@ -306,7 +307,7 @@ self.set_progress(done=5, total=80, unit="视频",
### 新增 App 任务 ### 新增 App 任务
参照 `tasks/douyin/` 结构,6 步即可新增一个 App 任务,详见 [doc/TASK_DEV.md](file:///d:/platform-tools/doc/TASK_DEV.md)。 参照 `tasks/douyin/` 结构,6 步即可新增一个 App 任务,详见 [doc/TASK_DEV.md](doc/TASK_DEV.md)。
--- ---
@@ -406,10 +407,13 @@ finally:
| 文档 | 内容 | | 文档 | 内容 |
|------|------| |------|------|
| [doc/TASK_DEV.md](file:///d:/platform-tools/doc/TASK_DEV.md) | 任务开发指南(新增 App 任务的完整模板和规范) | | [doc/DEVELOPMENT.md](doc/DEVELOPMENT.md) | **开发手册**:开发流程、git 工作流、技术红线、环境、本地开发 |
| [doc/ARCHITECTURE.md](file:///d:/platform-tools/doc/ARCHITECTURE.md) | 架构详解(分层设计、数据流、关键设计决策) | | [doc/TASK_DEV.md](doc/TASK_DEV.md) | 任务开发指南(新增 App 任务的完整模板和规范) |
| [doc/DEPLOY.md](file:///d:/platform-tools/doc/DEPLOY.md) | 部署指南(环境准备、STF 配置、生产部署) | | [doc/ARCHITECTURE.md](doc/ARCHITECTURE.md) | 架构详解(分层设计、数据流、关键设计决策) |
| [doc/API.md](file:///d:/platform-tools/doc/API.md) | API 接口文档(全部 HTTP 接口说明) | | [doc/DEPLOY.md](doc/DEPLOY.md) | 部署指南(环境准备、STF 配置、生产部署) |
| [doc/API.md](doc/API.md) | API 接口文档(全部 HTTP 接口说明) |
> **注意**:所有 git 操作(含 push 到 dev)都需负责人确认后才能执行,详见开发手册。修改 `core/`、`tasks/`、`templates/` 后需重启服务/强刷浏览器才生效。
--- ---
+218
View File
@@ -0,0 +1,218 @@
# 开发手册(DEVELOPMENT)
面向本项目开发者:开发流程、git 工作流、环境说明、技术红线、本地开发、常见开发任务。
---
## 1. 开发流程与 git 工作流
### 1.1 分支策略
| 分支 | 用途 |
|------|------|
| `dev` | **开发分支**,所有新功能/修复都在这里开发 |
| `main` | **生产分支**(主分支),只放已确认的稳定版本 |
生产环境 = STF 主机 `192.168.20.220` 的 `/mnt/data/openstf/auto_control`(python-app 容器运行 `web_server.py`)。
### 1.2 git 操作铁律(重要)
**所有 git 操作都必须先经项目负责人明确确认后才能执行**,包括但不限于:
- `commit` / `push`(**即使 push 到 dev 也要确认**)
- `merge`(dev → main)
- `revert` / `checkout` / `reset` / `branch -D` 等
**标准流程:**
```
1. 在 dev 分支开发、本地测试
2. 完成改动 → 把改动清单 + 建议 commit 信息 列给负责人
3. 负责人确认 → 才能 commit + push dev
4. 需要发布 → 负责人确认后再合并到 main
5. 部署生产 → 负责人明确指示后才 pull 到 220
```
> 不允许"开发完顺手就 commit/push"。即使是一次性小改动,也要先确认。
---
## 2. 环境说明
| 环境 | 位置 | 说明 |
|------|------|------|
| 开发机 | 本机(192.168.20.57) | `.venv` + 本地运行 `web_server.py` |
| 生产机 | STF 主机 220 的 `auto_control` | python-app 容器,`network_mode: host` |
| STF 服务 | `192.168.20.220:7100` | 设备农场(REST API) |
| 设备 | Tailscale `100.100.10.x:5555` | 5 台 Xiaomi,本机 `100.100.10.2` 在 tailnet 内 |
| uiautodev | 本机 `20242` | 元素抓取服务(web_server 自动拉起) |
### 2.1 adb key(关键)
- 本机 `~/.android/adbkey` 已换成 **STF adb 容器的 key**(5 台设备都信任)
- **不要随意更换 key**——设备会变 unauthorized 连不上
- 旧 key 备份在 `~/.android/adbkey.local.bak`
- 生产环境的容器也需要用这把 key(部署时处理)
### 2.2 设备连接方式
- 设备 serial 是 `IP:5555`(Tailscale 地址),**直连**优先
- STF 桥接(remoteConnect)在此环境**不可用**(隧道 adb key 认证失败,显示 unauthorized)
- 本机已在 tailnet 内,直连可靠且快(<1s)
---
## 3. 技术红线(开发限制)—— 违反会打断 STF,需人工恢复
这些是踩过坑后总结的,**任何修改都不能引入**。违反任何一条都会导致设备被 STF 误判离线、需人工处理:
1. **绝不 `adb kill-server`**
- 会断开所有设备的 adb transport,STF 对全网设备误判离线并触发重连
- 见 `core/adb_helper.py`
2. **绝不对 `IP:5555` 设备 `adb disconnect`**
- STF provider 共享该地址的 adb transport,disconnect 会断 STF
- 直连模式下 `release()` 不 disconnect
- 见 `core/device_worker.py` `STFDevice.release()`
3. **空闲设备扫描不主动 connect/disconnect**
- STF provider 内部通过 IP:5555 维持连接,外部 connect/disconnect 会让 STF 误判离线
- `_ForegroundScanner._scan_free` 对空闲设备直接返回"空闲",不碰 adb
- 见 `core/task_manager.py`
4. **adb key 保持为 STF 容器的 key**(见 2.1)
5. **直连优先,不引入 STF 桥接**(见 2.2)
### 3.1 其他开发限制
- **`web_server.py` 以 `debug=False` 运行,不热重载**:改 `core/`、`tasks/`、`templates/`、`static/` 后必须重启 web_server(前端 HTML 改完强刷浏览器)
- **任务参数放各自 `tasks/<app>/task.py` 顶部,不放 `config.py`**
- **生产环境(220)默认只读**:任何写操作(改文件/重启容器/部署)都必须先经负责人确认
- **数据库是 SQLite**(`data/users.db`,WAL 模式):运行时数据不提交 git
- **前端 JS 在 `static/admin/monitor.js`**(已从 HTML 拆分),HTML 里用 `<script src>` 引用
- **监控页/大列表已加分页**:100 台设备也只渲染 10 行/页,不要移除分页逻辑
- **任务批量触发已错峰**(`_START_STAGGER_SEC`):避免大量设备同时启动造成 adb/STF 风暴,不要移除
---
## 4. 本地开发手册
### 4.1 首次安装
```bash
# 用 Python 3.12 建 venv(README 推荐版本)
/opt/homebrew/bin/python3.12 -m venv .venv
.venv/bin/pip install -r requirements.txt
# macOS:adb 用系统自带的(bin/adb/adb 是被 gitignore 的符号链接)
ln -sf /opt/homebrew/bin/adb bin/adb/adb
# 确认 adb key(必须是 STF 容器的 key,否则设备连不上)
ls -la ~/.android/adbkey
```
### 4.2 启动
```bash
.venv/bin/python web_server.py
# 访问 http://localhost:18050/ 账号 admin/admin123
```
启动日志看到以下即成功:
```
[INFO] [core.worker] 心跳看门狗已启动
[INFO] [web] 管理后台: http://localhost:18050/ (admin/admin123)
[INFO] [web] 启动服务: http://localhost:18050/
```
### 4.3 测试
- **后端逻辑**:直接 `.venv/bin/python -c "..."` 调用(如 `tasks/`、`core/` 的函数)
- **前端 UI**:Playwright(系统 `python3` 已装),脚本示例见下
- **浏览器冒烟**:切 6 个 tab、开任务编辑器,确认无 JS 错误
```python
# Playwright 冒烟示例(python3 运行)
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
b = p.chromium.launch(headless=True)
pg = b.new_page()
pg.goto("http://127.0.0.1:18050/login")
pg.fill("input[name=username]", "admin")
pg.fill("input[name=password]", "admin123")
pg.click("input[type=submit], button[type=submit]")
pg.wait_for_load_state("networkidle")
# ... 检查各 tab、编辑器
b.close()
```
### 4.4 常用调试
- **看日志**:`logs/` 下 `core.log` / `task.log` / `web.log` / `action.log`(10MB 滚动,保留 5 份)
- **看设备/任务状态**:浏览器监控页,或 `GET /api/status`、`GET /api/health`
- **清理 STF 残留占用**:`python scripts/cleanup.py`(或前端"强制释放占用")
- **打包项目**:`python scripts/pack.py`
---
## 5. 常见开发任务
### 5.1 新增 App 任务
参照 `tasks/douyin/` 结构,详见 **[doc/TASK_DEV.md](TASK_DEV.md)**(6 步模板)。
```
tasks/<app>/
__init__.py # from . import task
task.py # DEFAULT_PARAMS + Worker + @register_task
actions/ # 专属操作(可选)
```
### 5.2 新增专属操作
在 `tasks/<app>/actions/` 建 `.py`,继承 `BaseAction` + `@register_action(ACTIONS)`,在 `__init__.py` import。
### 5.3 修改前端
| 文件 | 内容 |
|------|------|
| `templates/admin/monitor.html` | HTML 结构 + CSS + `<script src>` 引用 |
| `static/admin/monitor.js` | 全部前端 JS |
改完**强刷浏览器**(Cmd/Ctrl+Shift+R),必要时重启 web_server。
### 5.4 新增 API
在 `web_server.py` 加 Flask 路由,更新 **[doc/API.md](API.md)**。
### 5.5 新增数据库字段/表
- 模型改 `core/models.py`,首次建表用 `create_all()`
- **已有数据的老库**:在 `core/models.py` 的 `SCHEMA_MIGRATIONS` 里加迁移(版本号递增 + SQL)
---
## 6. 发布流程
详见 **[doc/DEPLOY.md](DEPLOY.md)**。摘要:
1. dev 开发测试完成
2. 负责人确认 → 合并到 main
3. 负责人确认 → 生产 220 `git pull`
4. 重启 python-app 容器生效
**发布前检查**:生产容器 adb key、依赖、数据库迁移。
---
## 7. 文档索引
| 文档 | 内容 |
|------|------|
| [README](../README.md) | 项目总览、快速上手 |
| **[DEVELOPMENT.md](DEVELOPMENT.md)** | 本文档:流程/准则/限制/手册 |
| [TASK_DEV.md](TASK_DEV.md) | 任务开发指南(新增 App 任务模板) |
| [ARCHITECTURE.md](ARCHITECTURE.md) | 架构详解(分层、数据流、设计决策) |
| [API.md](API.md) | 全部 HTTP 接口说明 |
| [DEPLOY.md](DEPLOY.md) | 部署指南(环境、生产、故障排查) |