Skip to main content

Modules

Asset
ADP-PLN-FEAT-DOC-0020
Feature
modules
领域
plane-core
作用域
application-level
文档状态
stub
产品生命周期
planned
文档 Owner
DOC
事实源
canonical-docs
工程 Owner
PLN
Development Ready
not-ready
更新
2026/10/14

FEATURE DEVELOPMENT PACKAGE

工程就绪状态

工程 Owner:PLN · 仓库:PLN

BLOCKED
development · not ready
  • 原子需求与验收
  • 设计与工程合同
  • 代码与仓库定位
  • 里程碑与工作包
  • 验证计划
  • 无阻断决策
verification · not ready
  • Development Ready 已通过
  • 验收标准已覆盖
  • 正式测试已登记
  • Fixture 与环境已定义
  • 测试规格已物化到正式测试
release · not ready
  • Verification Ready 已通过
  • 实现修订可定位
  • 发布证据已登记
  • 兼容与迁移已定义
  • Runbook 与回滚已定义
查看阻断项(6)
  • 功能仍为 stub:不可进入开发
  • Development Ready 缺少:原子需求与验收
  • Development Ready 缺少:设计与工程合同
  • Development Ready 缺少:代码与仓库定位
  • Development Ready 缺少:里程碑与工作包
  • Development Ready 缺少:验证计划

功能目标​

为 Plane 的“Modules”建立可发现的 Feature 边界。首批仅完成 inventory 和页面合同骨架;页面可见不表示实现、验收或发布已经完成。

功能结论​

主题当前结论
Producer / 用户Project 成员。
入口Project Modules 导航;具体路由、按钮和权限仍待基于当前实现补证。
可见结果按交付主题聚合工作项并展示进度。
系统保证任何写操作都必须遵守 Workspace 隔离、对象权限、并发与审计约束;未补证字段不得写成稳定合同。
明确不做Module 是 Project 内聚合,不是本文 planning manifest 的 cycle。
权威 owner产品语义由本页补全后的 canonical contract 持有;实现与环境状态分别由 Plane source、TEST/PROD evidence 持有。

当前落地状态、已批准合同与差距​

  • 当前落地状态:stub。inventory 来源于当前 Plane 用户可见导航或设置范围,但本页尚未完成 source、UI、API 和测试核验。
  • 已批准合同:除下文“复制模块”与工作项业务状态展示合同外,本页只批准“Modules”作为独立 Plane Feature 纳入功能库及其主层级;上表不得解释为其他模块行为的完整合同。
  • 差距与后续交付:需要核对用户入口、角色矩阵、稳定状态、数据/API、异常行为和现有测试,再由 Producer 审核后提升状态。

用户、权限、流程与数据​

补全文档时至少覆盖:角色和租户边界、主要读写流程、稳定状态与状态转换、数据 owner、API/事件、幂等与并发。当前不推断未核验的字段、端点、默认值或可用性。

复制模块​

用户旅程与边界​

Project 管理员和成员在模块列表、卡片或详情页的共用“⋯”菜单选择“复制模块”, 填写新名称并提交。访客不能操作。目标固定为同一个 Project,不提供跨项目复制。 源模块可处于归档状态,副本始终为未归档的新模块。

弹窗建议“原名称(副本)”;同名时加递增编号,建议名称和显式名称都受 255 字符限制。 同项目的未删除模块(包括已归档模块)参与名称唯一性判断。提交时冲突明确报错, 不静默改名。默认勾选“同时创建工作项副本”,默认不勾选“保留计划日期”。 工作项数量由服务端读取,页面筛选、分页与布局不影响复制范围;提交时重新读取源内容, 预览数量不是源数据锁定承诺。

复制工作项时可开启默认关闭的“替换标题中的文字”,填写“查找文字”和“替换为”, 例如将 英雄09 替换为 英雄13。只支持一组区分大小写的普通文本替换, 替换副本标题内全部匹配位置;模块名称单独填写,工作项描述和源标题保持原样。 两项都必须包含非空白文字,按原输入精确匹配;不支持正则、多组规则或逐项编辑。

