Skip to content

项目管理

逸灵风的结构化项目管理,基于统一实体模型

模型说明(v0.2 简化): 已移除里程碑与必填完成条件。项目保留日程 + 终态状态;可选背景说明放在实体 content(仅在项目编辑对话框中编辑)。任务仅经 body.project_id 关联项目。

v1 交付:项目文件夹树、项目实体、任务归属迁移。OKR、跨实体链接、甘特、项目文件夹级看板、文件资产为 [v2+](清单模块 /tasks 看板已落地,见 task.md)。

project_folder (organizational tree, independent from task_list folders)
└── project (leaf — cannot nest)
└── task_item (via body.project_id)
task module (/tasks) — lists, smart lists, backlog tasks (body.project_id empty)

项目文件夹与任务清单文件夹是两套独立树。清单模块仍是未派入项目条目的 清单侧临时任务池


仅用于项目管理的独立文件夹层级——与任务清单文件夹(task_list.is_folder不共享

规则细节
嵌套无限深度;纯组织
无生命周期无起止日期或终态状态
父级body.parent_id → 另一 project_folder 实体 id,或根为 null
防环同任务清单文件夹——嵌套不得成环
删除递归移除子文件夹;所含项目置 folder_id: null(项目不被删除)

[v2+] 文件夹级甘特 / 看板,聚合文件夹下全部项目(清单模块看板不覆盖此范围)。

示例布局:

FreeAnima (product tag or top folder name)
├── 0.8
│ └── Ship 0.8.5 (project)
└── 0.9
└── Memory pipeline v2 (project)

规则细节
叶节点项目不可嵌套。分组用 project_folder
日程创建时必填 start_atend_at(或把显式结束条件编码为 end_at
背景可选实体 content — 项目背景 / 说明;出现在列表或任务详情面板
终态状态completed / cancelled / on_hold(另有默认 active

背景说明仅在项目编辑对话框ProjectEditorDialog)中编辑。创建对话框只收集标题 + 日程;主项目视图在页头显示日期、在列表显示任务——不显示 content

不算项目:

  • 持续产品维护(无明确结束)
  • 临时杂务如「清理冰箱压缩机」(无计划日程——留在清单模块)
  • task_list 文件夹或多个任务清单(属于清单模块,非项目管理)

项目进入终态或被删除时,任务处理是显式的:

事件任务行为(v1 默认)
status → completed默认:留在项目内(保留 project_id)。显式 release_tasks: true 把未完成任务移到默认清单(收件箱)。
status → cancelledcompleted
status → on_hold任务保留 project_id;项目 UI 只读或降级编辑
删除项目全部任务移到默认清单is_default 收件箱):清空 project_id,设置 list_id

非活跃项目(on_hold / completed / cancelled)默认在项目侧栏隐藏;可切换显示非活跃(同归档任务清单模式)。

项目归档语义用 project.status(及可选未来 archived_at)——不要复用 task_list.body.closed。任务清单归档(closed: true)仍是:侧栏隐藏、禁止变更清单已归档)。

[v2+] 已归档项目上下文标记弱引用链;文件共归档由用户显式决定。

类型说明归属
任务最小执行单元;待办 / 已完成body.project_id 设置时属于项目
项目材料不绑定任务的文件/文档[v2+] — 文件实体 + 项目引用
链接实体日记、笔记、剪藏[v2+] — 经未来关系层弱引用

清单模块即既有 /tasks 壳路由:多个 task_list、文件夹树、智能清单、已归档清单。

规则细节
范围「不在任何项目」表示 task_item.body.project_idnull
多清单未派入项目的任务可落在任一普通清单(含默认清单 is_default,如收件箱)——不是单一「收件箱」以外的专用池清单
可见性已设 project_id 的任务在清单模块列表视图中隐藏
默认清单懒创建的默认清单仍是清单模块内的普通清单——不是清单模块与项目之间的同步收件箱
无同步收件箱没有自动双向同步或两边都要整理的「inbox」。任一时刻任务属于要么清单模块要么某个项目

智能清单与已归档清单同属该模块;见 智能清单


任务一次只属于一侧:要么清单模块(清单侧),要么恰好一个项目。归属在 body 字段上互斥

动作效果
从清单侧拖 / 移任务 → 项目project_id清空 list_id;任务从清单模块视图与清单计数中消失
从项目移任务 → 清单list_id(用户选清单);清空 project_id——无「恢复上一清单」/ 移回清单
任务从项目 A → 项目 B直接转移;list_id 保持 null
全局搜索匹配全部任务;结果展示归属 清单 / {清单名}Project / {项目标题};点击导航到所属表面
字段类型规则
list_idnumber | null在清单侧时必填(project_id null)。在项目内为 null——勿保留上一清单 id
project_idnumber | null任务在项目内时设置;在清单侧时为 null

