docs(任务模块): 任务归档 T-ARC 需求与设计 (T-ARC-01~08)
- 需求文档 §3.15: 手动归档(⋯菜单+连带子任务)/自动归档(项目级档位 3天/一周/一月/永不)/归档排除/游标分页大量查询/恢复/彻底删除/配置入口/权限 - 功能设计 §15: Project.autoArchive + Task.archived/archivedAt/archiveSource、 归档/恢复/归档查询 API、自动归档双保险执行(读时惰性+小时cron)、 边界处理; 覆盖自检表更新为 157 条 - 数据库设计: Project 补 notes/taskKinds/icon/autoArchive 字段, Task 补归档三字段与两索引, 迁移清单标注 20261026000000_task_archive 待实施
This commit is contained in:
@@ -319,7 +319,63 @@
|
||||
|
||||
---
|
||||
|
||||
## 15. 覆盖自检表
|
||||
## 15. 任务归档(T-ARC)
|
||||
|
||||
> 归档与 T-FL 显示控制的分层:**隐藏 = 展示过滤(可逆、不落库)**;**归档 = 移出主工作集(落库、可恢复)**。
|
||||
> 自动归档的倒计时起点是任务**被隐藏的时刻**(由 `doneAt + 列保留窗口` 推导,不新增 hiddenAt 字段)。
|
||||
|
||||
### 15.1 数据
|
||||
|
||||
| 落点 | 说明 |
|
||||
| --- | --- |
|
||||
| `Project.autoArchive VARCHAR(8) NOT NULL DEFAULT 'never'` | 自动归档档位:`3d` / `1w` / `1m` / `never`;项目级共享(同 T-FL-12 口径) |
|
||||
| `Task.archived BOOLEAN NOT NULL DEFAULT false` | 归档标记;归档**不迁移表**,主查询统一追加 `archived = false` |
|
||||
| `Task.archivedAt DATETIME(3) NULL` | 归档时刻(查询过滤与排序键) |
|
||||
| `Task.archiveSource VARCHAR(8) NULL` | `'manual'` / `'auto'`,溯源用 |
|
||||
| 索引 | `idx_task_project_archived (projectId, archived, archivedAt)`;`idx_task_project_status_archived (projectId, status, archived)` |
|
||||
| 迁移(待实施) | `20261026000000_task_archive`:三列 + 两索引(MySQL DDL 见数据库设计文档 §3.1/§3.4) |
|
||||
|
||||
### 15.2 API
|
||||
|
||||
| 接口 | 说明 |
|
||||
| --- | --- |
|
||||
| `POST /api/tasks/:id/archive` | 手动归档:父任务连带全部后代置 `archived/archivedAt/archiveSource='manual'`;幂等(已归档直接返回当前态) |
|
||||
| `POST /api/tasks/:id/unarchive` | 恢复:父任务连带后代清除归档三字段;原列因 `ON DELETE RESTRICT` 必存在,状态保持不变 |
|
||||
| `GET /api/projects/:id/tasks/archived?keyword&kind&columnId&from&to&cursor&limit` | 归档查询:`keyword` 标题 LIKE、`kind`、`columnId`、`from/to`(归档日期,含边界);`limit` 默认 20、≤100;游标 = `archivedAt+id` 复合降序,返回 `{ items, nextCursor }`,`nextCursor` 为空即到底 |
|
||||
| `PUT /api/projects/:id` | 增接受 `autoArchive`,枚举校验(非法 400) |
|
||||
| 既有查询 | `GET /projects/:id/tasks`、统计、列计数等全部追加 `archived: false`;`taskCount`(projectSummary)同口径 |
|
||||
|
||||
### 15.3 自动归档执行
|
||||
|
||||
- **归档到期判定**:`due = 隐藏时刻 + autoArchive 档位`;隐藏时刻 = `doneAt + 列保留窗口`(复用 `retentionStart` 口径,含 `today/3d/week/month`;`forever` 列任务永不隐藏、不进入自动归档)。
|
||||
- **执行时机(双保险)**:
|
||||
1. **读时惰性**:加载项目任务时对该项目先执行一轮到期归档(保证用户看到的数据与判定一致,刚到期的任务当场消失);
|
||||
2. **每小时 cron 兜底**:扫描全部 `autoArchive != 'never'` 项目的到期 done 任务批量归档(`archiveSource='auto'`)。
|
||||
- **幂等**:`archived = false` 且 `status = 'done'` 且 `doneAt` 非空才进入判定;重复执行无副作用。
|
||||
- **批量写**:cron 用 `updateMany`(按到期集合),读时惰性用单项目范围 `updateMany`。
|
||||
|
||||
### 15.4 前端
|
||||
|
||||
| 落点 | 说明 |
|
||||
| --- | --- |
|
||||
| 任务 `⋯` 菜单 | 新增「归档」(`Dialog.confirm`,含子任务时提示连带条数);成功后列表/看板乐观移除 |
|
||||
| 项目管理 | 「归档设置」分区:`Selector` 四档(3 天后/一周后/一月后/永不),保存即生效 |
|
||||
| 项目视图头部 | 项目栏新增「已归档」入口 → 全屏弹层:过滤条(关键词/类型/列/归档时段)+ 分页「加载更多」+ 行内「恢复 / 删除」 |
|
||||
| 主视图 | 列表/看板无需感知归档(数据源已排除);恢复后经 `load()` 回到原位 |
|
||||
|
||||
### 15.5 边界
|
||||
|
||||
| 场景 | 处理 |
|
||||
| --- | --- |
|
||||
| 归档父任务时新增/恢复子任务 | 子任务随父判定:父 archived 则子不单独出现在主列表(查询按父排除) |
|
||||
| 自动归档期间用户正在编辑该任务 | 详情弹层保存正常(归档不锁写);保存后任务仍在归档集 |
|
||||
| 恢复后任务再次到期隐藏 | 重新进入自动归档倒计时(`doneAt` 未变则可能立即再次到期,属预期) |
|
||||
| 「永不」档位 | 不做任何自动归档;手动归档不受影响 |
|
||||
| 拷贝任务 | 拷贝件不继承归档态(`copyTask` 不复制 archived 三字段) |
|
||||
|
||||
---
|
||||
|
||||
## 16. 覆盖自检表
|
||||
|
||||
| 模块 | 编号范围 | 条数 | 本文对应章节 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -337,6 +393,7 @@
|
||||
| 数据需求 | T-DT-01 ~ 09 | 9 | §12 |
|
||||
| 非功能需求 | T-NF-01 ~ 05 | 5 | §13 |
|
||||
| 异常与边界 | T-EX-01 ~ 19 | 19 | §14 |
|
||||
| **合计** | — | **149** | — |
|
||||
| 任务归档 | T-ARC-01 ~ 08 | 8 | §15 |
|
||||
| **合计** | — | **157** | — |
|
||||
|
||||
> 需求文档共 **149 条**需求点,本文逐条给出设计落点,覆盖率 **149/149**。(其中 `T-BD-14~16`、`T-COL-*`、`T-EX-18~19`、`T-VW-08~10`、`T-PJ-11/12`、`T-UI-11` 为评审后新增,编号不连续,非笔误。)
|
||||
> 需求文档共 **157 条**需求点,本文逐条给出设计落点,覆盖率 **157/157**。(其中 `T-BD-14~16`、`T-COL-*`、`T-EX-18~19`、`T-VW-08~10`、`T-PJ-11/12`、`T-UI-11`、`T-ARC-*` 为评审后新增,编号不连续,非笔误。)
|
||||
|
||||
Reference in New Issue
Block a user