179 lines
6.3 KiB
Markdown
179 lines
6.3 KiB
Markdown
# Daily Todo 功能设计文档
|
||
|
||
## 概述
|
||
|
||
每日待办(Daily Todo)是一个以"天"为维度的任务管理模块,与现有的看板(以项目/多天为维度)形成互补。
|
||
|
||
**核心价值:** AI 每天早上自动预生成今日待办(基于前一天未完成的看板任务 + 前一天对话记录),用户可手动增删改。
|
||
|
||
## 时区说明
|
||
|
||
- 所有日期相关字段均使用**用户本地日期**(后端统一用 `datetime.date.today()` 计算,不依赖 UTC)
|
||
- `todo_date` 格式:`YYYY-MM-DD`(本地日期字符串),便于按天查询
|
||
|
||
## 数据模型
|
||
|
||
### DailyTodo 表
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | String(36) | 主键,UUID |
|
||
| user_id | String(36) | 所属用户,索引 |
|
||
| title | String(500) | 待办标题 |
|
||
| is_completed | Boolean | 是否完成,默认 false |
|
||
| source | Enum | `ai_kanban` / `ai_chat` / `manual`,来源 |
|
||
| source_detail | String(500) | 展示用说明文本,如"看板:完成用户登录功能" |
|
||
| source_ref_id | String(36) | 来源原始ID(看板TaskID或对话ConversationID),可空 |
|
||
| todo_date | String(10) | 所属日期,格式 YYYY-MM-DD,复合索引 (user_id, todo_date) |
|
||
| completed_at | DateTime | 完成时间,可空 |
|
||
| created_at | DateTime | 创建时间 |
|
||
| updated_at | DateTime | 更新时间 |
|
||
|
||
**索引:** `INDEX (user_id, todo_date)`,查询今日待办的主要路径
|
||
|
||
### DailyTodoHistory 归档表
|
||
|
||
归档时机:每天凌晨 1:00,APScheduler 清理 7 天前的记录
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | String(36) | 主键,UUID |
|
||
| original_id | String(36) | 原记录ID(原记录归档后可能已删除) |
|
||
| user_id | String(36) | 所属用户 |
|
||
| title | String(500) | 待办标题 |
|
||
| is_completed | Boolean | 最终完成状态 |
|
||
| source | Enum | 来源 |
|
||
| source_detail | String(500) | 展示用说明文本 |
|
||
| todo_date | String(10) | 所属日期 |
|
||
| completed_at | DateTime | 完成时间 |
|
||
| created_at | DateTime | 创建时间 |
|
||
| archived_at | DateTime | 归档时间 |
|
||
|
||
**保留策略:** 归档记录保留 7 天,到期自动删除(APScheduler 每日清理)
|
||
|
||
## 核心功能
|
||
|
||
### F1: 今日待办列表
|
||
- 展示当天的所有待办事项
|
||
- 每条可勾选完成状态(勾选后划线 + 变灰)
|
||
- 支持新增、编辑、删除
|
||
- 按创建时间倒序排列
|
||
- 分页:每页 50 条,支持 `page` + `page_size` 参数
|
||
|
||
### F2: 历史记录
|
||
- 可查看昨天、前天等历史日期的待办
|
||
- 切换日期查看,**只读**(历史不允许修改/删除)
|
||
- 历史数据来自 `DailyTodo` 表(按 todo_date 过滤)
|
||
- 注:不从 `DailyTodoHistory` 表读取——归档表仅作备份保留
|
||
|
||
### F3: AI 自动预生成
|
||
- 触发时机:每天早上 8:00(APScheduler 定时任务),也可手动触发
|
||
- 数据来源:
|
||
1. **看板任务**:前一天创建的、状态 ≠ done 的任务,取前 20 条(按 created_at 倒序)
|
||
2. **对话记录**:前一天创建的对话,取其消息内容前 2000 字发给 LLM
|
||
- AI 处理流程:
|
||
1. 查询上述数据,拼装为分析文本
|
||
2. 发送给 LLM,Prompt 要求输出 JSON 数组:`[{ "title": "...", "reason": "..." }]`
|
||
3. 解析 LLM 返回,若返回为空或解析失败则跳过对话分析
|
||
4. 批量写入 DailyTodo 表(source=ai_kanban / ai_chat)
|
||
- **幂等处理(关键)**:使用事务 + 插入前检查,确保同一天不会重复生成
|
||
```
|
||
BEGIN TRANSACTION
|
||
IF EXISTS (SELECT 1 FROM daily_todos WHERE user_id=? AND todo_date=? AND source IN ('ai_kanban','ai_chat')):
|
||
ROLLBACK -- 已有AI生成,跳过
|
||
ELSE:
|
||
INSERT ... -- 批量写入
|
||
COMMIT
|
||
```
|
||
- **容错**:LLM 不可用时记录日志,跳过该部分,不阻塞整体流程
|
||
- 看板任务上限 20 条,对话分析最多提取 3 条
|
||
|
||
### F4: AI 来源说明
|
||
- 每条 AI 生成的待办,显示其来源说明
|
||
- `source=ai_kanban`:`source_detail` = "看板:{任务标题}",`source_ref_id` = 原始 Task ID
|
||
- `source=ai_chat`:`source_detail` = "对话:{reason 摘要(截取前60字)}"
|
||
|
||
## API 设计
|
||
|
||
### GET /api/todos
|
||
查询待办列表(支持分页)
|
||
- Query: `?date=2026-03-20&page=1&page_size=50`(date 默认当天)
|
||
- Response:
|
||
```json
|
||
{
|
||
"items": [DailyTodoOut],
|
||
"total": 12,
|
||
"page": 1,
|
||
"page_size": 50
|
||
}
|
||
```
|
||
|
||
### POST /api/todos
|
||
新增待办(手动)
|
||
- Body: `{ title: string }`
|
||
- source 固定为 `manual`,todo_date 为当天
|
||
|
||
### PATCH /api/todos/{id}
|
||
更新待办(完成状态 / 标题)
|
||
- Body: `{ is_completed?: boolean, title?: string }`
|
||
- 仅当日待办可修改,历史日期返回 403
|
||
|
||
### DELETE /api/todos/{id}
|
||
删除待办
|
||
- 仅当日待办可删除,历史日期返回 403
|
||
|
||
### POST /api/todos/ai-generate
|
||
手动触发 AI 预生成
|
||
- 检查今日是否已有 AI 生成记录,有则返回 200(幂等,不重复生成)
|
||
- 无则执行 AI 分析流程,返回生成结果
|
||
|
||
### GET /api/todos/summary
|
||
获取今日待办摘要
|
||
- Response: `{ date: "2026-03-20", total: 5, completed: 2, pending: 3 }`
|
||
|
||
## 响应 Schema
|
||
|
||
### DailyTodoOut
|
||
```json
|
||
{
|
||
"id": "uuid",
|
||
"title": "完成用户登录功能",
|
||
"is_completed": false,
|
||
"source": "ai_kanban",
|
||
"source_detail": "看板:完成用户登录功能",
|
||
"todo_date": "2026-03-20",
|
||
"completed_at": null,
|
||
"created_at": "2026-03-20T08:00:00Z"
|
||
}
|
||
```
|
||
|
||
## 定时任务
|
||
|
||
| 任务 | 时间 | 说明 |
|
||
|------|------|------|
|
||
| AI预生成 | 每天 08:00 | 为所有活跃用户执行 AI 预生成 |
|
||
| 历史归档清理 | 每天 01:00 | 删除 7 天前已归档的 DailyTodo 记录 |
|
||
|
||
## 前端页面
|
||
|
||
### TodoView.vue
|
||
- 路径:`/todo`
|
||
- 布局:顶部日期导航 + 下方待办列表
|
||
- 日期导航:今天、昨天、前天快捷按钮 + 日期选择器
|
||
- 今日视图:输入框新增 + 列表 + "AI 规划今日"按钮
|
||
- 历史视图:只读列表,无新增/删除按钮,灰色禁用样式
|
||
- 交互细节:
|
||
- 勾选完成:Motion 动画划线效果
|
||
- 加载状态:骨架屏
|
||
- 空状态:终端风格空提示
|
||
- 风格:sci-fi 全息终端,cyan (#00f5d4) + #03050a,与 AgentView 一致
|
||
|
||
### 侧边栏
|
||
- 新增菜单项:`{ name: '待办', path: '/todo', icon: CheckSquare }`
|
||
|
||
## 技术依赖
|
||
|
||
- 后端:FastAPI + SQLAlchemy + APScheduler + LLM Service
|
||
- 前端:Vue 3 Composition API + 复用 api/index 的 axios 实例
|
||
- 数据库:新表 DailyTodo + DailyTodoHistory(迁移 Alembic 或手动 CREATE TABLE)
|