不变量:

  • list_id / project_id 恰好其一非 null
  • 清单模块可见 ⇔ project_id IS NULL(且 list_id 已设)
  • 项目模块可见 ⇔ project_id = {当前项目}(且 list_id null)
  • list_id 不得指向文件夹(task_list.is_folder
  • 清单 item_count 只计该 list_id 下的 backlog 任务(project_id null)

番茄专注(pomodoro_task_focus.body.task_item_id / calendar_event_id)按关联目标 id 记录,与项目归属无关。


既有 smart_list 实体与完成类内置预设(今日完成等)留在清单模块;到期浏览在日历。

规则细节
默认范围智能清单查询仅含 project_id null 的任务,除非过滤器显式包含 project_id
v1不要把项目内任务混入智能清单结果(与仅清单侧的清单模块视图一致)
[v2+]project_id 过滤的预设或跨项目视图

对齐实体模型壳作用域

  • project_folderproject 位于当前 subject 的默认私有 world
  • 栖息地 RPC 方法接受可选 subject_kind: user | agent(默认 user,同任务)
  • v1: 项目无跨 user/agent world 共享

表面v1 行为
task.search / entity_search结果含 project_idproject_titlelist_name
ToolSet project文件夹与项目 CRUD(经 toolset_load 加载);project_create / project_patch 接受可选 content 作背景说明
ToolSet tasktask_create / task_update 支持 project_idtask_list / task_searchproject_id 过滤(与 list_id 互斥;默认仅清单侧)

OKR 位于项目之上:目标拆成关键结果;KR 经一个或多个项目落地。OKR 回答「为什么」与「多少」;项目回答「怎么做」与「何时」。

产品是持续命名空间(如「逸灵风」)——不是项目,不结束、不归档。v1:project.body.product_tag?: string 或顶层文件夹命名;无独立产品实体。


项目可弱链接独立实体:

实体关系说明
日记弱引用diary_entry 已存在;链接表或关系层 [v2+]
笔记弱引用未实现
剪藏弱引用未实现
文件 / 照片归属引用文件模块未实现;删项目不删文件

同一日记可链到多个项目。需要未来 memory_references / 关系表,见实体模型


文件与照片是全局资产,项目只是引用入口之一。删项目不删文件。引用的归档行为由用户显式决定。


方面决策
文件夹树分开project_folder vs task_list.is_folder
清单模块保留 — 清单侧临时池
收敛若清单侧使用减少再重新考虑;不要预先合并模块

路由布局
/projects文件夹树 + 项目任务列表 + 任务详情面板(响应式 ThreeColumnLayout);里程碑栏或里程碑对话框
/tasks不变;隐藏 project_id 任务

项目背景说明entity.content)仅在项目编辑对话框中编辑——不在侧栏、项目页头或任务列表。

两者经 subject_kind 继承壳 User / Agent 切换。


  • 既有任务:project_id 缺省 / null — 行为不变
  • 简化模型迁移: 删除 milestone 实体,清空 task_item.body.milestone_id,移除 project.body.completion_criteria;当 entity.content 为空时,从原 completion_criteria 回填
  • 新组件注册到实体组件索引

首版实现明确范围外

  • OKR / 个人目标实体已由目标模块承担(objective;v1 含 KR 式子目标与项目链接)
  • 甘特 / 文件夹级看板(跨项目聚合);清单模块看板见 task.md
  • 笔记、剪藏、文件/照片库与项目材料上传
  • 跨实体引用 UI 与已归档引用上下文
  • 栖息地管理台项目表面
  • 跨 user/agent world 项目共享

实体类型:content。注明处文本字段用实体列。

位置字段类型说明
entitytitlestring文件夹名
bodyparent_idnumber | null父文件夹实体 id
bodysort_ordernumber同级顺序
位置字段类型说明
entitytitlestring项目名
entitycontentstring可选背景 / 说明(UI 仅编辑对话框)
bodyfolder_idnumber | null父文件夹
bodystart_atstringISO 8601
bodyend_atstringISO 8601
bodystatusenumactive | completed | cancelled | on_hold
bodyproduct_tagstring可选 v1 产品标签
bodysort_ordernumber文件夹内同级
位置字段类型说明
bodyproject_idnumber | null在项目内时设置
bodylist_idnumber既有;见 任务归属

卫星壳 Project UI 走 IndexedDB 快照 + outbox(与日记 / 任务同级)。写 RPC 支持可选 client_op_id 幂等;详见 offline-platform.md


全部方法可选 subject_kind: user | agent(默认 user)。传输:POST|WS /rpc/v1

方法用途
projectfolder.list列文件夹树(含嵌套或带 parent_id 扁平)
projectfolder.create创建文件夹(parent_id?titlesort_order?
projectfolder.patch重命名、改父、重排
projectfolder.delete删除文件夹树;项目 → folder_id: null
方法用途
project.list列项目(folder_id?status?
project.stats侧栏徽章用每项目 task_countfolder_id?status?
project.create创建项目(必填 titlestart_atend_at;可选 contentfolder_id、…)
project.get项目详情
project.patch更新字段(含可选 content)、终态状态,或 release_tasks 副作用
project.delete删除项目;任务移到默认清单(收件箱)

任务条目栖息地方法(归属拆分)

Section titled “任务条目栖息地方法(归属拆分)”
方法用途
tasklist.item.list清单模块列任务(清单侧;默认排除项目内)
tasklist.item.create清单模块建任务(只认 list_id,可省略→收件箱)
project.item.list项目模块列任务(必填 project_id
project.item.create项目模块建任务(只认 project_id
task.moveToProject显式移入项目(清空 list_id
task.moveToList显式移回清单(清空 project_id
task.patch仅内容字段(标题/优先级/截止等;不含归属)
task.search跨归属搜索;结果含 project/list 归属
task.complete / uncomplete / delete按 id 共享操作

实现目标:packages/habitat/features/project/(domain + habitat + plugin.ts)与 packages/frontend/features/project/ui/spa);schema 在 packages/habitat/core/db/schema/entity/components/;SAP frames 在 packages/shared/rpc-contract/frames/

另见实体模型 — 项目模块