9.6 KiB
ProfileMax「发布」(Publishing) 功能扩展开发说明
目标:供 Zcode 在现有 SerpMax/ProfileMax 项目中直接扩展。新增一个「发布」一级菜单,页面内部使用 Ant Design Tabs(页签)管理子功能。此处“Tags”按页面 Tabs 理解;站点标签另用 tags 字段,不要混淆。 依据:
docs/审计-功能清单与技术栈.md(2026-10-28),开发前以当前源码为准。
1. 定位和边界
- 只扩展现有 ProfileMax:复用 Bun.serve、PostgreSQL/Bun.sql、React 19 + antd 6、Scripts、Tasks、54 个 MCP 工具、Profile/Proxy/Cookie、Node/Lease、Playwright、Fetch 和 WebDesk。
- 不做独立平台、不集成 LLM/Agent 服务。Zcode/Codex/OpenCode 通过 MCP + Skills 负责网站学习、文章生成、脚本编写与失败修复。ProfileMax 负责确定性执行、持久化、校验、调度、监控和评分。
- 网站资源由用户 CSV/JSON/API 导入,不实现自动发现/爬取资源引擎;仅支持有授权或允许投稿的网站,遵守站点规则。
- V1 不增加消息队列、微服务、第二套调度器;优先扩展现有 tasks、scripts 和 task_runs。现有脚本/任务功能必须保持兼容。
2. UI:一个「发布」菜单 + 内部 Tabs
导航增加 发布 (Publishing) 一级菜单,点击后页面顶部用 Ant Design Tabs 切换:
| Tab | 最小功能 |
|---|---|
| 项目 | 项目 CRUD;官网、产品资料、目标 URL、关键词、内容规则、默认语言 |
| 站点 | CSV/JSON 导入、列表/标签/筛选、站点 URL、平台类型、允许发布的账号/Profile 关联、脚本版本、状态 |
| 文章 | 草稿导入/编辑(Markdown/HTML)、文章版本、审核状态、目标链接/锚文本;内容由外部 Agent 生成后保存 |
| 发布任务 | 创建发布任务、选择文章/站点/Profile、脚本、执行时间/并发、运行日志、失败诊断、手动重试 |
| 质量与评分 | 发布 URL、链接属性、链接存活检查、最近检测时间、站点评分/外链评分和历史结果 |
- 页面沿用当前布局、路由、权限、组件、暗色主题及 API 封装方式;图标使用 lucide-react,不使用 Emoji。
- Tabs 的选择应支持 URL 定位(刷新保留),权限统一使用新增
publishing菜单权限,并校验关联 Profile 的所有权/分享权限。 - “发布”是一级菜单,其下使用 Tabs 而非再添加五个左侧菜单。站点本身的业务
tags用于分类筛选,与 UI Tabs 是两种概念。
3. 执行流程
- 用户/Agent 导入站点并与现有 Profile 关联,记录网站可发布权限、平台类型及标签。
- 外部 Agent 通过已有 MCP/browser tools 学习站点,优先复用已有
schema脚本,复杂页面才使用code;第一次或少量测试后保存稳定脚本并绑定站点(或平台)。 - 外部 Agent 根据项目资料生成有实际价值的文章,通过 MCP/REST 写入「文章」,标记
draft/review/ready。 - Publishing 生成发布作业并交给现有任务系统执行。文章正文、标题、图片、链接作为每次运行的输入参数;不为每篇文章复制脚本。执行时使用已有 Profile Lease。
- 将结构化输出(发布 URL、状态、错误码)与 task_run 关联,提交超时标记
unknown,先查是否已发布再重试,避免重复提交。 - 失败时保存脱敏错误、失败步骤、截图/DOM 摘要;将修复状态标记
needs_repair,外部 Agent 通过 MCP 查询、测试并提交新脚本版本。V1 允许 Agent 主动轮询,不要求 ProfileMax 自动启动 Agent。 - 发布后由后台定时进行 HTTP/HTML 检查;需要登录/JS 渲染才回退现有 Profile Fetch/Browser。定期计算评分,供站点筛选使用。
标准脚本 I/O(新增适配层,不破坏现有脚本 API)
interface PublishInput {
siteId: string;
article: {
title: string;
html: string;
markdown?: string;
images?: string[];
};
targetLinks: Array<{ url: string; anchor: string }>;
mode: "draft" | "publish";
}
interface PublishResult {
status: "draft" | "published" | "failed" | "unknown";
articleUrl?: string;
externalId?: string;
errorCode?: string;
message?: string;
}
任务需要 idempotencyKey、脚本版本快照和稳定的 run ID;不能因重试发布重复文章。
4. 数据模型(尽量少表,沿用现有数据库)
新增前先检查已有数据结构,避免重复:
| 表 | 核心字段 |
|---|---|
publishing_projects |
id, owner_user_id, name, website, config(jsonb), created_at |
publishing_sites |
id, project_id, url, platform, tags(text[]), profile_id(nullable), script_id(nullable), status, metadata(jsonb) |
publishing_articles |
id, project_id, title, markdown, html, target_links(jsonb), version, status, metadata(jsonb) |
publishing_jobs |
id, project_id, site_id, article_id, profile_id, task_id(nullable), script_version, idempotency_key, status, result(jsonb) |
publishing_checks |
id, job_id, checked_at, page_status, link_status, rel(jsonb), detail(jsonb) |
- 与现有
profiles/scripts/tasks/task_runs使用关联 ID,不复制 Cookie、Proxy 或完整执行日志。 - V1 脚本版本可增加
script_versions通用表及稳定版本指针;禁止直接覆盖正在运行的版本。版本表应是通用 Scripts 能力,不放在 Publishing 业务表中。 - 评分先用查询/视图或定期计算,不必新建评分历史表;Site Score 建议结合主题相关性、成功率、链接保留率、成本;Backlink Score 包含链接存活、属性、内容相关性及可获得的引荐效果。未知数据标记 unknown,不编造指标。
- 迁移延续现有 PostgreSQL 迁移惯例;新增索引(owner/project/site/job/status/idempotency_key);新写接口校验访问权限、输入及关联实体归属。
5. REST / MCP / Skills
REST API 建议统一前缀 /api/publishing:
GET/POST /projects、GET/PATCH/DELETE /projects/:idGET/POST /sites、POST /sites/import、PATCH /sites/:idGET/POST /articles、PATCH /articles/:idGET/POST /jobs、GET /jobs/:id、POST /jobs/:id/retryPOST /jobs/:id/verify、GET /jobs/:id/checks、GET /scores
MCP 复用 admin/src/api/mcp.ts 的认证与工具框架;V1 只补充少量组合工具:
publishing_import_sitespublishing_save_articlepublishing_create_jobpublishing_get_jobpublishing_verify_jobpublishing_get_repair_context
脚本 CRUD/运行尽量调用现有 MCP,不重复暴露同名能力。新增 skills/profilemax-publishing/SKILL.md 及 references,写明:导入站点、学习站点、复用/生成脚本、测试、生成内容、创建任务、查询失败、修复测试、验证链接。Skills 是外部 Agent 的操作说明,不在服务端执行大模型。
6. 代码落点与实现要求
- 前端:
admin/frontend/pages/Publishing.tsx;接入现有路由/导航;内部 Tabs 使用独立子组件,避免一个超大文件。 - API:
admin/src/api/routes/publishing.ts;保持现有Bun.serve路由模式、身份与权限中间件。 - DB:
admin/src/repos/publishing*.ts与现有迁移文件。 - 业务:
admin/src/runtime/publishing/负责作业映射、定时监控和评分;复用admin/src/runtime/taskScheduler.ts,不要写第二套 scheduler。 - Node:优先不改节点;只有在脚本 I/O 或故障证据无法通过现有 Schema 执行器实现时,才最小修改
node/src/core/schema/。 - MCP:
admin/src/api/mcp.ts增加工具,继续使用同一 Bearer 认证与权限校验。 - 现有
code脚本通过new Function在节点进程执行、没有沙箱:不得让 Agent 新生成的任意代码直接进入该运行通道。V1 优先 Schema;如果必须支持 Agent 生成 JS/TS,需先实现真正的低权限独立进程/容器隔离(不是node:vm),并限制敏感文件、进程、网络及密钥访问。Agent 输出和网页 DOM 一律视为不可信。 - 站点/脚本修复只提交候选版本,经测试和审查再发布 stable;不能在生产中直接修改热脚本。
7. 开发顺序与验收
阶段 A(最小可用):发布菜单+Tabs;项目/站点/文章 CRUD;导入站点/关联 Profile;MCP 读写;复用现有稳定脚本创建任务并显示结果。
阶段 B(脚本复用):参数化脚本 I/O、通用版本管理、失败证据、待修复状态、外部 Agent 的学习/测试/修复 Skill。完成代码执行隔离前,不允许自动运行不可信 Agent 生成的 code 脚本。
阶段 C(质量):定时外链验证、历史检查、站点评分及汇总报表。
必须验证:
- 发布菜单仅一个一级入口,内部五个 Tabs 切换和刷新定位正常;多用户权限正确。
- CSV/JSON 批量导入可去重,同项目站点可筛选、打标签、关联获授权的 Profile。
- 已有 Schema/脚本可复用,文章不同但不复制脚本;运行成功返回文章 URL。
- 失败、取消、超时、重复投递安全处理,重复任务不会导致重复发布。
- Agent 离线时正常任务与质量监控照常运行;失败待修复可通过 MCP 领取和诊断。
- HTTP 检测正常,动态/认证页面有回退方案;评分无数据时展示未知或样本数。
- 原有 Profiles、Scripts、Tasks、SERP、MCP、WebDesk 功能均通过回归测试。
Zcode 开发原则:先检查现有源码/接口与表结构,再最小增量改造;禁止重复造已有模块。本文是实施目标,不代表接口或表已经存在。