服务端预览返回命中工作项数量和最多 3 条前后示例,没有命中时明确提示,仍允许复制。 预览未完成或读取失败时禁止按当前规则提交。替换结果为空或超过 255 字符时, 指出无效标题数量和最多 3 个源工作项,阻止创建。提交时重新读取并锁定源工作项, 按同一规则检查全部标题;预览后变化的标题可能导致整次拒绝,不能产生部分副本。 弹窗内容区可滚动,底部操作按钮保持可访问。

创建成功后打开副本详情页。失败保留填写内容。超时或服务端异常时不自动再次提交; 浏览器当前会话保存本次目标 UUID 和选项,用户可关闭弹窗后重新打开查询结果, 也可显式重试同一次请求。重试保持目标 UUID、原选项和完整标题替换规则,因此不会生成第二套副本。

数据合同​

内容副本行为
模块名称使用用户提交的新名称
模块描述、图标、链接复制,链接记录获得新 ID
模块负责人、成员仅保留仍有效的项目管理员或成员
所属模块分组引用原项目分组;已删除分组不再引用
模块状态、归档状态planned、未归档
模块和工作项日期默认清空;选择保留日期时复制开始和目标日期
工作项集合源模块中有效、未归档、非草稿、非 Intake/Triage 工作项;不额外收集模块外子项
工作项内容新 ID 和编号;标题默认保留,开启替换时按所填规则生成;保留描述、有效类型、优先级、有效项目标签、有效负责人和估算
工作项状态通过普通创建链路解析项目的合法初始状态,初始化新的类型业务状态
父子关系仅重建复制集合内部关系;集合外父项引用清空;失效层级拒绝整次操作
工作项顺序在副本内保留源集合的排序次序
描述图片复制内部图片的存储对象及资源记录,处理 HTML 或 JSON 单独存在的图片引用,并重写两者引用;不复制旧协作二进制状态
里程碑、周期、其他模块关联、依赖清空,不继承原交付关联
评论、活动历史、工时、普通附件不复制;创建事件和初始描述版本属于副本自己的新历史
外部同步身份、收藏、订阅、个人视图不复制
Automation新工作项显式关闭开关;不复制或创建执行 Run

未选择复制工作项时只创建模块、有效成员、链接及模块描述资源。 同一工作项不会同时作为源和副本共享对象;后续修改副本内容不修改源对象。 用户自己删除仍被外部 URL 引用的资源不属于内部图片复制保证。

API 与机制​

端点:/api/workspaces/{slug}/projects/{project_id}/modules/{module_id}/duplicate/。

  • GET:接受本地化 suffix 和可选 destination_id,返回 suggested_name、 issue_count、existing_module_id、title_replacement_preview。可同时传入 title_find、title_replace 预览规则;两项使用相同的非空白、255 字符限制。 预览包含 matched_count、最多 3 条 samples(issue_id、before、after)、 invalid_count 及最多 3 条 invalid_samples(另含 reason: empty | too_long)。 未启用替换或恢复到已创建副本时,替换预览为 null。 恢复查询只识别当前 Project 内、当前用户创建的目标。
  • POST:接收 name、必填 UUID destination_id、include_issues(默认 true)、 keep_dates(默认 false),可选 title_replacement: { find, replace }。 替换规则仅允许随工作项复制提交,缺少字段、空白字段或字段超限拒绝请求。 当前源标题替换后无效时返回 400、code: duplicate_title_invalid 和无效标题预览。 成功返回 201 和 module_id、name、copied_issues。
  • 名称或目标 UUID 冲突返回 409;字段、图片或业务创建约束失败拒绝操作。 已删除或越界源对象返回 404,角色权限不足返回 403。

后端依次取得层级 Workspace(复制工作项时)、Project、编号锁;读取源模块, 复制工作项时锁定源集合并检查全部替换标题;随后保护有效分组,创建新模块、成员、链接和图片对象。 工作项按父项优先顺序通过 IssueCreateSerializer 创建, 复用类型、工作流、层级、业务状态及属性默认值规则;随后复制图片、创建关闭的 Automation 开关, 关联新模块并恢复集合排序。

