# 个人看板工具 · MVP 开发任务卡 > 版本:v2(按评审修订) > 决策前提:**固定三列** · **TaskRepository 接口 + localStorage 存储** · **dueDate 仅存日期** · **不引入 vue-router** ## 已定死的四项决策 | 决策 | 结论 | 理由 | |---|---|---| | 列是否可配置 | **否**,固定 `todo` / `doing` / `done` | 可配置列需引入 `columns` 表,成本翻倍,个人场景无收益 | | 存储 | **`TaskRepository` 接口 + localStorage 起步** | 200 任务约 60KB,localStorage 足够;保留接口便于换 Dexie | | `dueDate` 语义 | **仅日期 `YYYY-MM-DD`** | 个人看板不需要时刻,直接避开时区坑 | | 路由 | **不引入 vue-router** | 单视图 + 抽屉/弹窗即可,减少依赖 | --- ## 总览 | ID | 任务 | 优先级 | 估时 | 依赖 | |---|---|---|---|---| | T01 | 工程初始化与规范 | P0 | 0.5d | — | | T02 | 技术决策记录(ADR) | P0 | 0.25d | — | | T03 | 领域类型与常量 | P0 | 0.25d | T02 | | T04 | TaskRepository 接口 + localStorage 实现(含 schema 迁移) | P0 | 0.5d | T03 | | T05 | 排序算法:sortOrder 中点插入 + normalize | P0 | 0.5d | T03 | | T06 | Pinia store + 多标签页同步 | P0 | 0.5d | T04, T05 | | T07 | 看板三列骨架与空状态 | P0 | 0.5d | T06 | | T08 | TaskCard 任务卡片组件 | P0 | 0.5d | T07 | | T09 | UI 基础组件(Drawer / Toast / DatePicker / TagInput) | P0 | 1d | T01 | | T10 | 快速新增任务 | P0 | 0.5d | T07 | | T11 | 任务详情表单(创建 / 编辑 / 校验) | P0 | 1d | T09, T10 | | T12 | 删除与撤销 | P0 | 0.5d | T11 | | T13 | 拖拽改状态 + 列内排序(含筛选态保护) | P0 | 1d | T08, T11 | | T14 | 导出 / 导入 JSON + 启动自动快照 | **P0** | 0.5d | T04 | | T15 | 搜索与筛选 | P0.5 | 0.5d | T07 | | T16 | 逾期提示 + 键盘快捷键 | P1 | 0.5d | T10 | | T17 | 已完成归档 + 长列表性能 | P1 | 0.5d | T13 | | T18 | 核心逻辑单元测试 | P0 | 0.5d | T05, T14 | | T19 | E2E 关键路径测试 | P1 | 0.5d | T13, T14 | | T20 | 生产构建与部署 | P0 | 0.5d | T18 | **合计:11 人天**(纯开发,不含缓冲)→ 实际排期按 ×1.4 计,约 **15 天**。 **关键里程碑**:T01–T13 完成后即「可用 MVP」;T14 是数据安全底线,不得后置。 --- ## 任务卡明细 ### T01 · 工程初始化与规范 **优先级** P0 **估时** 0.5d **依赖** — **描述** Vite + Vue3 + TS 工程初始化;接入 Tailwind(**锁定 v4 + `@tailwindcss/vite`**)、Pinia、Vitest;配置 ESLint + Prettier;统一目录结构。 **验收标准** - [x] `npm run dev` 可启动,页面渲染正常 - [x] Tailwind 原子类生效(页面出现预期样式) - [x] `npm run lint` 与 `npm run format` 均可执行且无报错 - [x] `npm run test` 可运行(哪怕只有 1 个示例用例) - [x] 目录结构为 `src/{components,composables,data,stores,types,utils,views}` --- ### T02 · 技术决策记录(ADR) **优先级** P0 **估时** 0.25d **依赖** — **描述** 将上述四项决策写入 `docs/adr.md`,含背景、结论、被否决的方案及原因。 **验收标准** - [x] `docs/adr.md` 覆盖 4 项决策 - [x] 每项决策写明「否决了什么、为什么」 --- ### T03 · 领域类型与常量 **优先级** P0 **估时** 0.25d **依赖** T02 **描述** 定义 `Task`、`ColumnId`、`Priority` 类型与列定义常量。 **验收标准** - [x] `Task` 含 `id/title/description/status/priority/tags/dueDate/sortOrder/createdAt/updatedAt/completedAt` - [x] `status` 为字面量联合类型 `'todo' | 'doing' | 'done'`,**不使用 `enum`** - [x] `dueDate` 类型为 `string`(`YYYY-MM-DD`)或 `null` - [x] 列定义常量为只读,含 id / 标题 / 顺序 - [x] 无 `any`,`vue-tsc` 通过 --- ### T04 · TaskRepository 接口 + localStorage 实现 **优先级** P0 **估时** 0.5d **依赖** T03 **描述** 定义 `TaskRepository` 接口,提供 localStorage 实现,含 `schemaVersion` 与迁移入口。 > 实现修订:接口最终定为 `load()` / `save(tasks)` 的**整份快照读写**,而非细粒度 CRUD。 > 原因:数据量小(约 60KB),整份写入不会产生「部分写入」的不一致状态;且排序、导入、 > 跨标签页同步本质上都是快照操作。接口与实现分离这一目标不变。 **验收标准** - [x] 接口与实现分离,UI/Store 只依赖接口 - [x] 持久化结构含 `schemaVersion` 字段 - [x] 提供迁移入口(`MIGRATIONS` 表),未知/过高版本有明确报错而非静默降级 - [x] localStorage 不可用(隐私模式)时给出可读错误,不白屏 - [x] 写入失败(配额超限)抛出 `StorageWriteError` 并在界面提示 - [x] 数据损坏时**先备份到 `*.corrupt.<时间戳>` 再报错**,不覆盖用户原数据 --- ### T05 · 排序算法 **优先级** P0 **估时** 0.5d **依赖** T03 **描述** 实现 `sortOrder` 相邻中点插入;间距小于 `1e-6` 时对该列执行 normalize 重排(间隔 1024)。 **验收标准** - [x] 在任意两卡之间插入,顺序正确 - [x] 连续 100 次中间插入后,顺序仍正确(不出现精度崩坏) - [x] normalize 后同列 `sortOrder` 严格递增且间距均匀 - [x] 纯函数实现,无副作用,可独立单测 --- ### T06 · Pinia store + 多标签页同步 **优先级** P0 **估时** 0.5d **依赖** T04, T05 **描述** Store 作为内存态唯一来源,读写走 repository;通过 `BroadcastChannel` 广播变更,使多标签页一致。 **验收标准** - [x] 所有变更先写 repository 再更新内存态(或反之,但必须单一顺序) - [x] 标签页 A 的修改,标签页 B 在 1 秒内自动反映 - [x] 跨列拖拽在一次事务内同时更新 `status` 与 `sortOrder` - [x] 无「卡片已换列但顺序仍旧」的中间态 --- ### T07 · 看板三列骨架与空状态 **优先级** P0 **估时** 0.5d **依赖** T06 **描述** 三列布局(待办 / 进行中 / 已完成),响应式;每列含标题、计数、空状态。 **验收标准** - [x] ≥1024px 三列并排;<768px 纵向堆叠 - [x] 每列显示任务计数 - [x] 空列显示引导文案 - [x] 列内容区可独立滚动,页面不整体抖动 --- ### T08 · TaskCard 任务卡片组件 **优先级** P0 **估时** 0.5d **依赖** T07 **描述** 卡片展示标题、优先级、标签、截止日期;逾期与已完成有区分样式。 **验收标准** - [x] 三种优先级视觉可区分 - [x] 逾期(`dueDate` < 今天且未完成)显示警示色 - [x] 已完成卡片置灰 / 降饱和 - [x] 标签超过 3 个折叠为 `+N` - [x] 长标题截断,不撑破卡片 --- ### T09 · UI 基础组件 **优先级** P0 **估时** 1d **依赖** T01 **描述** 自建(或基于 headless 库)实现 Drawer/Modal、Toast、DatePicker、TagInput。**注意:Tailwind 只提供样式,不提供行为。** **验收标准** - [x] Drawer 支持 ESC 关闭、遮罩点击关闭、**焦点陷阱(focus trap)** - [x] Toast 支持自动消失与手动关闭 - [x] DatePicker 输出 `YYYY-MM-DD`,可清空 - [x] TagInput 支持回车添加、退格删除、去重 - [x] 上述组件均有可访问性属性(`role` / `aria-*`) --- ### T10 · 快速新增任务 **优先级** P0 **估时** 0.5d **依赖** T07 **描述** 列顶部或全局输入框,回车即建卡,默认进入「待办」。 **验收标准** - [x] 聚焦输入 → 输入标题 → 回车,卡片出现在列首 - [x] 空标题不可提交 - [x] 提交后输入框清空且保持聚焦(可连续录入) - [x] 全流程 ≤3 秒可完成 --- ### T11 · 任务详情表单 **优先级** P0 **估时** 1d **依赖** T09, T10 **描述** 创建与编辑复用同一表单,置于 Drawer 内。 **验收标准** - [x] 可编辑标题、描述、优先级、截止日期、标签 - [x] 标题必填,空值给出内联错误提示 - [x] 取消编辑不产生脏数据 - [x] 保存后看板与详情同步更新 - [x] `updatedAt` 正确刷新 --- ### T12 · 删除与撤销 **优先级** P0 **估时** 0.5d **依赖** T11 **描述** 删除任务后提供 Toast 撤销入口(保留最近一次删除内容)。 **验收标准** - [x] 删除后卡片立即消失 - [x] Toast 提供「撤销」,点击后卡片**连同原顺序**恢复 - [x] 撤销窗口结束后数据真正移除 - [x] 删除需二次确认(或依赖撤销兜底) --- ### T13 · 拖拽改状态 + 列内排序 **优先级** P0 **估时** 1d **依赖** T08, T11 **描述** 基于 `vue-draggable-plus` 实现跨列拖动与列内排序。 **验收标准** - [x] 跨列拖动更新 `status`,刷新后保持 - [x] 列内拖动更新顺序,刷新后保持 - [x] **筛选/搜索激活时禁用列内排序**(仅允许跨列改状态),避免顺序写坏 - [x] 拖拽中不触发卡片点击(区分 click 与 drag) - [x] 触摸设备可拖动 --- ### T14 · 导出 / 导入 JSON + 自动快照 **优先级** **P0** **估时** 0.5d **依赖** T04 **描述** 一键导出全部任务为 JSON;支持覆盖式导入;启动时自动快照到独立 key。**local-first 下这是唯一的数据安全网。** **验收标准** - [x] 导出文件名含日期,内容含 `schemaVersion` - [x] 导入前校验结构,非法文件给出明确错误且**不破坏现有数据** - [x] 导入为覆盖式,执行前二次确认 - [x] 每次启动写入快照 key,保留最近 3 份 - [x] 导出 → 清空 → 导入,数据完全还原 --- ### T15 · 搜索与筛选 **优先级** P0.5 **估时** 0.5d **依赖** T07 **描述** 关键词搜索(标题 + 描述)+ 按优先级/标签筛选。 **验收标准** - [x] 中文搜索用 `includes` 即可,**不引入分词库** - [x] 输入有防抖(≤300ms) - [x] 多条件为「与」关系 - [x] 筛选后列计数反映筛选结果 - [x] 一键清空全部筛选条件 --- ### T16 · 逾期提示 + 键盘快捷键 **优先级** P1 **估时** 0.5d **依赖** T10 **描述** 顶部统计条显示今日到期与逾期数量;提供常用快捷键。 **验收标准** - [x] 顶部显示「今日到期 N / 逾期 N」,可点击直接筛选 - [x] `N` 聚焦快速新增;`/` 聚焦搜索;`Esc` 关闭抽屉 - [x] 输入框内不劫持快捷键 - [x] 快捷键有可查看的帮助提示 --- ### T17 · 已完成归档 + 长列表性能 **优先级** P1 **估时** 0.5d **依赖** T13 **描述** 已完成列支持归档;长列表不卡顿。 **验收标准** - [x] 可一键归档「已完成」中超过 N 天的任务 - [x] 归档任务默认不显示,可切换查看 - [x] 单列 200 张卡片滚动仍流畅(必要时虚拟滚动) - [x] 归档操作可撤销 --- ### T18 · 核心逻辑单元测试 **优先级** P0 **估时** 0.5d **依赖** T05, T14 **描述** 只覆盖纯逻辑,UI 不强制测试。 **验收标准** - [x] 排序:中间插入、normalize、边界值 - [x] 筛选:单条件、多条件组合、空结果 - [x] 状态流转:`completedAt` 的写入与清除 - [x] 导入校验:合法 / 缺字段 / 版本不匹配 - [x] 核心模块行覆盖率 ≥80% --- ### T19 · E2E 关键路径测试 **优先级** P1 **估时** 0.5d **依赖** T13, T14 **描述** Playwright 覆盖一条主链路。 **验收标准** - [x] 新增任务 → 拖到进行中 → 标记完成 → **刷新后状态仍正确** - [x] 导出 → 清空 → 导入 → 数据一致 - [x] 每个用例使用独立浏览器上下文,互不污染 --- ### T20 · 生产构建与部署 **优先级** P0 **估时** 0.5d **依赖** T18 **描述** 生产构建、静态托管、基础可用性验证。 **验收标准** - [x] `npm run build` 无 TS 错误、无警告阻断 - [x] 产物可静态托管,刷新不 404 - [x] 首屏加载 ≤2s(本地网络) - [x] `README.md` 写明启动、构建、部署、数据备份方式 --- ## 完成定义(DoD) - 功能可演示,有明确交互结果 - **核心纯逻辑必须有单测;UI 组件不强制** - 数据刷新后不丢失 - 无阻断级 lint / type 错误 - 涉及数据结构的变更,必须同步更新 `schemaVersion` 与迁移逻辑