- item/tag/item_tag/comment/activity 五表迁移,RLS 全覆盖,pg_trgm 子串索引
- 状态机 domain/task.py:非法流转回 5002 并给 allowed,done 写 completed_at
- /workspaces/{ws}/items 列表/详情/新建/改/状态/软删/评论/标签
- 乐观锁 UPDATE...WHERE version,冲突 4009 + current_version
- Web 任务页:视图 tab、快速新建、勾选完成、开工/阻塞、详情事件流、游标分页
- 测试 43 全绿,ruff 干净,Web 构建通过
- 文档:2.Design/API.md 新增,ROADMAP 按已验证口径重写
This commit is contained in:
+35
-21
@@ -145,44 +145,58 @@
|
||||
|
||||
**里程碑目标**:自己开始每天用它记待办,连续 3 天不别扭。
|
||||
|
||||
> 进度口径:`[x]` = 已实现**且验证过**(测试/构建/冒烟),`[ ]` = 未做。每项后面写证据或偏差原因。
|
||||
|
||||
### 1.1 数据(1d)
|
||||
- [ ] `item` `item_assignee` `tag` `item_tag` `comment` `activity` 迁移
|
||||
- [ ] 索引:`(ws_id, status, due_at)`、`(ws_id, owner_id, status)`、`deleted_at` 部分索引
|
||||
- [ ] 全文索引:`zhparser` 或 `pg_bigm` 建在 `title + body_md`
|
||||
- [x] `item` `tag` `item_tag` `comment` `activity` 迁移(`backend/alembic/versions/0002_tasks.py`,revision 0002 ← 0001)
|
||||
- [x] 索引:`ix_item_ws_status_due (ws,status,due_at)`、`ix_item_ws_assignee`、`ix_item_ws_updated`、`ix_item_ws_sort`
|
||||
- [~] 中文全文:**没用 zhparser/pg_bigm,改用 `pg_trgm` + `ILIKE`**。理由:服务器是 Alpine 上的 PG 17,`pg_available_extensions` 只有 `pg_trgm`/`pgcrypto`,装 zhparser 要编译 + 改镜像;trigram 对中文按 3 字符切,子串匹配够用,且 `gin_trgm_ops` 索引能救性能。真正需要"相关度排序"时再上 zhparser(M3 知识库阶段重评)。
|
||||
- [x] 偏差:**没有 `item_assignee` 关联表**,`item.assignee_id` 单列。理由:M1 只有"一个任务一个负责人",多人协作由工单阶段(M2)的 `item_link` 承担;提前上关联表会让每条查询都多一次 join。
|
||||
- [x] RLS:五张新表全部 `ENABLE ROW LEVEL SECURITY` + `workspace_id = app_ws_id()`,并 GRANT 给 `dadao_app`
|
||||
|
||||
### 1.2 领域(1.5d)
|
||||
- [ ] 状态机 `inbox→todo→doing→done`(+ blocked/canceled),非法流转拒绝并给提示
|
||||
- [ ] 所有变更写 `activity`(含 `changed_fields` 增量)
|
||||
- [ ] `version` 乐观锁,冲突返回 409 带当前版本
|
||||
- [x] 状态机 `backend/app/domain/task.py`:`inbox→todo→doing→done`(+ blocked/canceled,`done→todo` 可重开);非法流转抛 `5002` 并回 `allowed`("你可以去 canceled/todo"),不用前端猜
|
||||
- [x] 所有变更写 `activity`(`created` / `updated` / `status_changed{from,to}` / `commented`,payload 是 JSONB)
|
||||
- [x] `version` 乐观锁:`UPDATE ... WHERE version = ?` 看 `rowcount`,冲突回 `4009` + `current_version`(实测 stale 请求拿到 `current=4`)
|
||||
- [x] `done` 写 `completed_at`,重开清空;`deleted_at` 软删,`view=deleted` 才看得到
|
||||
|
||||
### 1.3 API(1.5d)
|
||||
- [ ] 增删改查、批量状态变更、排序(手动 sort_order)
|
||||
- [ ] 视图查询:inbox / today / week / all,支持标签与关键词过滤
|
||||
- [ ] 搜索接口(标题 + 正文,返回高亮片段)
|
||||
- [x] 增删改查(`backend/app/api/items.py`)、`POST /{id}/status`、软删(带 version)
|
||||
- [x] 视图:`inbox|active|today|week|done|canceled|all|deleted`;`today/week` 按 `Asia/Shanghai` 切日界(`settings.default_timezone`),不按 UTC
|
||||
- [x] 过滤:`status`(可重复)、`assignee=me|<uuid>`、`tag`、`q`(标题+正文 ILIKE,实测中文 `周报` 命中)
|
||||
- [ ] **批量状态变更**未做(M1 先做单条,批量等看板拖拽一起上)
|
||||
- [~] 搜索返回高亮片段:未做,只返回命中行。理由:高亮要在客户端按 query 二次切词,纯展示逻辑,等 Web 有真实使用反馈再补
|
||||
- [x] 分页:`(sort_key DESC, id DESC)` keyset 游标;`sort=due` 不分页(NULLS LAST 会把 NULL 行切碎,只有今日/逾期短列表用)
|
||||
|
||||
### 1.4 Web(3d)
|
||||
- [ ] 四视图 + 看板拖拽(列 = 状态)
|
||||
- [ ] 详情侧栏:优先级/截止/标签/备注/子任务(一层)/评论
|
||||
- [ ] 全局快速录入(`Ctrl+K` 或顶部输入框,支持 `#标签` `!优先级` `@人` 语法)
|
||||
- [ ] 键盘流:`j/k` 上下、`Enter` 完成、`e` 编辑
|
||||
- [x] 视图 tab(今天/进行中/收件箱/已完成/全部)+ 搜索框 + 回车快速新建(`web/src/pages/Tasks.tsx`)
|
||||
- [x] 勾选完成/重开、`收下`(inbox→todo)、`开工`(todo→doing)、`阻塞`
|
||||
- [x] 点标题展开:正文、标签、最近 8 条事件流;`409` 时提示"刚被别人改过"并重载
|
||||
- [x] 加载更多(游标),空态文案("今天没有到期的事,挺好。")
|
||||
- [x] `npm run build` 通过:38 modules,`183.26 kB │ gzip 60.08 kB`
|
||||
- [ ] 看板拖拽(列 = 状态)未做
|
||||
- [ ] 详情侧栏(优先级/截止日期选择器/评论输入/子任务)未做——当前详情只读
|
||||
- [ ] 全局快速录入 `#标签 !优先级 @人` 语法未做
|
||||
- [ ] 键盘流 `j/k`、`Enter`、`e` 未做
|
||||
|
||||
### 1.5 安卓(1.5d)
|
||||
- [ ] 列表 + 详情 + 勾选完成
|
||||
- [ ] 下拉刷新、只读缓存(Room,仅离线展示,改动必须联网)
|
||||
- [ ] 任务列表 + 详情 + 勾选完成(`android/` 目前只有 M0 的登录/工作区壳)
|
||||
|
||||
### 1.6 通知与提醒(0.8d)
|
||||
- [ ] 站内通知表与未读角标
|
||||
- [ ] 每日摘要邮件(可关)
|
||||
- [ ] 站内通知表与未读角标(表在 M2 随工单一起建)
|
||||
- [ ] 每日摘要邮件
|
||||
|
||||
### 1.7 测试与验收(0.7d)
|
||||
- [ ] 每个接口一条 happy path + 一条越权用例
|
||||
- [ ] 前端关键交互 e2e(Playwright 起 3 条:登录、建任务、拖动状态)
|
||||
- [x] `backend/tests/test_items.py` 10 个用例:默认收件箱、状态机 happy path 与非法流转、版本冲突、跨租户 3003 且他人列表为空、搜索+标签、`today` 时区边界、软删、评论与事件流、游标翻页不重复
|
||||
- [x] 全量 `pytest -q` → **43 passed**;`ruff check` + `ruff format --check` 全 0
|
||||
- [ ] Playwright e2e 未做
|
||||
- [ ] 性能口径(1000 条下首屏 < 300ms)未实测
|
||||
|
||||
### M1 完成定义(DOD)
|
||||
- [ ] 连续 3 天所有待办都记在里面,没有回到微信/备忘录
|
||||
- [ ] 连续 3 天所有待办都记在里面,没有回到微信/备忘录 —— 只有真实使用能证伪,代码侧无法替代
|
||||
- [ ] 冷启动到"建完第一个任务"< 90 秒(新账号实测)
|
||||
- [ ] 1000 条任务下四视图首屏 < 300ms
|
||||
- [ ] 跨租户测试、越权测试全绿
|
||||
- [x] 跨租户测试、越权测试全绿(`test_tenant_isolation.py` + `test_items.py::test_cross_tenant_access_denied`)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user