移植自 mac-agent-os 的 mediacrawler_adapter:不起子进程、不开页面,用浏览器里那份
登录态直接调抖音 Web 接口。产物键名照抄 store/douyin,所以 ingest 那条链路一个字不用改。
**目前能用的(真环境实测,非推断)**:
profile/other : 200, 7075 字节 —— 博主主页指标(粉丝/获赞/作品数/昵称)
aweme/detail : 200, 45425 字节 —— 单条作品详情(含点赞/评论/收藏/分享)
**目前不能用的:作品列表 `aweme/post`。** 两个互相独立的原因:
1. 这个接口被抖音单独升级成了真校验:不带 x-tt-argus 回 403「Uifid Not Found」,
带上 dummy 值回 200 + **空 body**。也就是说「头在不在」骗得过,「真校验」过不了。
同一套头打 profile/other 和 aweme/detail 都是通的 —— 抖音是挑着接口加保护的,
挑中的恰好是「批量拉作品列表」这个最敏感的动作。
2. 改走页面截获也不行:CDP 浏览器打开博主主页会落到「验证码中间页」(当天大量探测的
代价,过几小时要重测)。
所以现在的边界是:**已知作品的指标刷新能做,自动发现新作品做不了**。
**排查中控住变量后得到的两条事实**(都写进注释了):
· `Accept` / `Accept-Language` / `Referer` 才是主页接口能返回真数据的原因 —— 只有
UA+client hints+Cookie 时是 200 但仅 121 字节的空壳,补上这三个头变 7074 字节。
(我先前猜的 sec-ch-ua 不是关键。)
· 因此 UA 与 client hints 必须**成套地取自同一个浏览器**,所以 BrowserIdentity 一次
从 CDP 取齐 cookie + UA + hints,而不是各自写死。
「200 + 空 body 必须当场报错」也是刻意写死的:放过去它会在下游变成「这个博主没作品」,
把一次失败伪装成一条正常结果 —— 爬虫那条路正是这么栽的,还被翻译成「账号被封」。
测试 +11:cookie 解析、请求头成套性(含 uifid 缺失/回退)、产物键名与 store 对齐、
以及 _get 的三条失败路径(空 body / 403 带网关原话 / 正常返回)。
131 lines
5.5 KiB
Markdown
131 lines
5.5 KiB
Markdown
# Dashboard 五层架构合规审计报告 v1.0
|
||
|
||
> 日期: 2026-06-19
|
||
> 审计范围: 所有 33 个前端视图 + 4 个内联模块
|
||
|
||
---
|
||
|
||
## 一、五层架构标准
|
||
|
||
```
|
||
Layer 5: 前端视图 (Vite views/*.js) → 调 API
|
||
Layer 4: API 路由 (routes/*.py) → 调 CommandBus
|
||
Layer 3: 命令总线 (CommandBus) → 调 MachineSession
|
||
Layer 2: 执行引擎 (mc run / mc task) → 调 原子操作
|
||
Layer 1: 浏览器 (Camoufox) → 执行操作
|
||
```
|
||
|
||
**通过标准**: 前端 API 调用 → 后端路由 → CommandBus.dispatch() → 子进程执行
|
||
|
||
---
|
||
|
||
## 二、账户操作视图 (必须走 CommandBus)
|
||
|
||
### ✅ 已合规 (7个)
|
||
|
||
| 视图 | 操作 | API 调用 | 后端路径 |
|
||
|:-----|:------|:---------|:---------|
|
||
| **养号执行** | 启动养号 | `POST /api/ops/run` | → CommandBus → `mc run` |
|
||
| **联邦指挥台** | 执行操作 | `POST /api/ops/run` | → CommandBus → `mc run` |
|
||
| **信息采集** | 批量采集 | `POST /api/ops/run {type:'collect'}` | → CommandBus `CMD_REGISTRY` → `mc run --blueprints=auto` |
|
||
| **信息采集** | 单账号采集 | `POST /api/ops/run {type:'collect'}` | → CommandBus `CMD_REGISTRY` → `mc run --blueprints=auto` |
|
||
| **定向评论** | 执行评论 | `POST /api/ops/run {type:'comment'}` | → CommandBus `CMD_REGISTRY` → `mc task comment` |
|
||
| **收藏点赞** | 执行点赞 | `POST /api/ops/run {type:'like'}` | → CommandBus `CMD_REGISTRY` → `mc run --blueprints=douyin_daily` |
|
||
| **登录** (账号管理/各视图🔑) | 打开浏览器 | `POST /api/ops/run {type:'login'}` | → CommandBus `CMD_REGISTRY` → `mc smart-login` |
|
||
| **CMD_REGISTRY 注册表** | 统一 cmd_type → 命令模板 | 在 command_bus.py 定义 | 新增操作只需加一行,不需改 dispatch |
|
||
|
||
### ℹ️ 系统运维操作 (不走 CommandBus 是合理的)
|
||
|
||
| 视图 | 操作 | API | 原因 |
|
||
|:-----|:------|:----|:------|
|
||
| **远程Shell** | 在远端执行命令 | `POST /api/federation/exec` | 系统管理工具, 非账号操作 |
|
||
| **对账检查** | ORACLE 宪法对账 | `POST /api/fleet/reconcile` | 系统健康检查 |
|
||
| **一键同步** | Git 同步所有机器 | `POST /api/fleet/sync` | 系统运维 |
|
||
|
||
### 📊 只读数据视图 (无操作, 无需 CommandBus)
|
||
|
||
| 视图 | API | 说明 |
|
||
|:-----|:----|:------|
|
||
| machines | `/api/machines` | 机器状态, 只读 |
|
||
| matrix-accounts | `/api/matrix/accounts` | 账号列表, 只读 |
|
||
| matrix-blueprints | `/api/matrix/blueprints`, `/api/matrix/atom-ops` | 蓝图列表+原子操作, 只读 |
|
||
| matrix-atom-ops | `/api/matrix/atom-ops` | 原子操作列表, 只读 |
|
||
| matrix-corpus | `/api/matrix/corpus` | 语料库, 只读 |
|
||
| matrix-summary | `/api/matrix/cross-machines`, `/api/matrix/system-info` | 多机总览, 只读 |
|
||
| matrix-sms-proxy | `/api/matrix/sms/*` | SMS 代理配置, 只读 |
|
||
| matrix-schedule | `/api/matrix/schedules` | 定时任务, 只读 |
|
||
| capabilities | `/api/capabilities` | 能力目录, 只读 |
|
||
| costs | `/api/summary`, `/api/costs/breakdown` | 费用统计, 只读 |
|
||
| productions | `/api/matrix/sms/accounts` | 生产列表, 只读 |
|
||
| assets | `/api/assets` | 资产库, 只读 |
|
||
|
||
### ❌ 14行占位符 (无功能)
|
||
|
||
| 视图 | 状态 |
|
||
|:-----|:------|
|
||
| ave-render, ave-script, ave-materials, ave-templates | 占位符 |
|
||
| crawl-history, crawl-sources | 占位符 |
|
||
| serve-dashboard, serve-mcp, serve-schedule | 占位符 |
|
||
| matrix-login | 跳转到采集 |
|
||
| matrix-publish | "开发中..." |
|
||
| workflow | 占位符 |
|
||
|
||
---
|
||
|
||
## 三、远程执行路径 (federation API)
|
||
|
||
`recording.js` 中 `_routeOperation()` 对远程机器分发走 federation API:
|
||
|
||
| 操作 | Federation 端点 | 现状 |
|
||
|:-----|:----------------|:------|
|
||
| login(远程) | `POST /api/federation/login` | ⚠️ 直接 SSH 执行 |
|
||
| logout(远程) | `POST /api/federation/logout` | ⚠️ 直接 SSH 执行 |
|
||
| comment(远程) | `POST /api/federation/comment` | ⚠️ 直接 SSH 执行 |
|
||
| nurture(远程) | `POST /api/federation/nurture` | ⚠️ 直接 SSH 执行 |
|
||
| collect(远程) | `POST /api/federation/collect` | ⚠️ 直接 SSH 执行 |
|
||
|
||
**这些 federation 端点应该也改为走 CommandBus**, 否则远程操作不经过命令总线的 preflight/冷却/并发控制。
|
||
|
||
---
|
||
|
||
## 四、ORACLE 合规检查规则
|
||
|
||
### 4.1 账号→机器映射表
|
||
|
||
`ORACLE.yaml` 是账号→机器的**宪法级**映射表。CommandBus 执行前自动校验:
|
||
|
||
```
|
||
请求: account=douyin_test, machine=5kechengdeAir
|
||
→ ORACLE 查 douyin_test → 应属于 chengzigedeAir
|
||
→ 发出警告: "douyin_test 按 ORACLE 应在 chengzigedeAir,实际发往 5kechengdeAir"
|
||
→ 仍然允许执行(可能是临时调配)
|
||
```
|
||
|
||
### 4.2 三种结果
|
||
|
||
| 检查结果 | 行为 | 前端显示 |
|
||
|:---------|:-----|:---------|
|
||
| 匹配 | 正常执行 | ✅ 绿色 |
|
||
| 不匹配 | 执行 + 警告 | ⚠️ 橙色警告 |
|
||
| 未登记 | 执行 + 警告 | ⚠️ 建议 git pull 后 fleet_reconcile |
|
||
|
||
### 4.3 规则存证
|
||
|
||
- `ORACLE.yaml` — 宪法文件,账号机器映射的 source of truth
|
||
- `command_bus.py` — 运行时校验,每次 dispatch 自动检查
|
||
- `fleet_reconcile` — 对账工具,检查实际状态是否符合 ORACLE
|
||
|
||
---
|
||
|
||
## 五、总结
|
||
|
||
| 类别 | 数量 | 状态 |
|
||
|:-----|:-----|:------|
|
||
| 账户操作视图 | **7** | ✅ **全部已合规**(走 CommandBus) |
|
||
| 系统运维视图 | **3** | ℹ️ 合理不走 CommandBus |
|
||
| 只读数据视图 | **12** | ℹ️ 无操作 |
|
||
| 占位符视图 | **11** | ❌ 无功能 |
|
||
| 远程分发端点 | **5** | ⚠️ 待改造 |
|
||
|
||
**当前优先级**: 远程端点(federation)改造 → 占位符填充 → 旧模块清理
|