所有数据库写入位于一个事务中;任何一项失败,模块与工作项全部回滚。 存储不参加数据库事务,本次创建的图片对象使用独立随机键,回滚时进行补偿删除; 存储清理失败记录服务端异常,可能遗留无引用对象,不能宣称跨数据库与存储的原子提交。 创建通知、Webhook 与描述版本任务只在提交后发送;发送失败记录异常,不把已经提交的副本 解释为回滚。

目标 UUID 使用模块主键唯一约束,同项目请求同时受编号锁串行保护。 重复请求命中已存在目标会返回冲突,前端随后查询并打开现有副本,不建立长期双模式或兼容路径。 不需要数据库迁移。模块描述资源使用既有 entity_identifier 字段记录新模块 ID。

实现来源与验收限制​

实现来源:autoai/autodev-plane,revision 7351aa255c0eb9e660470806b63ed790af93a9af。

  • apps/api/plane/app/views/module/duplicate.py:ModuleDuplicateEndpoint、输入合同、预览与恢复查询。
  • apps/api/plane/utils/module_duplicate.py:duplicate_module、集合范围、事务、层级重建和提交后活动。
  • apps/api/plane/utils/module_duplicate_assets.py:ModuleDuplicateAssets、独立图片及失败补偿。
  • apps/api/plane/utils/module_duplicate_titles.py:ModuleTitleReplacementSerializer、replaced_issue_title、有界预览与完整标题校验。
  • apps/web/core/components/modules/duplicate-module-modal.tsx:DuplicateModuleModal、默认选项、结果未知恢复。
  • apps/web/core/components/modules/duplicate-module-title-replacement.tsx:DuplicateModuleTitleReplacement、延迟预览、过期响应丢弃与示例显示。
  • apps/web/core/components/modules/quick-actions.tsx:ModuleQuickActions、共用菜单入口。
  • packages/types/src/module/modules.ts:复制 payload、preview 与 result 类型。

验收概要:副本独立、默认重置准确、有效人员和分组范围正确、完整集合不受页面筛选影响、 内部层级重建正确、名称冲突清晰、失败无数据库半成品、图片独立、同一次请求不会重复生成、 新工作项不自动执行;标题全部匹配替换、无命中可复制、无效标题整次拒绝、预览与创建一致、 重试保留原规则。外部 CI 对改动执行类型和 Lint 检查;标题替换专项运行交互、真实 TEST 环境功能行为、 描述图片删除独立性、事务并发与大模块容量仍需运行环境证据,不能用源码或 CI 静态通过代签。 本次未新增、扩写或修改测试;本地验证根据项目策略禁止执行。

跨层依赖与停止条件​

Module 工作项集合采用Issue 阶段责任流的展示合同: 以真实业务状态、当前环节负责人和工作项负责人组织紧凑列表,退役旧工作项状态的展示与筛选/分组/排序入口。 类型只出现一次,当前模块不逐行重复,未设置的次要属性不默认占位;业务状态只能通过业务动作推进。 这条已批准的展示合同不替代 owning source、外部 CI 和发布证据。

  • 依赖:Plane Module 分组、工作项生命周期。
  • 缺少权限、租户一致性、有效对象或 owning service evidence 时 fail closed。
  • 外部集成、运行时或发布 evidence 不得由本页的 stub 状态代签。

验证与权威来源​

补全前必须以 Plane 当前 source、真实 UI/路由、API schema、测试和 Producer 决策交叉验证;Docusaurus build 只证明页面可构建,不证明 Feature 已落地。

待决策问题​

  1. v1 的最小用户闭环、明确 non-goal 和验收场景是什么?
  2. 哪些角色可读、可写、管理或导出,direct 与 inherited 权限如何解释?
  3. 哪些状态、字段、API 与事件应成为长期稳定合同?