docs: doc/ 全量同步 dev 现状——API 目录补全(AI 控制台/系统备份/自动发现等)、去 STF 过时口径、补 generic_steps 与配置键速查;确立「功能/配置改动须同步文档」红线

- doc/API.md:补方法/路径标题,权限分层修正,新增 AI 控制台(/api/agent/*)、系统备份(/api/system/backup/*)、设备自动发现(/api/devices/discovery/*)、tap_text/summary/health/devices-apps 等整节端点,去 STF 残留
- doc/TASK_DEV.md:STF 时代描述清理;新增 §2.10 generic_steps(18 节点与必填/嵌套/静默跳过语义)、§2.11 自定义动作与单步测试、/api/jobs 盲存校验语义、resolve_serials/抢占语义、模板构造函数签名修正
- doc/DEPLOY.md:数据备份改为推荐「系统→数据备份」功能并说明重启生效目录,端口表 STF7100→MCP8033,补 start.sh 生产链路与 MCP_PLATFORM_PASS 同步,故障排查去 STF
- doc/MCP.md:加「现状边界」(平台级任务 CRUD 未 MCP 化,规划见 AI_TASK_GEN §9),busy/平台会话说明,MCP_ALLOWED_SERIALS 语义纠正
- doc/MCP_DESIGN.md:加实现现状对照、错误码、独立容器改演进备选、里程碑状态、API 映射表按实现重写
- doc/ARCHITECTURE.md:Tab/子分栏/线程模型/数据表/蓝图表去 STF,补 device_discovery/agent/system_backup/经验巡检等
- doc/DEVELOPMENT.md:新增 §5.6「改动必须同步文档」红线、§2.3 配置键速查、蓝图化新增 API 流程、文档索引补登记
- doc/STF_REMOVAL.md:加历史记录状态横幅
- doc/AI_TASK_GEN.md:新增 AI 建任务设计稿(含 §9 需转 MCP 工具分层)
This commit is contained in:
2026-09-09 16:05:56 +08:00
parent 470c76221e
commit fd829a6063
9 changed files with 1121 additions and 196 deletions
+34 -15
View File
@@ -1,6 +1,6 @@
# 架构详解
本文面向想深入理解 `platform-tools` 内部设计的开发者。如果你只想使用,看 [README.md](file:///d:/platform-tools/README.md) 即可。
本文面向想深入理解 `auto_control` 内部设计的开发者。如果你只想使用,看 [README.md](../README.md) 即可。
---
@@ -45,7 +45,7 @@
│
▼
┌──────────────┐
│ data/users.db│ SQLite 持久化(用户/分组/任务/设备池/自定义动作/APK记录)
│ data/users.db│ SQLite 持久化(用户/分组/任务/设备池/待连接设备/自定义动作/APK记录/AI会话/经验库 + app_meta KV)
└──────────────┘
```
@@ -175,17 +175,23 @@ SQLAlchemy 模型,存于 `data/users.db`:
| 模型 | 表名 | 说明 |
|------|------|------|
| `User` | user | 后台用户(Flask-Login 认证,SHA256 密码;`is_admin` 管理员 + `perms` 业务权限位) |
| `User` | user | 后台用户(Flask-Login 认证,Werkzeug 哈希密码;`is_admin` 管理员 + `perms` 业务权限位) |
| `DeviceGroup` | device_group | 设备分组(serials 存 JSON) |
| `TaskJob` | task_job | 任务计划(target/params/schedule/retry 存 JSON) |
| `CustomAction` | custom_action | 自定义动作(步骤打包,steps 存 JSON) |
| `ApkFile` | apk_file | APK 文件元信息 |
| `Device` | device | 设备池清单(替代 STF 池;enabled=False 不参与调度,含 model 型号列) |
| `PendingDevice` | pending_device | 自动发现「待连接池」(扫描发现、用户确认后才入正式池) |
> 表名默认取类名小写(models.py 未写 `__tablename__`)。另有三张非模型表,由原生 SQL 幂等创建、**不走 SCHEMA_MIGRATIONS**:
> - `app_meta`(KV):`_migrate_schema()` 内建表,存 `schema_version`、`discovery_*`、agent 配置 `agent_*` 等;
> - `agent_conversation` / `agent_experience` / `experience_audit`:AI 控制台会话 / 经验库 / 经验巡检(`web/agent_api.py` 顶部 `CREATE TABLE IF NOT EXISTS`)。
**数据库初始化**(`init_db`):
- 创建所有表
- 首次启动创建默认管理员 `admin/admin123`
- 自动迁移旧 `groups.json` / `jobs.json` 到 SQLite(迁移后归档为 `.migrated`)
- 版本化 schema 迁移(`SCHEMA_MIGRATIONS`):结构变更必须追加迁移条目,`create_all` 只建新表不加列
- 版本化 schema 迁移(`SCHEMA_MIGRATIONS`,**当前到 v4**,见 `core/models.py`):结构变更必须追加迁移条目,`create_all` 只建新表不加列
### 权限模型
@@ -242,13 +248,15 @@ APK 上传/解析/批量安装。
| `tasks_api.py` | 任务计划/分组/自定义动作/元素抓取/步骤测试 |
| `admin_api.py` | 用户管理/日志 |
| `tools_api.py` | adb 终端/剪贴板注入/应用版本 |
| `devices_api.py` | 设备池管理(增删停用/重连/型号采集) |
| `devices_api.py` | 设备池管理 + 自动发现(扫描/确认/忽略/手动重连/型号采集) |
| `apks_api.py` | 应用管理 |
| `tailscale_api.py` | Tailscale 管理 |
| `agent_api.py` | AI 控制台:会话 / 运行 / SSE / 停止 / 配置 / 经验库与巡检(读写 `agent_conversation`、`agent_experience`、app_meta `agent_*`) |
| `system_api.py` | 系统数据备份导出 / 导入恢复(`/api/system/backup/*`,仅 admin) |
| `common.py` | 跨模块共享(合并设备列表/屏幕状态) |
| `context.py` | 共享对象注入(mgr/apk_mgr/device_pool) |
`web_server.py` 只保留:app 创建、数据库初始化、蓝图注册、uiautodev 生命周期、启动(193 行)。
`web_server.py` 只做装配与启动(266 行):app 创建;`init_db` 前消费待生效备份恢复(`consume_pending_restore`);初始化 device_pool / device_discovery;装配 TaskManager / ApkManager;注册 10 个蓝图(auth/monitor/tasks/admin/tools/devices/apks/tailscale/agent/system,`web/__init__.py`);注册经验巡检 APScheduler(03:47 Asia/Shanghai);uiautodev 子进程启停与设备池预连接线程;启动。
---
@@ -300,7 +308,7 @@ tasks/douyin/actions/like.py — @register_action(ACTIONS) LikeAction
`templates/admin/monitor.html` 是纯 HTML+CSS+JS 单页应用,无框架依赖。
- **Tab 切换**:5 个 Tab(监控/任务/分组/日志/用户),纯 DOM 操作
- **Tab 切换**:7 个顶级 Tab(监控/任务/日志/用户/工具/AI 控制台/系统),均在 monitor.html 内 `.tab-panel` 切换(纯 DOM 操作);独立页面仅 `/login`、`/wall`。原"分组"已无顶层入口(移到工具页子分栏)
- **数据获取**:`fetch()` 调 JSON API,5 秒轮询 `/api/status`
- **状态渲染**:设备表格、任务卡片、进度条、徽章,纯 DOM 操作
@@ -317,9 +325,13 @@ tasks/douyin/actions/like.py — @register_action(ACTIONS) LikeAction
### 5.3 页内子分栏
任务/工具 Tab 用通用 `showSubTab(tabId, name)` 实现页内子分栏:每个子分栏一个 `.sub-panel`,
`_activeSubs` 记住各 Tab 上次选中的子分栏。工具 Tab 集中了全部管理工具(剪贴板注入/adb 终端/
Tailscale/应用管理/应用版本/已装应用/STF 设备管理),维护 Tab 仅保留 STF 服务。
任务/工具/系统 Tab 用通用 `showSubTab(tabId, name)` 实现页内子分栏:每个子分栏一个 `.sub-panel`,
`_activeSubs` 记住各 Tab 上次选中的子分栏。现状子分栏:
- **任务**:任务计划 / 自定义动作
- **工具**:剪贴板注入 / adb 远程终端 / Tailscale 管理 / 应用管理 / 应用版本管理 / 设备已装应用 / 设备池管理 / 设备分组
- **系统**:数据备份 / 导入恢复
(原"分组"顶级 Tab 与"维护/STF 服务"子分栏已不存在——分组已移入工具页子分栏,STF 已摘除。)
### 5.4 元素抓取模态框
@@ -344,15 +356,15 @@ Tailscale/应用管理/应用版本/已装应用/STF 设备管理),维护 Ta
### 6.3 为什么绝不 kill-server
`adb kill-server` 会断开所有设备的 adb transport,导致 STF provider 误判全部设备离线并触发重连。连接失败就返回 False,由调用方处理。
`adb kill-server` / `adb disconnect` 会断开共享的 adb transport(历史与 STF provider 共享;STF 摘除后红线仍保留——多 worker、前台扫描、设备自动发现共用同一 adb server),影响所有运行中的任务。连接失败就返回 False,由调用方处理。
### 6.4 为什么状态查询带缓存
STF API 响应慢(设备多时 2-5 秒),每次 `/api/status` 都打 STF 会阻塞 Flask。带 5 秒缓存,Worker 状态实时读内存(无 IO)。
状态源 = 本地 SQLite 设备池 + adb + 内存 worker 状态。5 秒缓存避免每次 `/api/status` 都查库/adb 阻塞 Flask;Worker 实时状态读内存,不受缓存影响。
### 6.5 为什么 DeviceOfflineError 不重试
设备掉线后短时间内不会自愈,重试只会浪费配额并阻塞调度器。让设备进入冷却,由运维/STF 恢复后再启用。
设备掉线后短时间内不会自愈,重试只会浪费配额并阻塞调度器。让设备进入冷却,可依赖设备自动发现(device_discovery 对正式池断联设备每轮 adb 重连)恢复后再启用。
---
@@ -361,14 +373,21 @@ STF API 响应慢(设备多时 2-5 秒),每次 `/api/status` 都打 STF
```
主线程(Flask)
├── HTTP 请求处理(threaded=True,每请求一线程)
├── APScheduler 线程(cron 触发)
├── TaskManager.scheduler(APScheduler,cron 触发任务计划)
├── 经验巡检 BackgroundScheduler(03:47 Asia/Shanghai,web_server 装配)
├── 设备自动发现线程(device_discovery._discovery_loop,默认 60s 一轮)
├── 设备池型号采集后台线程(device_pool._refresh_models_bg,启动/手动触发)
├── 设备池预连接线程(web_server._preconnect_pool_devices,重启后加速恢复)
├── AI Agent 运行线程(agent_api._agent_thread,单实例 + SSE 推送)
├── 看门狗线程(_Watchdog,30s 间隔)
├── uiautodev 子进程
├── uiautodev 子进程(PID + cmdline 校验,防容器 PID 复用误杀)
└── Worker 线程(每台设备一个)
├── _run_with_retry 线程(重试循环)
└── BaseWorker 线程(设备生命周期 + run_task)
```
> MCP server(127.0.0.1:8033)是**独立进程**(scripts/start.sh 拉起),不是 web_server 的线程。
**线程安全**:
- `_WORKERS_LOCK`:保护全局 worker 状态字典
- `_ADB_LOCK`:串行化所有 adb 调用