feat: continue CreatorHub plan01 implementation
This commit is contained in:
@@ -1,36 +1,48 @@
|
||||
# 浏览器容器控制面
|
||||
|
||||
> 当前实现说明,核对基线 `main@1fbf126`;不是新业务完成证明。目标范围与验收以 [plan01](../plan01.md) 为准,运行步骤见[部署说明](../deployment.md)。现状限制不自动成为新产品约束。
|
||||
|
||||
## 技术选型
|
||||
|
||||
- 前端:React 19 + react-admin(ra-core)+ MUI,包含运行环境、镜像版本、网关管理三个页面。
|
||||
- 前端:React 19 + Vite 8 + Refine + shadcn/ui + Tailwind CSS,图标 RemixIcon;项目自有 Layout 与 HashRouter,当前页面见 [main.jsx](../../web/src/main.jsx),依赖见 [package.json](../../web/package.json)。
|
||||
- 后端:Go 模块化单体,Fiber v3 提供 HTTP 路由,Viper 读取并校验启动配置,Logrus 输出 JSON 结构化日志,Cobra 保持当前两个服务入口。控制面提供同源 API 和静态文件,并编排网关;受限网关单独封装 Docker Engine API,是纯执行器。
|
||||
- 数据:环境配置(别名、中文名、网关、镜像版本、指纹参数)持久化在 Postgres,运行态实时查询网关;Profile 使用命名卷持久化;阶段 A 账号、凭据引用、确认、任务、尝试和审计实体同样由控制面持久化到 Postgres。
|
||||
- 数据:环境配置(别名、中文名、网关、镜像版本、指纹参数)持久化在 Postgres,列表/详情读取持久运行记录,不触发网关实时探测;后台独立维护运行租约;Profile 使用命名卷持久化;阶段 A 账号、凭据引用、确认、任务、尝试和审计实体同样由控制面持久化到 Postgres。
|
||||
- 部署:Docker Compose 启动控制面和受限网关;浏览器容器由网关按平台下发的镜像引用动态创建,缺失时自动拉取。
|
||||
|
||||
## 调用链与契约
|
||||
|
||||
```text
|
||||
React ──> control-plane ── /api/browsers ──(Bearer token)──> docker-gateway ──> docker.sock
|
||||
│ │
|
||||
│ └─> browser container
|
||||
└─ /api/phase-a, /api/browser-images, /api/gateways ──> PostgreSQL
|
||||
React ── /api/* (Basic Auth) ──> control-plane
|
||||
├─ /v1/browsers (Bearer token) ──> docker-gateway ──> docker.sock
|
||||
│ └─> browser container
|
||||
└─ 账号/环境/任务等持久记录 ──> PostgreSQL
|
||||
```
|
||||
|
||||
控制面是唯一事实源:网关不持有镜像清单和业务规则,镜像引用、启动命令和卷名均随请求下发。
|
||||
|
||||
- `POST /api/browsers` 接受 `{alias, name, gateway, image_version, fingerprint}`(严格 JSON,未知字段拒绝),校验后先落库,再调网关创建并启动;网关失败时回滚数据库行。`name` 为中文环境名,`alias` 限 `^[a-z0-9][a-z0-9-]{0,31}$`,容器名 `creatorhub-browser-<alias>`,Profile 卷 `creatorhub-profile-<alias>`。
|
||||
- `GET /api/browsers` 合并数据库环境与网关实时状态;环境在网关无容器时显示为未部署。
|
||||
- `POST /api/browsers/{alias}/start|stop` 改变状态;`POST /api/browsers/{alias}/upgrade` 收 `{version}`,由平台编排:停止并删除旧容器(保留 Profile 卷)→ 用新镜像引用与原指纹参数重建 → 启动;失败直接重试,不做自动回滚。
|
||||
- `DELETE /api/browsers/{alias}` 回收容器并删除数据库行,保留 Profile 数据卷。
|
||||
当前生命周期契约集中如下(代码:[控制面](../../cmd/control-plane/hub.go)、[环境存储](../../internal/hub/environment.go)):
|
||||
|
||||
| 接口/动作 | 当前行为与失败语义 |
|
||||
| --- | --- |
|
||||
| `POST /api/browsers` / create | 严格接收 `{alias, name, gateway, image_version, fingerprint, account_id, network_exit_id}`,未知字段拒绝;`account_id` 必填,`network_exit_id` 可空表示明确选择直连。新绑定要求账号 authorized/paused、镜像启用,指定出口须健康并再次核验。先保存环境与稳定 binding,创建停止态容器;不是创建即启动。相同绑定及配置可复用,冲突拒绝;已存在且账号可运行的环境可调和/恢复运行。网关失败不删除已保存环境/binding,保留以供核验/恢复 |
|
||||
| `GET /api/browsers`、`GET /api/browsers/{alias}` | 只读数据库环境/运行记录;列表的 running 表示已记录运行实例,不保证实时存活。页面可直接展示返回 status,不主动探测或轮询。后台租约调和与列表读取独立 |
|
||||
| `POST /api/browsers/{alias}/start` | 要求账号可运行;有出口时重新核验,不健康则失败而非直连。当前匹配且就绪的运行容器可复用;停止/缺失容器按当前 binding 重建并激活租约;支持预先选定的直连 |
|
||||
| `POST /api/browsers/{alias}/stop` | 停止容器并处理租约/清理状态;失败或结果不明可见,不据请求发出即声称已停止 |
|
||||
| `POST /api/browsers/{alias}/upgrade` | 接收 `{version}`,要求启用镜像;删除旧容器并保留 Profile,更新版本后按原指纹/binding 重建,账号可运行才启动,否则为停止态。无自动回滚;失败保留结果,人工重试进入现有调和流程。当前实现无条件核验出口,空出口的直连环境不能据 create/start 成功推断 upgrade 可用 |
|
||||
| `POST /api/browsers/{alias}/rebind` | 接收 `{network_exit_id}`;要求 paused、无 executing task、无活动 runtime,验证目标出口后变更。当前要求有效出口 ID,不支持以空值切回直连 |
|
||||
| `DELETE /api/browsers/{alias}` / recycle | 回收容器、处理运行记录,但保留环境、稳定 binding 与命名 Profile 卷;后续 create/start 复用。不是永久删除账号/环境或素材;没有新增永久删除 API |
|
||||
|
||||
`name` 是环境展示名,`alias` 限 `^[a-z0-9][a-z0-9-]{0,31}$`;容器名 `creatorhub-browser-<alias>`,Profile 卷 `creatorhub-profile-<alias>`。指纹中的代理字段拒绝,使用所选出口;已绑定代理失败不能静默直连。create/start/stop/upgrade/recycle 写同一 operation ID 的 requested/finished 审计对,网关断连且无法调和时 outcome 为 `unknown`;幂等/重试是生命周期核验,不等于 plan01 中人工/自动业务发送可重发。
|
||||
|
||||
- `GET/POST /api/browser-images` 维护可用镜像版本(版本号不可改,`PUT /{version}` 仅接受 `image_ref/note/enabled`);仅启用版本可用于创建与升级;被环境引用时拒绝删除。
|
||||
- `GET/POST /api/gateways` 注册网关(`POST` 可携带令牌,否则平台生成 48 位十六进制令牌并明文存储),`DELETE /api/gateways/{name}` 删除;仍被环境引用时拒绝删除。
|
||||
- 启停接受幂等响应,不自动重试未知结果;别名唯一约束由数据库保证。
|
||||
- 别名唯一约束由数据库保证;控制面不自动重试结果不明的用户生命周期请求,后台租约恢复的现状另见下文。
|
||||
|
||||
## docker.sock 安全边界
|
||||
|
||||
将 socket 以只读文件挂载**不会**限制 Docker API 的写操作;拥有 socket 等价于拥有宿主机 root 权限。因此:
|
||||
|
||||
- 只有 `docker-gateway` 挂载 socket,控制面和浏览器容器均不可见;网关加入 control 与 browser 网络,浏览器只拿到无凭据的内存转发代理地址,`/v1` 仍必须通过容器内不可见的网关令牌;
|
||||
- 只有 `docker-gateway` 挂载 socket,控制面和浏览器容器均不可见;网关加入 control 并按需接入浏览器隔离网络,浏览器在代理模式只拿到无凭据的内存转发代理地址,`/v1` 仍必须通过容器内不可见的网关令牌;
|
||||
- 网关只暴露面向领域的路由,不提供通用 Docker 代理;`/v1` 全部接口校验 `Authorization: Bearer <GATEWAY_TOKEN>`(常数时间比较),令牌由部署者在网关环境变量与平台注册表中保持一致;
|
||||
- 网关直连的 `POST /v1/browsers/{alias}/start|stop` 仅供内部维护使用,必须提交并精确匹配容器标签中的 `{binding_version,runtime_id,network_id}`;直连 start 拒绝空 `network_id`,generation 不匹配返回 `409`,控制面生命周期编排不依赖无 fence 的直连 start;
|
||||
- 网关恢复内存代理时会同时 fence 隔离网络成员及网关成员 IPv4,地址变化返回 `409` 并关闭刚恢复的监听;代理移除或代际替换会立即关闭所有已 hijack 的 CONNECT 双向连接,任一端先关闭也会关闭隧道两端,不等待优雅 drain;
|
||||
@@ -40,24 +52,17 @@ React ──> control-plane ── /api/browsers ──(Bearer token)──> doc
|
||||
- 控制面发布到宿主机所有网卡;控制网络为固定名称的 Compose 网络;浏览器 bridge 按 ownership、role、driver、Internal 失败关闭校验,且拒绝复用 control 网络;
|
||||
- Compose 基础镜像锁定 digest;浏览器镜像推荐使用 `@sha256:` 摘要引用以获得不可变性,tag 引用由部署者自行把控。
|
||||
|
||||
网关自身一旦被攻破,socket 仍允许接管宿主机;应用内校验不能消除这个平台级风险。开发阶段控制面不做认证或访问限制,安全由部署者自行把控。
|
||||
网关自身一旦被攻破,socket 仍允许接管宿主机;应用内校验不能消除这个平台级风险。开发目标不新增认证或访问限制,安全由部署者自行把控;但当前代码仍强制 HTTP Basic Auth(除 `/healthz` 外的 API 与静态页面),Compose 仍要求用户名/密码。见 [main.go](../../cmd/control-plane/main.go) 与 [compose.yaml](../../compose.yaml);本轮未移除现有策略,也不新增 RBAC 或认证 profile。
|
||||
|
||||
## 运行
|
||||
|
||||
Docker socket 的 GID 因宿主机而异:
|
||||
使用[部署说明](../deployment.md)中的完整变量及启动命令(含 Basic Auth、凭据主密钥与 socket GID),不维护另一套省略必填配置的命令。首次注册网关和镜像、创建账号、再创建停止态环境;恢复账号后显式启动。网关拉取镜像上限约 10 分钟;失败查看审计和保留的环境,不能按“数据库已回滚”直接假定没有资源。
|
||||
|
||||
```bash
|
||||
export GATEWAY_TOKEN="$(openssl rand -hex 24)" # 亦可在 .env 中设置
|
||||
DOCKER_GID=$(stat -c %g /var/run/docker.sock) docker compose up --build
|
||||
```
|
||||
## 现有账号与阶段 A 离线闭环
|
||||
|
||||
打开 <http://127.0.0.1:8080>,局域网内用宿主机 IP 访问同一端口。首次使用:在「网关管理」用 `GATEWAY_TOKEN` 注册 `http://docker-gateway:8081`,在「镜像版本」添加镜像引用(缺失时网关自动拉取,拉取上限 10 分钟)。浏览器容器可访问外网。
|
||||
本节描述已运行的基础及历史 schema,不规定 plan01 的新业务范围。旧阶段 A 的 Mock 任务验证不等于 G0 平台能力或 G1 抖音完整验收;当前抖音受限读取连接器也未接成完整竞品/监听/发送流程。
|
||||
|
||||
创建成功但启动失败时,网关会立即删除失败容器并保留命名 Profile 卷,控制面回滚数据库行,允许同名请求安全重试。
|
||||
|
||||
## 阶段 A 离线闭环
|
||||
|
||||
`POST /api/phase-a/accounts` 只接受 `{name, platform, platform_account_key, tags, cookies}`;`platform` 限定为 `douyin`、`xiaohongshu`、`wechat-official`、`kuaishou`,`cookies` 必须是浏览器 Cookie Header 格式。控制面通过持久 provider bridge 安全写入凭据:部署侧 Secret Manager/OS Keyring 注入 32 字节主密钥,独立凭据卷只保存 AES-GCM 密文,数据库只记录凭据引用;外部 API 不返回 Cookies、provider 或 `reference_key`。数据库明确回滚时清理凭据,提交结果未知时保留凭据并返回 `account_creation_result_unknown`,不自动破坏可能已提交的账号。内部账号 ID 由服务端生成,新账号默认 `paused`,`(platform, platform_account_key)` 全局唯一。pause/revoke 会递增账号版本并将 queued 任务置为 `policy_hold`,只有具备 binding 和 healthy 出口的未撤销账号才能 resume。账号与浏览器环境通过一对一 `environment_binding` 关联,出口可复用;运行实例保留历史,并以 binding 和外部 runtime id 的部分唯一索引限制活动实例。
|
||||
`POST /api/phase-a/accounts` 只接受 `{name, platform, platform_account_key, tags, cookies}`;`platform` 限定为 `douyin`、`xiaohongshu`、`wechat-official`、`kuaishou`,`cookies` 可空,非空时须为浏览器 Cookie Header 格式。控制面通过持久 provider bridge 安全写入凭据:部署侧 Secret Manager/OS Keyring 注入 32 字节主密钥,独立凭据卷只保存 AES-GCM 密文,数据库只记录凭据引用;外部 API 不返回 Cookies、provider 或 `reference_key`。数据库明确回滚时清理凭据,提交结果未知时保留凭据并返回 `account_creation_result_unknown`,不自动破坏可能已提交的账号。内部账号 ID 由服务端生成,新账号默认 `paused`,`(platform, platform_account_key)` 全局唯一。pause/revoke 会递增账号版本并将 queued 任务置为 `policy_hold`,resume 要求稳定 binding,若绑定出口则需 healthy,并满足无活动 runtime/待清理等条件;未绑定出口的显式直连不要求出口记录。账号与浏览器环境通过一对一 `environment_binding` 关联,出口可复用;运行实例保留历史,并以 binding 和外部 runtime id 的部分唯一索引限制活动实例。
|
||||
|
||||
草稿经 `POST /api/phase-a/confirmations` 显式确认后才可投递到 `/api/phase-a/tasks`。任务由幂等键去重;`POST /api/phase-a/mock/execute` 使用 `FOR UPDATE SKIP LOCKED` 领取一分钟租约,执行前统一核对账号、草稿和确认版本。缺少确认或版本不一致会进入 `needs_confirmation`,暂停账号或 Mock 策略结果会进入 `policy_hold`,不确定结果与过期租约进入 `needs_confirmation`;这些状态都不会自动重试。`GET /api/phase-a/audit` 只导出账号、确认版本、尝试和结果等非秘密证据。
|
||||
|
||||
@@ -65,10 +70,16 @@ DOCKER_GID=$(stat -c %g /var/run/docker.sock) docker compose up --build
|
||||
|
||||
`POST /api/network-exits` 只接受协议、主机、端口、已有 `credential_reference: {id}` 和预期出口身份;新出口为 `unchecked`,由 `POST /api/network-exits/:id/check` 经实际代理链路变为 `healthy` 或 `unhealthy`,`disable` 不可被检查重新启用。credential reference 的 `reference_key` 不出现在 API、日志或审计中;OS Keyring/Secret Manager bridge 在控制面进程启动前注入 `CREATORHUB_CREDENTIAL_<SHA256(reference_key)>`(大写十六进制),值为请求期解析的 `username:password`,控制面不持久化解析值。
|
||||
|
||||
`POST /api/browsers` 必须同时给出 `account_id` 和 `network_exit_id`。环境创建、启动和升级都会重新检查出口身份,只有 `healthy` 才调用网关;控制面强制下发代理和 `disable_non_proxied_udp`,fingerprint 中的代理字段会被拒绝。显式 `POST /api/browsers/:alias/rebind` 只允许 paused、无 executing task 且无活动 runtime 的账号。`DELETE /api/browsers/:alias` 回收容器但保留稳定 binding、环境和命名 Profile 卷,后续 create 复用它们。create/start/stop/upgrade/recycle 均写共享 operation ID 的 requested/finished 审计对;网关断连且无法调和时 outcome 为 `unknown`。
|
||||
环境创建/启动/回收及直连边界以上方生命周期表为唯一说明。已配置代理时由控制面下发代理信息与 `disable_non_proxied_udp`;直连并非代理失败后的替代路径。
|
||||
|
||||
解析后的出口凭据只存在于控制面单次请求和网关内存转发器中;Docker inspect、容器环境、标签、挂载、`Config.Cmd` 与进程参数只包含 `docker-gateway` 的无凭据本地代理地址。网关内存代理以 alias、binding version 和 exit ID 共同标识 generation;生命周期操作按 alias 串行,重启恢复或重建必须重新核对该 generation,旧出口代理不能被新容器复用。
|
||||
|
||||
stopped 环境启动时先删除旧容器并确认 runtime lease 释放,再按当前 binding 重建;控制面每 20 秒及列表读取时调和网关,续租 running runtime、释放 stopped/missing runtime,过期 lease 也会在绑定事务中回收。控制面用 PostgreSQL advisory transaction lock 按 alias 协调多副本;每个 Store 最多允许 5 个锁会话占用 10 连接池的一半,为锁内数据库调用保留连接。create 同时锁定账号 ID、alias、请求出口和请求镜像;start、reconcile/rebuild、rebind 和 upgrade 锁定 alias、当前出口及当前镜像(upgrade 还锁目标镜像),拿锁后重新读取出口与镜像版本。账号 pause/resume/revoke 使用账号 ID 与当前 binding alias 加入同一协调域;镜像禁用、引用更新或账号状态变更不能穿透在途生命周期。
|
||||
控制面后台每 20 秒调和网关([runtimeLeaseHeartbeat](../../cmd/control-plane/main.go)),续租 running runtime、释放 stopped/missing runtime;列表/详情读取不触发调和,过期 lease 也会在绑定事务中回收。控制面用 PostgreSQL advisory transaction lock 按 alias 协调多副本;每个 Store 最多允许 5 个锁会话占用 10 连接池的一半,为锁内数据库调用保留连接。create 同时锁定账号 ID、alias、请求出口和请求镜像;start、reconcile/rebuild、rebind 和 upgrade 锁定 alias、当前出口及当前镜像(upgrade 还锁目标镜像),拿锁后重新读取出口与镜像版本。账号 pause/resume/revoke 使用账号 ID 与当前 binding alias 加入同一协调域;镜像禁用、引用更新或账号状态变更不能穿透在途生命周期。
|
||||
|
||||
非法 upgrade/rebind 目标在进入 advisory lock key 前按公开格式校验;审计仅保留环境原有的非秘密资源关联,并以 `upgrade_input_rejected` / `rebind_input_rejected` 写同一 operation ID 的 requested/finished 对。reconcile 恢复或重建后会重新读取 context,finished 事件关联实际激活的 runtime instance、binding version 与出口;后台释放 runtime 的成功或失败也写独立的 `reconcile` 审计对。
|
||||
|
||||
## 与新业务计划的边界
|
||||
|
||||
- 当前受限抖音读取仅允许自身身份与 `count=20/max_cursor=0` 首批作品,JSON 响应限制为 1 MiB,见 [douyin.go](../../cmd/docker-gateway/douyin.go)。这些是现状,不是竞品分页或媒体下载的完成证据;后续媒体按 plan01 C4 分步保存产物引用,不复用通用 JSON 响应承载二进制。
|
||||
- 当前账号凭据入口处理 Cookie;plan01 要求的可选登录密码应允许输入现有凭据保存流程,读取不回显、不进入日志,并非新增“禁止收密码”的接口限制。
|
||||
- 新业务平台监听、前端业务推送和现有后台运行租约是三件事;前两者要求见 plan01 A6,列表不主动探测的约定不禁止业务事件推送。现有生命周期/租约可能核验出口,不应误写成已完成 plan01 的手动代理管理目标。
|
||||
|
||||
+13
-11
@@ -1,6 +1,8 @@
|
||||
# CreatorHub 部署
|
||||
|
||||
本文档适用于当前阶段 A:在一台 Linux 主机上通过 Docker Compose 部署。控制面使用单用户 HTTP Basic Auth;当前不提供 RBAC 或多租户隔离。
|
||||
本文档按 `main@1fbf126` 当前可运行代码说明单台 Linux 主机 Docker Compose 部署及旧阶段 A Mock 检查,不证明新产品功能已实现。[plan01](plan01.md) 是业务范围与验收依据,旧阶段 A 离线结果不等于 G0/G1,也不能替代抖音/小红书最终真机验收。
|
||||
|
||||
当前控制面仍使用单用户 HTTP Basic Auth(除 `/healthz` 外,包括静态页面),不提供 RBAC 或多租户隔离。开发目标不新增认证/访问限制,但本轮未删除现有代码或配置;以下变量仍须填写,不新增认证 profile。
|
||||
|
||||
## 部署内容
|
||||
|
||||
@@ -60,7 +62,8 @@ docker compose up --detach --build
|
||||
|
||||
1. 「网关管理」页注册网关:名称如 `gw-main`,Endpoint `http://docker-gateway:8081`,令牌填 `GATEWAY_TOKEN` 的值(即 `openssl rand -hex 24` 生成的值)。
|
||||
2. 「镜像版本」页添加可用镜像,如版本 `148.0.7778.215`、引用 `git.ipao.vip/rogee/fingerprint-chromium:148.0.7778.215`(或 `@sha256:` 摘要引用)。
|
||||
3. 「运行环境」页创建环境:中文名 + 小写别名 + 指纹参数,容器名 `creatorhub-browser-<别名>`,Profile 卷 `creatorhub-profile-<别名>`。
|
||||
3. 「社媒账号」页先创建账号(默认暂停),再在「运行环境」选该账号、网关、镜像,填写中文名、小写别名及指纹参数。代理可选;指定代理须先手动检测为健康,留空是明确直连,不是失败回退。
|
||||
4. 创建得到停止态容器;在账号页恢复账号后回环境页显式启动。容器名 `creatorhub-browser-<别名>`,Profile 卷 `creatorhub-profile-<别名>`。回收只删除容器、保留环境/binding/Profile;完整契约见[架构说明](architecture/container-control.md)。当前直连 create/start 不代表 upgrade/rebind 已支持空出口。
|
||||
|
||||
## 部署验证
|
||||
|
||||
@@ -84,8 +87,7 @@ docker compose ps
|
||||
|
||||
健康检查应成功,浏览器列表接口应返回 JSON,迁移查询当前应输出 `1`,三个 Compose 服务应为运行状态。`CREATORHUB_CREDENTIAL_MASTER_KEY` 必须由部署侧 Secret Manager/OS Keyring 持久保存并在每次启动时注入同一值;账号凭据以 AES-GCM 密文写入独立 `creatorhub_credentials` 卷,轮换主密钥前必须先迁移已有凭据。然后访问 <http://127.0.0.1:8080>;修改过 `CREATORHUB_PORT` 时使用对应端口。
|
||||
|
||||
若任何持久环境曾运行 PR 中间版本 `a37732c`,发布前先执行
|
||||
`SELECT to_regclass(current_schema() || '.account_credential_reconciliation');`。结果非空表示遗留了当前代码不再使用的非秘密对账表;不要手工改写 `schema_migration` 或直接删表。应在确认不再回滚到该中间版本并完成数据库备份后,以单独的前向迁移 v15 删除该表并先在备份副本演练;该清理不影响当前账号创建链路,但属于正式发布前检查项。
|
||||
旧实验版本的数据库异常应先记录版本、备份并核实,不把历史文档中的建议迁移当成本期开发要求;本期不新增兼容迁移、回填或双写。下文更新/恢复命令仅描述现有部署的数据操作,不改变 plan01 验收范围。
|
||||
|
||||
排障时读取结构化服务日志:
|
||||
|
||||
@@ -95,11 +97,11 @@ docker compose logs --tail=200 creator-hub docker-gateway postgres
|
||||
|
||||
## 手工业务验证(阶段 A Mock)
|
||||
|
||||
当前阶段 A 是单用户、虚拟平台 mock 的离线闭环,不连接真实社交平台。最小业务路径是:账号 → 草稿 → 显式确认 → 任务入队 → Mock 执行 → 审计回溯。
|
||||
本节的旧阶段 A 业务执行器是 Mock,不向真实社交平台发送;容器、数据库、网关和可选代理则是实际运行资源。最小业务路径是:账号 → 草稿 → 显式确认 → 任务入队 → Mock 执行 → 审计回溯。
|
||||
|
||||
页面路径如下:
|
||||
|
||||
1. 登录后在「网关管理」注册 <http://docker-gateway:8081,令牌必须等于> GATEWAY_TOKEN。
|
||||
1. 登录后在「网关管理」注册 <http://docker-gateway:8081>,令牌必须等于 GATEWAY_TOKEN。
|
||||
2. 在「镜像版本」添加并启用一个可拉取的 fingerprint-chromium 镜像。
|
||||
3. 可选:在「网络出口」创建出口并点击「检测」,健康状态必须为「健康」;这里只填写凭据引用 ID,不填写密码、Cookie 或 token。留空则使用网关所在机器的网络出口直连。
|
||||
4. 在「社媒账号」创建平台为抖音的账号;创建后默认暂停,后续仍可使用 Mock 执行器验证离线闭环。
|
||||
@@ -213,7 +215,7 @@ printf 'PASS account=%s environment=%s task=%s state=succeeded audit=task_queued
|
||||
|
||||
通过标准:/healthz 返回 204;受保护的 /api/browsers 返回 JSON;网关、控制面、PostgreSQL 均为运行状态;运行环境有 runtime_id 和 runtime_instance_id;任务最终为 succeeded,且执行尝试的脱敏证据为 mock_outcome=succeeded;审计至少包含 task_queued、task_claimed、task_finished。重复提交同一确认时应返回同一任务 ID,不应产生第二条任务。
|
||||
|
||||
验证完成后的安全清理(不删除 PostgreSQL 或 Profile 卷):
|
||||
验证完成后的容器回收(保留账号、环境/binding、PostgreSQL 数据与 Profile 卷,不是永久删除环境):
|
||||
|
||||
~~~bash
|
||||
api() {
|
||||
@@ -234,11 +236,11 @@ docker compose stop
|
||||
| 手工验证脚本在 `:?` 处退出 | CREATORHUB_PORT、GATEWAY_TOKEN、CONTROL_PLANE_USERNAME、CONTROL_PLANE_PASSWORD、CREATORHUB_CREDENTIAL_MASTER_KEY 是否都已 export | 在启动 Compose 的同一个 shell 中 export 完整变量集;不要只依赖 `.env` 或 Compose 默认值 |
|
||||
| creator-hub 未启动 | docker compose ps、docker compose logs --tail=200 postgres docker-gateway creator-hub | 先确认 PostgreSQL 与网关 health 为 healthy;网关需能访问 /var/run/docker.sock,DOCKER_GID 使用 stat -c '%g' /var/run/docker.sock 的实际值 |
|
||||
| API 返回 401 | curl 是否带 --user CONTROL_PLANE_USERNAME:CONTROL_PLANE_PASSWORD | /healthz 不需要认证,其余 /api/* 需要控制面 Basic Auth |
|
||||
| /api/browsers 返回 503 或网关不可用 | 网关注册的 Endpoint、令牌与 Compose 的 GATEWAY_TOKEN | Endpoint 在 Compose 网络内应为 <http://docker-gateway:8081;重新注册时令牌必须完全一致> |
|
||||
| 生命周期动作报网关不可用 | 网关注册的 Endpoint、令牌与 Compose 的 GATEWAY_TOKEN | Endpoint 应为 <http://docker-gateway:8081>;令牌必须完全一致。列表/详情只读持久记录,其成功不能证明网关在线 |
|
||||
| 出口一直是 unchecked/unhealthy | 出口协议、主机、端口;控制面容器到代理的连通性;last_check_reason | 先用无认证代理完成最小验证;有认证时只提供已配置的凭据引用,不把认证值放到请求、日志或文档 |
|
||||
| 创建环境时报 image_unavailable 或拉取超时 | image_ref 格式、镜像架构、Docker daemon 的 registry 登录和网络 | 版本表中的镜像必须可被 Docker daemon 拉取;缺失镜像会由网关按引用拉取,最长约 10 分钟 |
|
||||
| 创建环境时报 image_unavailable 或拉取超时 | image_ref 格式、镜像架构、Docker daemon 的 registry 登录和网络 | 版本表中的镜像必须可被 Docker daemon 拉取,最长约 10 分钟;已保存环境/binding 不会因网关失败自动删掉,核对记录后按原配置恢复 |
|
||||
| 恢复/入队返回 503 | readiness、GET /api/browsers/<alias>、GET /api/network-exits/<id> | binding_missing、network_exit_unhealthy、runtime_missing 表示固定资源未就绪;先修复出口并启动原环境,不要换出口重试 |
|
||||
| Mock 执行没有领取任务 | GET /api/phase-a/tasks/<id> 的 state、hold_reason | POST /api/phase-a/mock/execute 只领取满足账号、确认、健康出口、活动 runtime 和租约条件的 queued 任务;policy_hold/needs_confirmation 不会自动重试 |
|
||||
| Mock 执行没有领取任务 | GET /api/phase-a/tasks/<id> 的 state、hold_reason | POST /api/phase-a/mock/execute 只领取满足账号、确认、已绑定出口健康(显式直连无此项)、活动 runtime 和租约条件的 queued 任务;policy_hold/needs_confirmation 不会自动重试 |
|
||||
| 停止 Compose 后浏览器仍在运行 | docker ps --filter 'name=^creatorhub-browser-' | 动态浏览器不由 Compose 管理;先通过「运行环境」停止/回收,再 docker compose stop,不要误删 Profile 卷 |
|
||||
|
||||
不要执行 docker compose down --volumes 作为普通排障手段;它会删除 PostgreSQL 数据卷。不要把控制面密码、网关令牌、代理密码、Cookie 或 token 写入仓库、截图、日志或审计查询。
|
||||
@@ -314,7 +316,7 @@ docker compose config --quiet
|
||||
docker compose up --detach --build
|
||||
```
|
||||
|
||||
镜像版本升级在页面「运行环境 → 升级」完成:平台会停止并删除旧容器(保留 Profile 卷),用新镜像引用与原指纹参数重建后启动;失败时直接重试即可,无需回滚。
|
||||
镜像版本升级在页面「运行环境 → 升级」完成:删除旧容器并保留 Profile,用新镜像与原指纹/binding 重建,账号可运行才启动,否则保持停止态;无自动回滚。失败先查看记录,人工重试由现有流程调和,不承诺所有失败都可直接重试消除。当前 upgrade 无条件要求有效代理出口,直连环境会失败;rebind 也不支持空出口切回直连。此为现状限制,不是新产品范围裁决。
|
||||
|
||||
数据库迁移只支持安全前进,不提供自动破坏性回滚。需要同时恢复旧代码和更新前数据库时,修改下面两个变量后**整块执行一次**;不要逐行或拆块执行。预检、恢复演练、动态容器停止、停服、主库恢复、提交切换和启动都位于同一个 fail-fast subshell 中。
|
||||
|
||||
|
||||
+461
@@ -0,0 +1,461 @@
|
||||
# CreatorHub 需求细化与验收标准
|
||||
|
||||
> 版本:v1.2 · 2026-09-12
|
||||
> 状态:业务范围已逐项确认;本文是实现与验收依据,不代表功能已经完成。
|
||||
> 现状基线:`feat/plan01-implementation` 基于 `main@1fbf126`,已同步远程;本轮完成一批本地 G1.1/G1.2 实现与离线验证,未完成真实平台验收。
|
||||
> 优先级:本需求高于现有实现及旧产品规划;遇到平台能力不足或新的业务歧义,必须向使用者确认,不得自行删减、替换或假装成功。
|
||||
|
||||
## 1. 目标、范围与完成定义
|
||||
|
||||
在现有账号、浏览器环境与代理管理基础上,形成四个可实际使用的模块:
|
||||
|
||||
1. **竞品分析**:导入竞品账号,发现新作品,监测指标,筛选爆款,选择素材并生成仿写文案。
|
||||
2. **账号管理**:登记实名与登录资料,管理账号状态、大号与小号关系,监听大号收到的互动并按策略响应。
|
||||
3. **环境管理**:一账号一环境,自动配置稳定指纹,手工管理与分配代理。
|
||||
4. **工作台**:采集自有与竞品账号的一级评论,识别线索,人工回复/私信;展示并操作所选平台账号的私信会话。
|
||||
|
||||
### 1.1 交付范围
|
||||
|
||||
- 平台为**抖音、小红书**。分阶段实现:先验证抖音完整流程,再完成小红书;最终交付必须逐平台验收,不能以“能登记小红书账号”替代业务功能。
|
||||
- 本文及相关旧文档同步是需求基线;当前工作树已补充一批 CreatorHub 本地实现,但不部署、不操作真实平台账号,也不把离线结果当作平台成功证据。
|
||||
- 后续功能交付以第 8 节的可观察结果为准,既要覆盖成功,也要覆盖缺数据、重复操作、失败和恢复。
|
||||
- 平台不提供的事件、UID、指标或动作能力属于**待验证的外部依赖**,不是默认排除项。必须给出证据并由使用者决定替代或范围调整;未经确认,该项不能通过验收。
|
||||
|
||||
### 1.2 统一术语
|
||||
|
||||
| 名称 | 含义 |
|
||||
| --- | --- |
|
||||
| 自有账号 | 在本系统登记、由使用者登录操作的平台账号 |
|
||||
| 竞品账号 | 通过链接加入监测的目标账号,不要求也不收集其登录凭据 |
|
||||
| 大号 | 开启大号模式、接收互动并配置响应策略的自有账号 |
|
||||
| 小号 | 被一个同平台大号选中,用于执行响应动作的自有账号 |
|
||||
| UID | 平台提供的稳定用户标识;不得用昵称、头像或显示名称代替 |
|
||||
| 账号状态 | 人工维护的正常、禁言、封禁、注销等业务状态,不等于登录状态或环境状态 |
|
||||
| 自动响应 | 大号收到互动后,系统按启用策略选择一个小号执行一个动作 |
|
||||
| 人工发送 | 使用者选择账号、确认目标和内容后发送;与自动响应分开记录 |
|
||||
| 结果不明 | 已尝试执行,但未获得足以判断成功或失败的证据;不得标为成功或自动补发 |
|
||||
|
||||
## 2. 当前系统与需求差距
|
||||
|
||||
以下来自代码检查,**不是本轮真实平台验证结论**。路径用于定位现状,不冻结后续实现方式。
|
||||
|
||||
| 范围 | 已有基础 | 本需求需要补齐或改变 | 代码依据 |
|
||||
| --- | --- | --- | --- |
|
||||
| 页面入口 | 账号、任务、审计、环境、代理、镜像、网关等页面 | 竞品池、作品、素材仿写、评论线索、响应策略、私信会话尚无完整入口 | [页面路由](../web/src/main.jsx) |
|
||||
| 账号 | 平台账号 ID、标签、Cookie、暂停/恢复等 | 实名资料、登录用户名/密码、备注、人工业务状态、自动登录与大小号关系 | [账号页面](../web/src/AccountsPage.jsx)、[账号存储](../internal/phasea/store.go)、[账号接口](../cmd/control-plane/phasea.go) |
|
||||
| 平台范围 | 登记项还包含公众号、快手 | 新业务仅承诺抖音、小红书;其他登记项不是业务能力验收结果,也不因此要求删除无关已有功能 | [账号页面](../web/src/AccountsPage.jsx) |
|
||||
| 作品读取 | 有抖音连接器、指标字段与测试 | 连接器只核验登录者自身、读取首批 20 条,未接成运行中的竞品采集链路;需目标账号解析、分页、保存、查询和定时更新 | [抖音连接器](../internal/douyin/connector.go)、[连接器测试](../internal/douyin/connector_test.go)、[网关读取限制](../cmd/docker-gateway/douyin.go) |
|
||||
| 指纹与环境 | 结构化指纹、独立 Profile、启动/停止/升级及代理接入 | 默认固定 seed 不是自动分配;需首次自动生成、地区匹配及稳定性验证 | [环境页面](../web/src/BrowsersPage.jsx)、[指纹参数](../internal/hub/fingerprint.go)、[环境存储](../internal/hub/environment.go) |
|
||||
| 代理 | 添加、列表、手动检测、停用、实际转发 | 补齐编辑、删除、重新启用及引用约束;不增加自动轮换 | [代理页面](../web/src/NetworkExitsPage.jsx)、[代理转发](../cmd/docker-gateway/proxy.go) |
|
||||
| 任务与发送 | 有草稿确认、任务记录、Mock 执行 | 不能作为真实回复、私信、点赞、关注、转发成功的证据;需接通实际平台执行及结果核验 | [任务页面](../web/src/TasksPage.jsx)、[任务接口](../cmd/control-plane/phasea.go) |
|
||||
| 事件、线索、私信、AI | 未发现完整可运行链路 | 均需新增业务能力,不能把旧文档、类型定义或模拟返回记为已实现 | [页面路由](../web/src/main.jsx)、[抖音连接器](../internal/douyin/connector.go) |
|
||||
|
||||
### 2.1 已确认的冲突裁决
|
||||
|
||||
- [旧探索方案](product/compliance-product-plan.md)排除了自动评论、自动关注、批量私信等;本文明确纳入**由互动触发、按用户冷却限制的单次自动响应**。不得沿用旧排除项阻止实现,也不得扩展为无差别群发。
|
||||
- 旧流程强调每次草稿人工确认;本文的自动响应由人工配置、启用策略后自动执行,工作台与私信页面则逐次人工确认。不能混为一个审批流程。
|
||||
- 旧读取代码仅支持登录账号自身与首批作品;本文要求竞品账号和完整范围内分页,后续须接通真实能力,不能只在界面标注支持。竞品仅采公开可访问或已授权的数据,不要求竞品登录,也不以旧“仅自有账号”限制删减竞品范围。
|
||||
- 账号实名状态、业务状态、登录状态分别记录;禁止把“授权成功”当作“已实名”,或把一次网络错误当作“封禁”。
|
||||
- 自有账号的互动和私信采用**事件监听**,不以定时轮询替代;竞品作品与评论仍按固定计划采集。现有账号/环境列表不主动检测、不轮询实时状态的约定保持不变。
|
||||
|
||||
### 2.2 文档职责与现状边界
|
||||
|
||||
- 本文规定目标业务;[旧探索方案](product/compliance-product-plan.md)仅保留历史背景,其阶段 A 离线 Mock 不等于本文 G0/G1。尚未实现是开发差距,不是计划缺陷。
|
||||
- [架构说明](architecture/container-control.md)集中记录当前生命周期 API;[部署说明](deployment.md)只验证当前可运行代码,不证明本文四模块已验收。当前控制面仍有 Basic Auth;本期开发目标不新增认证、RBAC 或认证 profile,本轮也不删除现有认证。
|
||||
|
||||
## 3. 竞品分析
|
||||
|
||||
### C1. 账号导入与监测管理
|
||||
|
||||
- 用户输入抖音或小红书账号主页链接;平台可解析的作品分享链接可先解析作者,再展示确认。无法确定作者时要求填写主页链接,不猜测账号。
|
||||
- 保存前展示平台、账号昵称、稳定标识、主页链接及可取得的头像;使用者确认后加入监测。缺少稳定标识不得创建成功。
|
||||
- 以“平台+目标账号稳定标识”去重;短链接、长链接指向同一账号时不产生两条监测记录。
|
||||
- 支持列表查询、启用/暂停监测及手动更新。暂停只停止后续采集,已采数据保留;不默认扩展批量导入、自动发现相似账号。
|
||||
- 首次默认回溯最近 **30 天**作品,回溯天数可在统一设置中修改。采集全部符合范围且平台可提供的作品,不限制为首页或固定 20 条;可展示进度并在中断后继续。
|
||||
- 作品以“平台+作品标识”去重,展示作者、标题/正文、发布时间、原链接、可取得的封面、点赞/评论/转发数及最近采集时间。
|
||||
- 不可获取的指标显示“不可获取”,未采集显示“待采集”,不能填 0。平台真实返回 0 则显示 0;指标以当前真实值更新,不强制只能增加。
|
||||
|
||||
### C2. 两种独立的检查计划
|
||||
|
||||
| 配置 | 已确认默认值 | 约束 |
|
||||
| --- | --- | --- |
|
||||
| 历史回溯天数 | 30 天 | 正整数;定义首次采集范围,不等于数据删除期限 |
|
||||
| 账号新作品检查间隔 | 30 分钟 | 正数;与作品指标计划分开 |
|
||||
| 指标初始间隔 | 1 小时 | 正数 |
|
||||
| 指标间隔倍数 | 2 | 大于 1,作品越旧检查越少 |
|
||||
| 指标最大间隔 | 24 小时 | 不小于初始间隔 |
|
||||
| 指标监测年龄 | 发布满 30 天停止 | 正数;停止采集不删除历史数据 |
|
||||
|
||||
- 以上为一组全局设置,不增加每账号覆盖、热度自适应或公式编辑器。
|
||||
- 以作品发布时间为起点,间隔为 `min(初始间隔 × 倍数^n, 最大间隔)`,`n` 从 0 开始;累计时刻是发布时间后 **1、3、7、15、31、55、79……小时**。
|
||||
- 计算统一使用 UTC 时刻和固定时长,1 天 = 24 小时,不按本地自然日或夏令时换日;界面可转为本地时间但注明时区。首次回溯以开始时刻 `T` 固定窗口 `[T - 回溯时长, T]`,分页期间不滑动窗口。
|
||||
- 账号启用时立即检查新作品,以该次启用时刻为固定间隔起点;一级评论补充采集同理。正常到期条件为 `当前时刻 >= 计划时刻`,同一计划点只启动一次;暂停不启动,恢复或重启最多采一次当前结果,再取严格晚于当前时刻的计划点。
|
||||
- 首次发现先采一次当前指标,再等待该作品严格晚于当前时刻的计划点;发现时恰好到期,这次当前采集即覆盖该点,不再重复。已经错过的历史时刻不逐次补跑。
|
||||
- 派发前再次检查发布年龄;`当前时刻 >= 发布时间 + 监测年龄` 时不再安排自动指标检查(与计划点重合时停止优先)。首次回溯到比监测年龄更旧的作品,仍采初始资料和当前可得指标,但不创建持续指标计划。
|
||||
- 暂停、进程重启或短暂中断后,每部作品最多补一次当前采集,不集中回放历史计划;已有作品不重复入库。登录失效、验证挑战等需人工处理的阻断不得靠重试消除。
|
||||
- 修改设置后以保存时刻重设账号/评论未来检查起点,作品指标仍以发布时间计算未来点;不重写历史指标时间,也不补造过去的数据。
|
||||
- 缺少可靠发布时间或时区、时间无效/位于未来时,资料标为“发布时间待核验”,不猜日期、不把发现时间当发布时间,不纳入已确认回溯结果或安排年龄相关计划;保留待核验项及范围不完整提示。获得可靠时间后按当前窗口及未来计划处理,不回填错过的采集。
|
||||
|
||||
### C3. 爆款筛选
|
||||
|
||||
- 支持平台、监测账号、作品发布时间,以及点赞、评论、转发最低值筛选。
|
||||
- 只对用户填写的条件进行判断,所有已填写条件**同时满足**才入选;数值阈值为非负数,等于阈值也满足。
|
||||
- 未配置某项阈值不限制该项;配置了阈值但对应指标不可获取,则不进入该筛选结果,并说明缺少指标。
|
||||
- 不增加系统综合评分、增长预测、AI 爆款推荐或排行榜算法。“爆款”在本期就是满足用户筛选条件的作品。
|
||||
|
||||
### C4. 素材与仿写:两次人工确认
|
||||
|
||||
固定流程:
|
||||
|
||||
`标题/正文 → 人工选取素材 → 下载视频、提取音频、语音转写 → 人工确认是否仿写 → 系统生成标题与口播文案`
|
||||
|
||||
- 未被人工选取的作品只获取作品资料,不自动下载媒体、转写或生成文案。
|
||||
- 选取后可查看各步骤进度、视频、音频、转写文本及失败原因;下载保留平台可获取文件,不包含去水印、视频画面 OCR、配音合成或剪辑。
|
||||
- “语音转写”是对音轨中说话内容的识别,不能拿作品描述冒充;“分析”用于理解现有标题、正文与转写,不额外输出未经要求的复杂分析报告。
|
||||
- 无音轨或无可识别语音时明确标注,不编造转写;其他下载/转写失败显示具体失败步骤,不能标成全部素材完成。
|
||||
- 素材准备成功后,用户可放弃或填写仿写要求并确认。下载或转写失败时,必须先解决失败步骤才允许仿写,不提供“部分素材继续”分支。已确认无音轨/无说话内容属于明确的素材结果,不等于任务失败,仍须如实展示。
|
||||
- 输出仅为**可编辑的标题与口播文案**,保留来源作品、采用的素材及用户要求;不自动发布、不生成视频、不做多代理创作流程。
|
||||
- 重复点击同一次选取/确认不得重复启动同一任务。失败允许人工重试失败步骤,已有成功素材不无故重新下载;AI 失败不得用原文或空内容冒充成功。
|
||||
- 作品/评论分页与媒体下载是不同链路;任务按下载、提音、转写、生成保存步骤状态和产物引用,页面按需预览,不把媒体二进制塞进通用 JSON 读取响应,也不靠放大当前 JSON 上限冒充媒体支持。最终须用超过一页数据及真实媒体证明可用;当前读取限制只是后续接通点。
|
||||
- 空间不足、文件过大或服务配额不足须明确失败步骤、原因和已有产物;未经用户授权不得自动删除素材腾空间,不静默丢弃成功产物。
|
||||
|
||||
## 4. 账号管理与自动响应
|
||||
|
||||
### A1. 账号资料与状态
|
||||
|
||||
| 字段 | 要求 |
|
||||
| --- | --- |
|
||||
| 平台 | 抖音或小红书;和平台稳定账号标识共同确定账号身份 |
|
||||
| 登录账号、密码 | 可选;与平台 UID 分开,密码输入后不由读取接口回显,也不进入列表、日志或错误信息 |
|
||||
| 实名状态、姓名、身份证 | 人工记录,用于区分账号;不校验平台真实实名、不代办认证、不上传身份证资料 |
|
||||
| 备注 | 用户补充说明,不用标签代替 |
|
||||
| 账号状态 | 人工维护正常、禁言、封禁、注销;需要其他状态时先确认,不设计可编程状态系统 |
|
||||
| 大号模式 | 开关;开启后可管理本大号的小号、响应策略、冷却时间与 AI 回复要求 |
|
||||
| 登录情况 | 独立展示已登录、需登录、登录失败/待人工处理等实际结果与时间,不推断处罚状态 |
|
||||
|
||||
- 支持账号资料新增、查看、编辑;必填平台及能区分账号的标识,已获得平台 UID 后检查身份重复和登录一致性,不通过改昵称掩盖冲突。
|
||||
- 登录密码允许由新增/编辑请求输入并进入现有凭据保存流程,账号资料仅关联凭据;读取只显示是否已配置,编辑空白不覆盖已有密码。当前接口只接收 Cookie,不代表密码能力已实现,也不能以“API 禁止接收密码”阻断本需求。
|
||||
- 实名资料只做输入类型、长度等基本校验;不把人工记录包装成已核验身份,不要求用户为运行普通功能提交身份证证据。
|
||||
- 正常账号按实际登录及平台能力执行。**非正常账号暂停自动动作**;禁言账号禁止人工评论、私信及带文案转发;封禁、注销账号不参与采集和发送。已有数据仍可查看,人工登录/检查入口保留。
|
||||
- 账号恢复正常后需人工重新启用受影响策略,不补发暂停期间的历史互动。登录失败不擅自修改上述业务状态。
|
||||
|
||||
### A2. 登录
|
||||
|
||||
- 已存在有效登录时复用;未登录且提供用户名与密码时尝试自动登录,否则直接进入可见浏览器人工登录。
|
||||
- 自动登录失败显示真实原因:例如凭据错误、平台不支持该登录方式、验证码/扫码/设备确认、网络失败或页面变化;未知原因明确写“无法确认”,不能猜测。
|
||||
- 失败后保留同一环境交用户人工处理,不循环尝试、不自动更换账号/代理/指纹,也不绕过验证码。
|
||||
- 登录后核对实际平台账号身份;与选定账号不一致时停止该账号任务并提示纠正,不能把别的账号登录结果保存为成功。
|
||||
|
||||
### A3. 大小号关系与策略
|
||||
|
||||
- 一个小号只归属一个**同平台**大号;不能自己关联自己,大号不能再作为其他大号的小号,不建立多层关系。
|
||||
- 大号可关联多个小号,并配置有明确先后顺序的策略。每条策略包含:启停、适用事件类型、一个执行小号、**一个动作**及动作所需内容。
|
||||
- 事件是大号**收到**评论、点赞、转发、关注等互动,不是跟随大号主动操作。以上四类全部纳入,不因平台获取困难自行删除;其他事件类型须说明含义后确认。
|
||||
- 同一事件按顺序找到第一条匹配、账号可用且目标明确的策略执行。较早策略因登录/业务状态/缺少目标而不可用时可检查下一条,并记录原因;一旦选中并开始执行,不再换小号或换动作补发。
|
||||
- 大号模式关闭、策略停用、关系调整时停止受影响的未执行动作;关系调整后需人工重新配置并启用。已发送动作不能假装撤回;在途动作实际结果继续保留。
|
||||
|
||||
| 响应动作 | 目标与必要条件 |
|
||||
| --- | --- |
|
||||
| 给用户发私信 | 互动者的稳定 UID;需要文本 |
|
||||
| 回复评论 | 事件中明确关联的评论;需要文本 |
|
||||
| 点赞评论或作品 | 策略明确选择评论或作品,事件中存在对应目标标识 |
|
||||
| 关注互动用户 | 互动者的稳定 UID |
|
||||
| 转发作品 | 事件中明确关联的作品;平台要求文案时还需文本 |
|
||||
|
||||
所有自动动作都必须另有互动者稳定 UID 供 A5 冷却使用,即使点赞/转发只需作品 ID 也不例外。缺少必要目标时不猜测、不搜索用户的其他作品代替。例如关注事件只有用户而没有评论,不能执行“回复评论”;只有聚合点赞数却没有互动者 UID 时,不能触发面向用户的响应。
|
||||
|
||||
### A4. 文本来源与 AI
|
||||
|
||||
- 需要文本的动作允许预填多条非空候选文本;每次随机选择其中一条。只有一条时直接使用,不要求轮换不重复。
|
||||
- 未填写候选文本时,使用 AI 按**大号统一的回复要求**生成。启用此类策略前必须具备有效 AI 配置及该大号回复要求。
|
||||
- AI 输入限于当前事件、相关作品/评论、允许使用的业务说明和回复要求;不新增知识库、长期记忆、多轮自动聊天。
|
||||
- AI 失败、内容为空或超出平台限制时停止本次响应并显示原因,不改用隐藏的默认话术、不截断后强发、不自动重发。
|
||||
- 用户内容是待分析材料,不应改变大号预设要求、执行账号或目标;保存实际选中文本或生成文本与执行结果的对应关系。
|
||||
|
||||
### A5. 同一用户只自动响应一次
|
||||
|
||||
- 冷却范围为**平台+大号+互动用户 UID**,该大号下所有小号、所有事件和所有动作共同计算。
|
||||
- 大号可配置正数冷却时间,默认 **24 小时**;不能把 0 解释成禁用冷却。
|
||||
- 从选中小号、开始执行时占用响应名额并计时。一个 UID 在冷却内不论触发什么事件,都只允许一次自动动作,不执行“关注后再私信”等组合。
|
||||
- 冷却检查和占用必须不可被并发穿透;服务重启、监听重连、策略重启、修改候选文本不能清除已占用的冷却。事件身份及永久去重按 A6;冷却到期只允许新事件,不允许旧事件重放。
|
||||
- 失败、AI 生成失败、结果不明均保留已经开始执行的冷却,不自动尝试下一个小号。没有匹配策略、账号不可用等尚未开始执行的情况不占用名额。
|
||||
- 修改冷却时长只作用于新开始的响应;已占用名额保留其原到期时间,避免修改设置意外提前解锁。
|
||||
- **人工回复和人工私信不受自动响应冷却限制**,不拿自动冷却阻止用户逐次确认的发送;必须明确标识人工/自动来源,仍防止同一次提交重复发送。
|
||||
|
||||
### A6. 事件监听与接近实时
|
||||
|
||||
- 自有账号登录后由后台监听大号互动和私信新消息;关闭页面不停止后台监听。私信事件更新会话,不触发自动聊天;竞品采集不依赖竞品登录。
|
||||
- **事件身份**为“平台+接收账号+平台稳定事件 ID”;也可使用经真机验证能唯一定位事件、跨重连/重启仍稳定的游标。普通翻页游标不当然是事件身份;不得用昵称、时间/内容哈希猜唯一。缺少可靠身份属于 G0 阻塞,不启用该类自动响应。
|
||||
- 首次监听及每次重新启用先保存已验证的历史基线(平台事件时间边界或可验证的事件位置),基线建立期间不执行自动动作;从确定的新事件边界开始响应,旧通知只作历史展示。平台没有时间标识时必须证明游标/事件位置可区分新旧;两者都没有则标为边界不明,不猜测。
|
||||
- 持久保存已接收事件的最小身份、边界归类和处理结论(含未匹配、跳过、失败与结果不明),同一旧事件永不因策略修改、冷却到期或重启再次执行;该最小去重记录不随冷却到期删除,不要求永久保存原始消息全文。
|
||||
- 断连、登录失效、解析失败可见;恢复时核对持久基线和平台恢复位置,重复只更新原记录。**迟到/待核验事件**指恢复时取得的断连期间事件,或无法证实发生在持续启用的新事件边界内的事件,不以“晚了几秒”任意划线。默认只记录、不补发自动动作;是否能可靠恢复、缺失范围以及恢复事件是否允许触发,须在 G0 提交平台证据并取得用户批准后明确,不默认授权历史补发。停用期间及启用前事件始终不触发。
|
||||
- 进程重启按断连恢复处理,不清除基线、事件去重或冷却;无法确认恢复连续性时显示数据缺口,从重新确认的新边界开始。私信历史可按平台能力恢复显示,但不触发发送;不能以重连成功声称事件无遗漏。
|
||||
- **平台→后台的事件监听**与**后台→页面的业务更新**分层验收:前者不得用固定轮询或 Mock 替代;后者采用一种适合现有服务的推送方式即可,不要求 SSE/WS 双实现,不引入新基础设施。禁止账号/环境列表实时状态探测不等于禁止业务事件推送。
|
||||
- 监听正常时,从系统收到事件起 **5 秒内开始处理**;已打开且正常连接的相关页面 **30 秒内可见**。自动响应展示接收/处理中,不承诺 30 秒内 AI 或动作完成。页面关闭、离线时不测页面可见时限;重新打开先读取持久结果,再接后续更新,页面断连须可见,不能记成准时展示。
|
||||
- 分别记录平台事件时间(若提供)、系统接收、处理开始、已打开页面展示及动作结束;缺少平台时间则来源延迟不可测,不填 0。只有系统处理快不证明平台投递及时;每类事件、UID、恢复边界和接近实时能力须经真机证据验收,缺口交用户裁决而非自行删除。
|
||||
|
||||
## 5. 环境与代理
|
||||
|
||||
### E1. 自动配置环境指纹
|
||||
|
||||
- 一账号一环境,首次创建自动生成不同 seed 及相容参数;沿用现有指纹 Chromium 与独立 Profile,不再要求用户手填所有参数。
|
||||
- 语言、时区按所选代理的明确地区匹配;地区未知或不足以唯一判断时显示待确认并要求人工选择,不默默填入猜测地区。
|
||||
- 指纹与 Profile 在重启、普通升级后保持;必要手工调整只在环境停止后进行,并显示影响。不每次启动自动换指纹。
|
||||
- 指纹必须在真实浏览器中生效,不能只验证保存了 JSON;不同账号不串 Profile 或登录资料。
|
||||
- 不承诺“无法识别”“永不封号”,不开发额外反检测评分或新指纹内核。
|
||||
|
||||
### E2. 代理管理
|
||||
|
||||
- 支持新增、查看、编辑、删除、停用、重新启用及**手动检测**;支持 HTTP、HTTPS、SOCKS4、SOCKS5 与协议允许的认证配置。
|
||||
- 显示名称、协议、地址、端口、启停状态、可取得的地区/出口 IP、最近一次检测时间和结果。历史检测不是实时状态,不自动轮询检测。
|
||||
- 一个环境指定一个代理,多个环境可共用;绑定代理时明确使用哪个记录。环境原有的显式直连能力不作为故障替代路径。
|
||||
- 更换代理、修改正在被环境使用的连接参数前,必须停止受影响环境;再次启动使用用户明确选定的配置。
|
||||
- 被环境引用的代理不能直接删除,先解除或更换。停用后不能用于新启动;被运行环境使用时提示先停环境,避免管理状态与实际连接不一致。
|
||||
- 代理失败显示原因,不静默直连、不自动换代理,不增加批量导入、供应商采购、自动轮换或代理池调度。
|
||||
|
||||
## 6. 工作台
|
||||
|
||||
### W1. 评论来源与采集
|
||||
|
||||
- 来源可区分自有账号、已启用的竞品账号;默认覆盖其最近 30 天作品,复用 C2 的回溯天数及 30 分钟更新间隔。
|
||||
- 本期**只采集一级评论,不采集楼中楼回复**;即使自有账号事件监听能及时发现评论,也不取消这一范围内的定时补充采集与去重。
|
||||
- 分页获取范围内全部平台可提供的一级评论,支持中断后继续;不能以首屏、热门评论或前 N 条宣称完整。
|
||||
- 展示来源类型、平台、作品、评论内容、作者 UID/可得昵称、发表时间、采集时间;没有 UID 可查看文字,但不可执行面向该用户的动作。
|
||||
- 同一平台评论只保存一个逻辑对象;来源同时命中自有和竞品范围时保留来源关联,不生成重复评论或重复线索。删除、隐藏或平台限制导致不可获取时如实说明。
|
||||
|
||||
### W2. 主题、关键词及 AI 线索规则
|
||||
|
||||
每条规则只包含:名称、启停、来源范围、内容主题说明、包含关键词、排除关键词、AI 线索判定说明。
|
||||
|
||||
执行顺序固定:
|
||||
|
||||
1. **作品主题**:AI 根据作品标题与正文判断是否符合该规则的主题,不先下载整个视频做主题分析。
|
||||
2. **评论关键词**:作品主题通过后,评论包含任一包含词且不含任何排除词才通过;词按文本包含匹配,不增加正则表达式编辑器。
|
||||
3. **评论 AI 判断**:仅对前两步通过的评论判断是否符合线索要求;全部通过才标记线索。
|
||||
|
||||
- 关键词采用确定的原文子串匹配:保存时仅去除每个词首尾的普通空格、制表符、CR/LF,空词拒绝;不改变评论原文。区分大小写,不折叠内部空白、不合并全半角、不做 Unicode 规范化。例如 `AI` 不匹配 `ai`,`买 车` 不匹配 `买车`,`é` 不匹配 `e` 加组合重音;包含与排除使用同一规则,不增加可配置归一化系统。
|
||||
- 必填主题、至少一个包含词和 AI 判定说明,排除词可空。规则可创建、编辑、启停,禁用规则不再参与新判断。
|
||||
- 同一评论命中多条规则时仍为一条线索,展示所有命中规则、关键词和简短判定原因,不复制成多条待联系对象。
|
||||
- 显示未分析、非线索、已识别线索、分析失败等真实结果。AI 不可用、结果无法解析或依据不足不能标成“无符合线索”。
|
||||
- 规则修改不偷偷重写历史结论;记录当时规则内容,用户可明确对已采评论重新分析,并展示最新结果,不增加复杂版本管理界面。
|
||||
- 线索可按来源、平台、账号、规则、时间筛选;本期不增加销售漏斗、CRM、自动打分和跟进任务系统。
|
||||
|
||||
### W3. 人工回复与私信
|
||||
|
||||
- 从评论或线索选择发送账号、确认目标,输入/编辑文本后显式发送评论回复或向评论作者发私信。
|
||||
- 只能选择同平台且具备相应操作条件的自有账号;执行前核对实际登录身份和目标。平台不允许跨账号回复时明确失败,不假装已发送。
|
||||
- 用户人工确认的操作**不受 A5 自动冷却限制**;线索识别本身不自动发送。
|
||||
- 成功必须有平台侧可核验证据;未返回确认则标为结果不明,提示先检查原生平台,不能自动重发。
|
||||
- 一次人工确认在提交前取得持久操作标识,固定账号、目标和实际文本;双击、网络重试、页面重开与进程重启均查询/提交同一标识,不再生成第二次发送。服务端保证同标识至多执行一次,不能只靠按钮禁用。
|
||||
- 结果不明只提供查询/人工核验并记录证据,不将“重试”变成重新发送;确认未发送也不重用原操作触发。用户确需另发时须重新核对账号、目标和文本、明确再次确认,产生新的操作标识。记录两次操作关系及原因,不能把新发送伪装成结果核验。
|
||||
|
||||
### M1. 私信会话
|
||||
|
||||
- “登录用户”指当前选择的**已登录平台账号**,不是 CreatorHub 的登录用户名。支持切换账号,展示会话列表、对方、最近消息、时间和消息详情。
|
||||
- 详情区分收发方向、文本、时间及发送状态;历史消息按平台可提供范围加载,不承诺恢复已删除、不可见或平台未返回的完整历史。
|
||||
- 新消息通过 A6 的监听更新,不需要持续手动刷新;切换账号和查看历史时可主动读取。监听断开时展示状态并保留已有消息。
|
||||
- 支持人工输入、确认并发送文本,遵循 W3 的身份、状态、重复提交与结果核验要求,不受自动冷却限制。
|
||||
- 不新增群聊管理、附件发送、已读回执、AI 自动聊天。平台收到非文本消息时至少标明消息类型/不支持展示,不当作空白文本或丢失会话。
|
||||
|
||||
## 7. 必须遵守的最小实现约束
|
||||
|
||||
### 7.1 保留必要能力,不扩展通用平台
|
||||
|
||||
- 复用当前 Go 控制面、Docker 网关、数据库、浏览器环境以及 React/Refine/shadcn/ui;先核实已安装依赖能力,再决定是否新增依赖。
|
||||
- 为实际需要的采集、监听、执行和 AI 调用分别划清职责,但**不预建插件市场、通用工作流引擎、任意条件编辑器或多代理框架**。
|
||||
- 先完成一个平台、少量真实账号的完整流程,不为了假定的海量并发引入微服务拆分、额外 MQ、Redis、分布式调度或多租户系统。确需新增基础设施时说明已有方案不足并确认。
|
||||
- 复用已有持久任务与记录能力前,必须确认它能处理真实任务;不能把 Mock 换个名字接到界面。不继续保留已被替代的旧业务代码路径或兼容层。
|
||||
- 指数监测用确定的间隔规则;冷却用明确的用户范围;策略用有序单动作列表;线索用固定三步判断。不要实现能表达任意业务的通用规则系统。
|
||||
- AI 仅服务于已确认的语音转写/素材理解、仿写、主题与线索判断、无候选文本时的单次响应;配置只满足真实调用,不增加模型市场、自动供应商切换或隐藏降级。
|
||||
|
||||
### 7.2 不允许以“简单”为由省略
|
||||
|
||||
- 不能省略真实平台接通、分页、断连可见、身份核对、重复事件去重、并发冷却、人工确认、失败与结果不明区分。
|
||||
- 关键记录能关联平台、账号、作品/评论/事件、命中策略或规则、所选小号、人工确认和最终结果;已有任务/日志页面能承载的内容不另建监控系统。
|
||||
- 记录排查所需的时间和原因,但不把密码、身份证、Cookie、代理凭据或无关完整私信写入日志。
|
||||
- 只读采集的临时中断可按下一计划或人工操作恢复;明确的登录/平台验证阻断需人工解决;已经开始的自动写动作及结果不明动作不自动重试。
|
||||
- 同一执行账号的所有写操作(人工回复/私信及自动动作)统一串行协调,不只锁小号自动任务;实际写入前重新核对停用、业务状态、当前登录身份及目标,自动动作另核对关系/策略。等待执行时条件变化即阻止未开始的操作;已开始结果如实保留,不以停止冒充撤销。并发竞争、重启恢复须有可重复测试。
|
||||
- 表格、筛选、操作按钮保持克制,沿用现有布局与 RemixIcon;不另造大屏、营销式卡片或装饰性流程编辑器。键盘操作、加载/空/错误/禁用状态必须可用。
|
||||
|
||||
### 7.3 成熟产品参考的使用边界
|
||||
|
||||
参考 Hootsuite 的[消息条件自动处理](https://help.hootsuite.com/s/article/automatic-actions)、[统一收件箱](https://help.hootsuite.com/s/article/inbox-faq)及[关键词包含匹配](https://www.hootsuite.com/whats-new/partial-keyword-matching-for-inbox-automations):采用常规的会话列表、保存文本、有序条件判断和可解释分类,不复制其完整企业功能。
|
||||
|
||||
这些资料仅作产品行为参考,**不证明抖音/小红书提供相同能力**,也不授权复制源码或界面资产。本次未引入上游代码。
|
||||
|
||||
### 7.4 页面地图与操作闭环(推荐路由,不代表已实现)
|
||||
|
||||
沿用现有 HashRouter、Layout、表格及抽屉/页签;下列路径省略 `#`。主导航为竞品分析、账号管理、环境管理、工作台;任务/审计保留共用入口,镜像/网关留在现有环境管理入口。设置只含 C2 采集计划与**批准后**的 AI/转写调用配置,不建模型市场。
|
||||
|
||||
| 页面与推荐入口 | 列表、详情及关键字段 | 编辑、按钮与跳转 | 对应验收 |
|
||||
| --- | --- | --- | --- |
|
||||
| 竞品 `/competitors`,详情 `/competitors/:id` | 平台、昵称/稳定标识、主页、监测启停、最近/下次采集、进度和失败;详情用“作品/采集记录”页签 | 导入链接→解析预览→确认保存/取消;启用/暂停、手动更新;账号进入作品列表 | AC-C1、AC-C2、AC-C3、AC-U1 |
|
||||
| 作品(竞品详情作品页签,跨账号筛选复用同一列表) | C1 字段、C3 筛选、多页加载、已采页/条数及总量未知提示;详情展示原文、指标时间、下一指标计划/停止原因 | 筛选/清空、分页、打开原平台、选取素材;详情抽屉返回保留筛选与页码,进度不以首屏当完成 | AC-C2、AC-C4、AC-C5、AC-C6、AC-U1 |
|
||||
| 素材(作品详情“素材/文稿”页签) | 选中来源、分步状态、视频/音频预览、转写、无音轨/无语音结果、产物引用与失败原因 | 第一次确认选取后才准备;只重试失败步骤;准备完成后填要求并第二次确认仿写/放弃;标题/口播编辑、保存,保存失败保留输入,无发布按钮 | AC-C7、AC-C8、AC-C9、AC-C10、AC-U2 |
|
||||
| 账号 `/accounts`、`/accounts/:id` | A1 资料、业务/登录/环境状态分列;详情“资料/登录/大小号与策略/监听记录”页签 | 新增/编辑抽屉、保存/取消;密码只显示已配置;打开绑定的同一浏览器人工登录、重核身份,冲突显示期望/实际标识并停止;跳转环境与任务 | AC-A1、AC-A2、AC-A3、AC-U3 |
|
||||
| 大小号与策略(账号详情页签) | 同平台小号归属、策略顺序/事件/执行号/单动作、候选文本、大号 AI 要求、冷却时长与占用记录 | 大号开关、关联/解除、策略编辑/启停、上移/下移、保存/取消;文本列表增删;缺 UID/目标/AI 条件显示禁用原因;监听记录可跳转事件任务 | AC-A4、AC-A5、AC-A6、AC-A7、AC-A8、AC-A9、AC-A10、AC-A11、AC-A14、AC-U3 |
|
||||
| 环境 `/browsers`、`/browsers/:id`;代理 `/network-exits`、`/network-exits/:id` | 账号绑定、指纹、代理地区、历史检测时间和状态;代理引用列表 | 创建/启动/停止/升级/回收保持显式动作;停止后修改、待定地区人工选择;代理增改删/停启/手动检测,引用冲突跳转相关环境。回收不宣称永久删除 | AC-E1、AC-E2、AC-E3、AC-E4、AC-E5、AC-U1 |
|
||||
| 评论/线索 `/workbench` 的“评论/线索/规则”页签 | W1 字段、W2 筛选、分析状态、命中原因;评论详情展示来源作品与原规则依据 | 规则新增/编辑/启停;明确选择已采评论范围后确认重新分析,展示进度/失败;回复/私信抽屉选择同平台账号、目标/文本预览并确认;跳转作品、账号、任务 | AC-W1、AC-W2、AC-W3、AC-W4、AC-W5、AC-U4 |
|
||||
| 私信 `/workbench` 的“私信”页签 | 顶部账号选择器、会话列表及消息详情双栏;收发方向/时间/发送结果、历史范围、非文本类型、监听连接状态 | 账号/会话切换隔离请求与草稿;旧请求返回不能覆盖新账号,草稿不带到别的目标;切换有未保存文本时提示保留当前并取消切换或放弃再切换;发送前确认,历史加载/读取失败可重试 | AC-M1、AC-M2、AC-M3、AC-U5 |
|
||||
| 任务 `/tasks`、`/tasks/:id`,关联 `/audit` | 来源人工/自动、操作/事件标识、账号与目标、策略/规则、实际文本、步骤/时间、证据引用、失败/结果不明 | 由任一业务结果跳转任务,再跳回原作品/评论/会话;只读/素材失败可按规则重试,写结果不明仅“查看平台/核验结果”,新发送需回业务页重新确认 | AC-A12、AC-A13、AC-W5、AC-M3、AC-B1、AC-B2、AC-B3 |
|
||||
| 设置 `/settings` | 全局采集计划;获批 AI/转写服务、模型/版本、参数和配置记录;秘密仅显示是否配置 | 编辑/保存/取消;校验 C2 边界,保存计划提示只改未来;未批准调用配置不启用相关 AI 动作 | AC-C4、AC-C5、AC-A11、AC-U6 |
|
||||
|
||||
**各页共用交互约定**:首次加载显示加载状态,空数据区别于筛选无结果及读取失败;错误保留已有数据和输入并提供适用的重试。翻页失败停在原页;提交中禁用重复按钮、说明具体禁用原因,不把失败清成空列表。只读重试不触发写入;写入结果不明遵循 W3。表单离开、取消或切换页签前提示未保存内容,可留在原处继续编辑或明确放弃;可保存的资料/文稿先保存成功才离开,发送草稿不能以“保存”代替发送确认。键盘可达、焦点回到触发入口,详情返回保留原列表筛选和分页;无权取得的字段明确不可获取,不能编造默认值。
|
||||
|
||||
## 8. 验收清单
|
||||
|
||||
下表是功能验收要求。本轮仅执行本地单元测试、构建和静态诊断,未执行真实平台功能测试。每项记录平台、输入、操作、预期、实际结果和证据;“不支持/待验证”不得填写通过。
|
||||
|
||||
### 8.1 竞品与素材
|
||||
|
||||
| 编号 | 场景 | 必须观察到的结果 |
|
||||
| --- | --- | --- |
|
||||
| AC-C1 | 主页链接、可解析分享链接、重复链接、无效链接 | 正确确认目标;同账号不重复;无效/身份不明有具体错误,不创建假账号 |
|
||||
| AC-C2 | 在回溯范围内准备超过一页作品,包含窗口内外作品 | 页间无漏项/重复;范围边界按发布时间正确处理;首批 20 条不是完成标志 |
|
||||
| AC-C3 | 采集中断、恢复,暂停后到检查时间 | 可继续采集,已完成内容不重复;暂停不再启动新采集,历史数据仍可查看 |
|
||||
| AC-C4 | 使用可控时钟测试新作品与指标计划 | 新作品默认每 30 分钟检查;指标累计 1/3/7/15/31/55 小时,24 小时封顶,满 30 天停止;两种计划独立 |
|
||||
| AC-C5 | 首次发现旧作品、服务中断、修改计划 | 即时采一次后按未来时刻执行;不补跑全部错过计划,不制造历史指标 |
|
||||
| AC-C6 | 阈值以下/等于/以上、缺失指标、真实 0、指标下降 | 等值入选;所有已填条件同时满足;缺值不当 0;真实值正确更新 |
|
||||
| AC-C7 | 浏览爆款但不选取;选取后不确认仿写 | 前者没有媒体/AI 转写任务;后者只准备素材,不生成仿写稿 |
|
||||
| AC-C8 | 素材成功、无音轨、转写失败、重复点击 | 视频/音频/真实转写可核验;异常分步显示;一次确认不产生重复任务 |
|
||||
| AC-C9 | 素材准备后确认或放弃仿写 | 确认后才生成可编辑标题及口播文案;来源、用户要求对应;放弃不调用生成;不发生自动发布 |
|
||||
| AC-C10 | AI 失败或素材步骤失败 | 失败不冒充成功;下载/转写失败时禁止确认仿写,解决失败后才可确认;无音轨与任务失败明确区分 |
|
||||
|
||||
### 8.2 账号、自动响应与监听
|
||||
|
||||
| 编号 | 场景 | 必须观察到的结果 |
|
||||
| --- | --- | --- |
|
||||
| AC-A1 | 新增/修改资料,区分账号 UID、用户名、实名与业务状态 | 字段分别保存与显示;不伪称平台已实名;凭据不进入日志 |
|
||||
| AC-A2 | 有/无密码、有效登录、密码错误、验证码、身份不符 | 对应复用/自动尝试/人工登录;错误有原因,不循环尝试、不误认别的账号 |
|
||||
| AC-A3 | 正常→禁言/封禁/注销→正常 | 执行限制符合 A1;已有数据可查;恢复后不擅自重启策略或补发历史互动 |
|
||||
| AC-A4 | 自关联、跨平台、重复归属、大小号循环、调整关系 | 非法关系被拒绝;变更停用受影响策略,不产生错误账号动作 |
|
||||
| AC-A5 | 四类大号收到的互动 | 评论、点赞、转发、关注均用真实事件证明;大号主动操作不误触发;无 UID/目标明确提示 |
|
||||
| AC-A6 | 多条策略匹配、首条不可用、选中后失败 | 按优先顺序仅执行一个可用策略的单个动作;开始后不换小号补发 |
|
||||
| AC-A7 | 私信、回复、点赞评论/作品、关注、转发 | 各动作在真实平台确认目标、账号及结果;不相容事件/动作不猜目标,不能用一次私信证明所有动作可用 |
|
||||
| AC-A8 | 同 UID 多事件、多小号并发及跨动作 | 同一大号冷却内总共只开始一个自动动作;不是每个小号各执行一次 |
|
||||
| AC-A9 | 不同 UID、不同大号、到期边界、重复事件、重启 | 冷却范围正确;到期可响应新事件;旧事件永不重放;重启不清空冷却 |
|
||||
| AC-A10 | 失败、结果不明、AI 失败、修改冷却时长 | 已开始的名额保留到原到期;不补发;未开始的无匹配事件不占用冷却 |
|
||||
| AC-A11 | 多条候选文本、单条文本、空候选、无 AI 配置 | 文本来自候选集;空候选才使用大号 AI 要求;配置不足不能启用;生成失败/空/超长停止 |
|
||||
| AC-A12 | 监听建立、启用、断连、重连、登录失效 | 新互动被处理;历史通知不触发;断连/缺口可见;重连无重复动作,不用轮询冒充监听 |
|
||||
| AC-A13 | 监听正常时收到互动与私信 | 收到后 5 秒内开始处理、30 秒内页面可见;平台推送与最终动作耗时单独记录,不掩盖来源延迟 |
|
||||
| AC-A14 | 关闭大号模式、停用策略、账号状态改变与执行竞争 | 尚未开始的动作被阻止;已开始的实际结果可追踪,不假装撤销或再执行 |
|
||||
|
||||
### 8.3 环境与代理
|
||||
|
||||
| 编号 | 场景 | 必须观察到的结果 |
|
||||
| --- | --- | --- |
|
||||
| AC-E1 | 至少两个账号新建环境、重启、升级 | 自动生成不同 seed;单账号指纹/Profile 保持,真实浏览器参数生效,登录不串号 |
|
||||
| AC-E2 | 代理地区明确、未知、多时区 | 可确定时正确匹配;不确定时请求人工确认,不静默猜测 |
|
||||
| AC-E3 | 四类代理按合法配置连接、认证失败、网络失败 | 真实浏览器走选定出口;支持的认证方式有证据;失败不静默直连或轮换 |
|
||||
| AC-E4 | 编辑、停用、重新启用、删除被引用代理 | 运行引用须先停环境;引用未解除不得删除;重新启动使用明确配置 |
|
||||
| AC-E5 | 打开账号/环境/代理列表,点击手动检测 | 打开列表不触发实时状态探测或轮询;只在用户明确操作时检测,显示检测时间 |
|
||||
|
||||
### 8.4 评论线索与私信
|
||||
|
||||
| 编号 | 场景 | 必须观察到的结果 |
|
||||
| --- | --- | --- |
|
||||
| AC-W1 | 自有/竞品来源、多页评论、楼中楼、重复来源 | 范围内一级评论无页间遗漏/重复;不采楼中楼;来源正确,缺 UID 禁止定向动作 |
|
||||
| AC-W2 | 主题不匹配、主题匹配但无关键词、命中排除词、AI 否定/肯定 | 严格按“作品主题→关键词→评论 AI”执行;只有全部通过才生成线索 |
|
||||
| AC-W3 | AI 异常、规则禁用/修改、显式重新分析、多规则命中 | 失败不当非线索;禁用不再判断;历史依据保留;多规则只产生一个评论线索 |
|
||||
| AC-W4 | 人工回复/私信,自动冷却尚未到期 | 人工确认仍可发送;线索出现不自动发送;账号、目标、文本及平台结果一致 |
|
||||
| AC-W5 | 双击发送、错账号、超时、平台拒绝 | 一次操作至多发送一次;身份不符拒绝;超时不明不自动重发;平台失败如实显示 |
|
||||
| AC-M1 | 切换两个已登录账号、查看列表与消息详情 | 会话按所选账号隔离;收发方向、时间、历史范围正确,不串消息 |
|
||||
| AC-M2 | 收到新文本、非文本、断连后重连 | 文本接近实时更新;非文本有类型提示;断连可见、重连不重复,不自动回复 |
|
||||
| AC-M3 | 会话内人工文本发送、禁言账号、结果不明 | 正常账号人工确认后发送;禁言被阻止;证据不足保持结果不明、不补发 |
|
||||
|
||||
### 8.5 新增页面与边界验收(原 37 项编号及含义保留)
|
||||
|
||||
| 编号 | 场景 | 必须观察到的结果 |
|
||||
| --- | --- | --- |
|
||||
| AC-U1 | 页面地图列表/详情跳转,加载/空/错误/禁用,分页失败及返回 | 导航可达;字段、进度、计划和原因可读;错误不当空数据;筛选/页码保留,不触发状态探测 |
|
||||
| AC-U2 | 素材两次确认、分步失败/重试、无语音、文稿保存失败及离开 | 两道确认独立;成功产物复用;无音轨/无语音可继续;保存失败保留编辑,未保存离开有提示 |
|
||||
| AC-U3 | 账号编辑、密码配置、人工登录、身份冲突、策略排序与监听记录 | 资料保存准确;密码可输入而不回显/泄露;同环境处理登录;策略顺序可见可保存,身份冲突阻止执行 |
|
||||
| AC-U4 | 规则编辑、显式选择范围重新分析,查看线索并人工确认 | 原依据可查;新分析范围/进度/失败可见;线索不自动发送,确认中账号与目标明确 |
|
||||
| AC-U5 | 两账号/会话切换,草稿未保存、旧请求迟返、非文本/断连 | 消息与草稿不串号;离开可取消/放弃;旧响应不覆盖新视图,非文本及断连可见 |
|
||||
| AC-U6 | 修改设置、未批准 AI 配置、表单校验/保存失败 | 只含批准范围;未批准不调用;无效时间拒绝,失败保留输入且未来计划不误改 |
|
||||
| AC-B1 | 缺事件身份、首次历史、缺时间、断连/停用/重启、冷却到期旧事件 | 按 A6 基线与永久去重;不猜唯一、不擅自补发,缺口/迟到可见;缺 UID 的所有自动动作均阻止 |
|
||||
| AC-B2 | 人工/自动同账号并发、等待中停用/换身份/目标变化、发送后响应丢失 | 写操作不串扰且执行前重核;同操作跨重启不再发送;不明仅核验,新发送另行确认 |
|
||||
| AC-B3 | 后台监听时关页、打开正常页面、页面独立断连再打开 | 关页不停止监听;5 秒处理与正常已开页面 30 秒可见分别有时间证据;重开恢复持久结果,来源延迟不可测不填 0 |
|
||||
| AC-B4 | UTC 跨夏令时、恰好计划/回溯/30 天边界、缺发布时间 | 按 C2 固定时长及包含边界;到期一次、停止优先、不猜时间、不回填历史 |
|
||||
| AC-B5 | 大小写、内部空白、全半角、组合字符、空关键词 | 严格按 W2 原文子串匹配与保存规则,可用确定样例重现,不隐含规范化 |
|
||||
| AC-B6 | 多页读取、真实媒体产物预览、磁盘/配额不足 | 读取和媒体分离且有真实证据;资源不足分步失败可查,不未经授权删除素材 |
|
||||
|
||||
### 8.6 AI 质量与真实平台门槛
|
||||
|
||||
- 在相关功能开发前,与使用者共同选取脱敏的主题/非主题、包含词/排除词、线索/非线索、边界评论样本,逐条标注预期。硬性三步执行、停用、失败和禁发规则必须全部通过,不能交给 AI 自行决定。
|
||||
- 转写样本包含清晰语音、背景音乐、无语音;用户核对关键内容及缺失提示。仿写样本核对标题/口播结构、用户要求、来源关联和可编辑性;自动文本样本核对大号回复要求、目标与平台长度限制。
|
||||
- 已确认采用**使用者批准的样本逐项验收**;AI 语义准确率、转写误差率和创作质量尚无量化阈值,不编造 95% 等承诺。在相关功能开发前共同标注样本与可接受误差,再确定质量门槛;未经样本确认不能将 AI 质量标为已验收。
|
||||
- 每个平台至少使用一个大号、两个小号及可控互动账号验证关系和冷却;竞品/评论样本需包含超过一页数据。只读样本与可控写入样本分别准备,不向无关真实用户发送测试消息。
|
||||
- 为每个平台填写下方能力证据表;全部未接通项均保持未通过。
|
||||
- 本期不承诺任意规模吞吐或永久不受平台限制;生产规模需要真实使用数据后再确认,不预先添加容量平台。
|
||||
|
||||
### 8.7 逐平台能力证据矩阵模板
|
||||
|
||||
状态仅为**待验证 / 支持 / 条件支持 / 不支持**;支持不等于验收已通过,仍须有对应 AC 结果。每个分项逐平台记录测试日期、客户端/平台版本、授权样本、复现操作、脱敏证据位置及限制;条件支持/不支持不得自动删项,范围改变另记用户批准。下表为初始登记,**无真机结论**;复合行执行时按行内分项各填一行,不以某一事件/动作成功代表全部。
|
||||
|
||||
| 能力(须逐分项记录) | AC 关联 | 抖音状态 | 小红书状态 | 证据 | 限制 | 用户变更批准 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 主页/分享链接解析、稳定账号标识 | AC-C1 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 作品/一级评论全部分页、发布时间/窗口 | AC-C2、AC-W1、AC-B4 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 点赞数、评论数、转发数 | AC-C6 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 视频下载、音频提取、无语音结果 | AC-C8、AC-C10、AC-B6 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 登录复用、用户名密码、同环境人工登录/身份核对 | AC-A2、AC-U3 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 评论、点赞、转发、关注事件各自的 ID/UID/目标/时间 | AC-A5、AC-A12、AC-B1 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 基线、断连恢复/缺口、游标稳定性、迟到分类、投递延迟 | AC-A9、AC-A12、AC-A13、AC-B1、AC-B3 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 私信、回复评论、点赞评论/作品、关注、转发动作及成功核验证据 | AC-A7、AC-W4、AC-W5、AC-B2 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 私信账号隔离、历史范围、文本/非文本监听、人工文本发送 | AC-M1、AC-M2、AC-M3、AC-U5 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
| 指纹/Profile 稳定、代理实际出口及认证方式 | AC-E1、AC-E2、AC-E3 | 待验证 | 待验证 | 待提供 | 待核实 | 无 |
|
||||
|
||||
## 9. 实现顺序与检查要求
|
||||
|
||||
| 阶段 | 可交付结果 | 通过条件 |
|
||||
| --- | --- | --- |
|
||||
| G0:证据与输入冻结 | 抖音能力矩阵、事件身份/基线/恢复边界、AI 验收包 | 缺可靠事件身份/UID/目标/监听证据即阻塞相应自动能力;不以 Mock 通过。冻结脱敏样本及逐条预期、允许误差、服务商/模型版本/参数/提示要求等配置记录;服务商、样本、质量阈值或费用未获批准仍为前置待确认,不作已批准声明 |
|
||||
| G1.1:抖音账号与环境 | 账号资料、凭据、同环境登录/身份核对、稳定指纹与代理 | AC-A1、AC-A2、AC-A3、AC-E1、AC-E2、AC-E3、AC-E4、AC-E5、AC-U3 的相关部分独立验证 |
|
||||
| G1.2:抖音只读采集 | 竞品导入、作品/一级评论分页、计划与筛选 | AC-C1、AC-C2、AC-C3、AC-C4、AC-C5、AC-C6、AC-W1、AC-U1、AC-B4 |
|
||||
| G1.3:抖音媒体与 AI | 两次素材确认、文稿编辑保存、主题/关键词/线索及重新分析 | AC-C7、AC-C8、AC-C9、AC-C10、AC-W2、AC-W3、AC-U2、AC-U4、AC-U6、AC-B5、AC-B6;批准样本逐项核验 |
|
||||
| G1.4:抖音人工动作 | 评论/线索逐次确认、真实执行、任务证据与不明核验 | AC-W4、AC-W5、AC-B2 的人工部分;私信动作先验证发送,不以此代替完整会话 |
|
||||
| G1.5:抖音监听与自动响应 | 大小号、有序五动作、四事件、AI 候选、冷却与恢复 | AC-A4、AC-A5、AC-A6、AC-A7、AC-A8、AC-A9、AC-A10、AC-A11、AC-A12、AC-A13、AC-A14、AC-B1、AC-B2、AC-B3;补齐人工/自动竞争证据 |
|
||||
| G1.6:抖音私信及完整回归 | 账号隔离会话、历史/非文本、新消息、人工文本发送 | AC-M1、AC-M2、AC-M3、AC-U5;G1 全部片段及第 8 节所有抖音适用项通过后才称抖音完整完成 |
|
||||
| G2:小红书完整流程 | 先独立重复 G0 证据核实,再按 G1.1 至 G1.6 同范围验证 | 每项取得小红书证据;差异须用户批准,不以抖音、账号登记或部分功能替代 |
|
||||
| G3:整体回归 | 两平台共存、错误恢复、无串号及无重复发送 | 所有适用项有证据,未通过项清零或经用户明确调整需求;分段验收不替代最终完整范围 |
|
||||
|
||||
后续代码变更遵循 [AGENTS.md](../AGENTS.md):
|
||||
|
||||
- 非平凡行为先写能在未实现时失败的最小回归测试,单元测试覆盖率至少 65%;尤其覆盖时间边界、并发冷却、监听重复、平台失败及人工/自动区别。
|
||||
- 后端通过 `go test ./...`、`go vet ./...`,并构建 `./cmd/control-plane`、`./cmd/docker-gateway`;并发、生命周期与共享状态变更运行 `go test -race ./...`;Compose 变更运行 `docker compose config --quiet`。
|
||||
- 前端从 lockfile 安装、通过非交互测试及 `npm --prefix web run build`;关键页面覆盖加载、空数据、错误、禁用、确认/取消和重复点击。
|
||||
- 离线测试只证明本地逻辑,真实平台必须另外验收;请求返回 200、任务入队、模拟连接器成功均不能代替平台动作成功。
|
||||
|
||||
### 9.1 本轮文档完成标准
|
||||
|
||||
- 原始四模块需求均有对应细化、边界及验收项;逐项确认的业务选择无遗漏、无相反表述。
|
||||
- 区分现状、目标、已确认规则与待真实验证的外部条件,不将建议数值或 AI 质量写成未经确认的承诺。
|
||||
- 相对链接有效、验收编号唯一、Markdown 检查通过;没有功能代码改动,原有未提交修改保留。
|
||||
|
||||
### 9.2 后续必须确认而不得猜测的事项
|
||||
|
||||
业务流程已按本轮对话确定。以下依赖真实验证或尚未提供的材料,**不阻塞本文交付,但阻塞相应功能最终验收**:
|
||||
|
||||
1. 两平台每类事件是否提供可靠事件身份、互动者 UID、明确目标、历史基线和接近实时投递;断连恢复范围及迟到事件处理须按 A6/G0 验证并批准,无法提供时由使用者决定该项替代或范围调整。
|
||||
2. 平台未提供的指标、下载能力、动作限制、账号密码登录方式及历史消息范围,须逐项给证据,不能通用地写成“尽力支持”。
|
||||
3. 使用者指定/批准的 AI、转写服务及调用配置、脱敏评价样本与质量门槛;不擅自选择付费服务或上传整库资料。
|
||||
4. 遇到本文之外的事件类型、业务状态、自动聊天、批量发送、视频生成或规模要求,重新确认需求,不顺带扩展。
|
||||
|
||||
### 9.3 本轮评审处理表
|
||||
|
||||
| 问题或评审说法 | 修复位置 | 处理结论 |
|
||||
| --- | --- | --- |
|
||||
| 旧“仅自有/阶段 A 离线”覆盖新范围,架构栈/生命周期互相矛盾 | 2.1、2.2;旧产品首页、架构、部署 | 历史与目标分开,当前代码事实单独说明,不新增永久删除 API 或认证方案 |
|
||||
| 功能尚未实现即计划缺陷 | 第 2 节、第 9 节 | 评审误判:属于实现差距,不用 Mock 冒充完成,也不删需求 |
|
||||
| 无音轨/无语音必须重新决定;API 应禁止接收密码 | C4、A1、AC-U2、AC-U3 | 评审误判:已确认可继续;密码允许输入凭据流程,禁止回显/日志泄露,不阻断录入 |
|
||||
| 页面不够可执行,缺跳转与异常状态 | 7.4、8.5 | 紧凑页面地图与共用交互,优先现有页签/抽屉,无新通用系统 |
|
||||
| 去重/冷却、基线/断连、人工重试与并发边界不足 | A3、A5、A6、W3、7.2、AC-B1 至 AC-B3 | 可靠身份、永久最小去重、迟到核验、持久操作标识及同账号写协调 |
|
||||
|
||||
### 9.4 当前本地实现状态
|
||||
|
||||
- 已有:CreatorHub 数据表与 API、账号/大小号关系约束、规则与线索判断、作品/一级评论分页采集边界、断点租约、来源关联、指数指标计划、抖音自有/竞品只读采集调度,以及工作台的错误/重试/确认状态。
|
||||
- 下一轮 TODO:真实平台事件监听与断连恢复;抖音实际点赞/评论/关注/转发/私信写入;素材真实下载/提音/转写;小红书采集与动作;生产 AI/转写供应商、模型、密钥与质量样本;以及对应的 G0/G1 真机证据。
|
||||
- 本地限制:仓库默认未配置 `CREATORHUB_POSTGRES_TEST_URL`;本轮使用运行中的 PostgreSQL 完成了 CreatorHub 数据行为、来源关联、指标、操作、消息和 checkpoint 租约集成测试,覆盖率为 65.6%。CI 或后续环境需提供专用测试库以重复该验证。
|
||||
| 时间/文本匹配不确定,媒体读取限制误当需求缺陷 | C2、W2、C4、AC-B4 至 AC-B6 | 固定 UTC 时长、原文匹配、分步产物引用;真实分页/媒体另验,不预设扩容或自动删素材 |
|
||||
| AI 输入未冻结、平台能力无证据模板、G1 过大 | 8.6、8.7、第 9 节 | G0 保留外部批准前置,矩阵全为待验证;G1 分段可验但不替代最终完整流程 |
|
||||
@@ -1,6 +1,9 @@
|
||||
# CreatorHub 内部技术探索方案
|
||||
|
||||
> 状态:已入库,阶段 A 按单用户范围验证
|
||||
> 状态:历史探索记录,不再作为当前产品范围与验收依据。
|
||||
> 当前权威入口:[需求细化与验收标准](../plan01.md)。冲突以该文档及使用者最新确认为准;以下“本轮”“当前”均指 2026-08-27 的旧探索阶段。
|
||||
> 旧阶段 A 仅离线 Mock,不等于新计划 G0/G1;旧“仅自有账号”、自动动作排除项和逐次草稿确认不限制新计划中的公开可访问/已授权竞品采集及按策略自动响应。人工发送仍逐次确认。
|
||||
> 本文中的 RBAC、Secret Manager 等历史设想不构成本期新增系统要求;实际部署与现有认证见[部署说明](../deployment.md),不因新开发目标而宣称旧认证已移除。
|
||||
> 日期:2026-08-27
|
||||
> 上游参考快照:`3441293738/creatorhub@11df1389ee557169bb2381e5ea08de96f14f80c7`
|
||||
|
||||
@@ -46,7 +49,7 @@ CreatorHub 是一个**内部、非公开**的多账号运行环境与运营任
|
||||
P0 是首轮验证必需,P1 仅在 P0 通过后开展。
|
||||
|
||||
| 领域 | P0 | P1 | 本轮停止线 |
|
||||
|---|---|---|---|
|
||||
| --- | --- | --- | --- |
|
||||
| 运行环境 | 每账号独立 Profile;运行时版本固定;单实例占用锁;环境变更留痕;浏览器崩溃可见 | 升级灰度、备份恢复、跨 OS 兼容矩阵 | Profile 串用、版本漂移、设备校验或未知挑战页 |
|
||||
| 网络出口 | 账号稳定绑定;连通性与认证观测;出口失效时禁止静默直连;凭据脱敏 | 容量、延迟、可用率和成本统计 | 出口地址/地区异常变化、认证失败、网络策略不明确 |
|
||||
| 账号池 | 自有/授权标记;平台账号唯一键;凭据只存引用;状态和撤销 | 标签、归档、登录态健康 | 授权不明、账号映射冲突、凭据进入日志 |
|
||||
@@ -97,7 +100,7 @@ Secret Manager / OS Keyring 只保存凭据,数据库仅存引用。
|
||||
### 高层威胁与控制
|
||||
|
||||
| 威胁 | 可观测现象 | 系统控制 |
|
||||
|---|---|---|
|
||||
| --- | --- | --- |
|
||||
| Profile 或账号串用 | 当前账号标识与任务账号不一致 | 执行前双重校验、每账号锁、立即停机 |
|
||||
| 凭据泄露 | 日志/错误/导出中出现敏感字段 | Secret 引用、结构化脱敏、敏感字段扫描 |
|
||||
| 环境兼容性漂移 | 浏览器版本、启动结果、页面能力或登录态变化 | 固定版本、记录变更、按兼容矩阵回归;不猜测检测机制 |
|
||||
|
||||
Reference in New Issue
Block a user