6.3 KiB
项目写入与附件上传设计
目标
为现有只读 NocoBase CRM MCP 增加受限的项目创建与更新能力,并支持通过同一 HTTP 服务上传文件、再将其增量关联到项目附件。
范围仅覆盖 NocoBase 项目集合 t_projects。服务不得提供任意集合、任意字段或删除项目的能力。
已确认的数据模型
项目集合:t_projects(标题:项目)。
| MCP 参数 | NocoBase 字段 | 说明 |
|---|---|---|
name |
f_project_name |
项目名;创建时必填 |
customer_id |
client_ID |
客户外键,目标集合为 t_nt3pjadelqi |
inquiry_date |
xm_project_inquiry_date |
项目收到日期,YYYY-MM-DD |
progress |
f_projects_progress |
项目进展 |
applications |
f_projects_applications |
应用 |
part_numbers |
f_projects_part_numbers |
涉及产品料号 |
period_usage |
f_projects_period_usage |
项目用量 |
details |
f_projects_details |
详细信息 |
附件关联字段为 f_projects_attachments,类型为 belongsToMany,目标为 NocoBase 内置 attachments 集合,存储为 local。联系人、跟进记录、项目情况更新、系统字段和其它字段均不在首版写入范围内。
允许的项目进展为:询价阶段、已报价、送样、已定点、SOP、终止。MCP 接受这些中文标签,并映射到 NocoBase 已配置的内部枚举值。
方案选择
采用分步上传方案:HTTP 上传端点先将文件写入 NocoBase 附件库并返回附件 ID;MCP 项目工具再使用该 ID 建立项目关联。
此方案将二进制 multipart 上传与 MCP JSON 工具调用分开,便于客户端重试、明确上传与项目写入的失败边界,也避免客户端持有 NocoBase JWT。单请求中同时提交项目和文件、以及让客户端直接调用 NocoBase 均不采用。
HTTP 上传接口
新增可选的 POST /uploads,与 /mcp 部署在同一个 HTTP 服务中,并复用现有 MCP Bearer Token 中间件。交付加固后该路由默认关闭;只有设置 NOCOBASE_MCP_ENABLE_UPLOADS=1 才注册。
请求必须为 multipart/form-data,每次仅接收一个名为 file 的文件字段。默认单文件上限为 25 MiB。首版不额外限制 MIME 类型;部署者可在配置中收紧允许的类型。
服务将文件流式写入受控临时目录,随后转发到 NocoBase:
POST <NOCOBASE_MCP_UPLOAD_API_BASE_URL>/attachments:create?attachmentField=t_projects.f_projects_attachments
转发请求使用 NOCOBASE_MCP_UPLOAD_JWT 中配置的 NocoBase 用户 JWT。该 JWT、NocoBase API 地址和文件内容均不得写入日志、MCP 结果或 config.json。临时文件无论成功或失败都必须立即清理。
成功响应:
{
"upload_id": 123,
"filename": "quote.pdf",
"size": 456,
"mimetype": "application/pdf"
}
upload_id 是 NocoBase attachments.id。上传前必须以当前用户凭证调用 roles:check,并按 NocoBase 的全局或表级 ACL 解析确认 t_projects:create/update 至少一项可用。上传成功但尚未关联到项目的附件会保留;首版不运行自动清理任务,以避免误删业务文件。
MCP 工具
新增:
create_project(
name, customer_id?, inquiry_date?, progress?,
applications?, part_numbers?, period_usage?, details?,
attachment_ids?
)
update_project(
project_id,
name?, customer_id?, inquiry_date?, progress?,
applications?, part_numbers?, period_usage?, details?,
add_attachment_ids?, remove_attachment_ids?
)
规则
name创建时必填,且去除首尾空白后不能为空。inquiry_date必须为YYYY-MM-DD。progress必须是上表中定义的六个中文标签之一。customer_id只写入client_ID。attachment_ids仅用于创建后建立附件关联。- 更新附件只接受
add_attachment_ids和remove_attachment_ids;不提供覆盖整个附件集合的语义。 - 同一个附件 ID 不得同时出现在 add 和 remove 列表中。
- 输入列表必须去重;不存在或无权访问的附件使该次附件关联操作失败。
创建或更新标量字段后,再执行附件关联。若关联操作失败,响应必须包含已创建或已更新的 project_id 和结构化失败详情;不回滚已经成功写入的项目字段。关联操作使用 NocoBase belongsToMany 的 add 与 remove 资源操作。
错误契约
所有业务失败均保持现有 MCP 的结构化错误格式。首版增加:
invalid_project_inputinvalid_progressproject_not_foundattachment_not_foundupload_too_largeunsupported_media_typenb_upload_failednb_upload_unauthorized
上传端点对缺失或无效的 MCP Bearer Token 返回 401。上游 JWT 失效或被拒绝时,上传端点返回明确的认证失败,不重试登录,也不暴露上游令牌。
配置与权限
config.json 追加固定的 projects 映射,包含项目资源、八个可写字段、客户外键和附件关联字段。该映射不允许调用方覆盖。
运行时环境变量:
NOCOBASE_MCP_UPLOAD_API_BASE_URLNOCOBASE_MCP_UPLOAD_JWTNOCOBASE_MCP_UPLOAD_MAX_BYTES(默认26214400)- 可选 MIME 白名单环境变量或配置项
服务角色必须拥有:t_projects 的 create/update、attachments 的上传/create,以及 t_projects.f_projects_attachments 的 add/remove 权限。README 和 systemd 服务配置必须明确这些新增权限与密钥配置;只读用户保持 NOCOBASE_MCP_ENABLE_UPLOADS=0。
验证
- 为 NocoBase 客户端新增创建、更新和关联 add/remove 的命令构造单元测试。
- 为项目服务增加字段白名单、日期、进展、附件冲突和结构化错误测试。
- 为上传 ASGI 接口增加认证、multipart、文件上限、上游失败和临时文件清理测试。
- 为 MCP server 增加新工具的 schema、参数传递和附件增量语义测试。
- 自动化测试全部使用模拟的 NocoBase/HTTP 调用;不得连接真实 NocoBase 或写入真实项目、附件。
非目标
- 删除项目或附件。
- 管理联系人、跟进记录、项目更新记录或任意其它关联。
- 任意字段写入或调用方指定资源。
- 自动清理未关联附件。
- 客户端直接持有或提交 NocoBase JWT。