# EveryPublish Web-only 系统设计 > V1 版本 · 2026-08-21 ## 1. 总体形态 ```text 浏览器 React/TDesign │ REST + Browser WebSocket ▼ Go server ├─ JWT/工作区/权限/审计 ├─ 素材存储(本地盘,StorageDriver) ├─ 任务状态机 + Dispatcher ├─ Challenge/Notification └─ WebExecutor / PlatformAdapter(本机执行) │ ├─ mock(自动化联调默认) └─ Playwright/Patchright profile + cookie vault(真实平台) ``` V1 不需要客户端 App、设备配对、Agent WSS、Ed25519 设备身份或 Agent 设备管理。浏览器连接服务器即可完成管理;服务器进程运行在用户当前设备上时,平台浏览器和 cookie 也留在该设备。 ## 2. 模块职责 | 模块 | 责任 | |---|---| | `apps/web` | 页面、表单、上传进度、Browser WS 状态、错误提示 | | `server/internal/api` | REST 鉴权、参数校验、工作区隔离、审计 | | `server/internal/task` | 可验证的任务状态转移 | | `server/internal/ws` | Browser WS 广播;不再把 Agent 当 V1 必需依赖 | | `WebExecutor` | 统一提交/进度/结果/挑战接口 | | `TaskEvent` | 持久化每次状态转移、执行结果和错误信息 | | `PlatformAdapter` | 每个平台登录、Cookie 检查、视频/图文发布 | | `StorageDriver` | 本地素材存储;后续可换 OSS | ## 3. 数据与凭据 - 业务表保留 workspace_id,所有查询必须带当前 workspace。 - 素材按流式 SHA-256 写入本地盘,服务端限制最大上传体积。 - 本地平台 cookie 仅存当前设备的受保护数据目录(AES-256-GCM,workspace/account 分隔),不写入网页响应和审计日志。 - 挑战输入不写明文日志;QR URL/token 只在挑战生命周期内可见。 ## 4. API/实时协议 REST 使用 `/api/v1`;浏览器 WS 使用 `/ws/browser?token=`。页面首次加载总是 REST 拉取,WS 只负责增量事件;WS 断开时显示状态并启动有限轮询。 ```text task.status {taskId,status,errorMessage,publishedUrls,progress} challenge.status {challengeId,accountId,status,prompt,expiresAt} notification.new {id,kind,title,content} executor.health {mode,online,queueDepth,lastError} ``` ## 5. 执行与失败语义 ```text queued → dispatched → running → success └→ failed → retry → queued running/queued → cancelled running → waiting_challenge → running/failed ``` 每次执行都记录 adapter、账号、开始/结束时间、错误分类、目标平台响应摘要和回执 URL。`example.com/fake` 只能出现在显式 mock 模式,不能作为真实平台成功结果。