feat: strengthen backup and mobile workflows
ci / gitleaks (push) Successful in 1m19s
ci / docker (push) Successful in 5m48s

This commit is contained in:
2026-09-16 21:12:52 +08:00
parent 6f38190c92
commit 6c234d7d82
64 changed files with 5059 additions and 635 deletions
+31 -102
View File
@@ -1,117 +1,46 @@
# dodo 产品与技术决策记录
## 定位
## 定位与当前范围
dodo 是一个纯自托管的 TickTick-like 任务与习惯管理工具。目标不是一比一复刻 TickTick,而是做一个数据归自己、界面温暖紧凑、适合个人长期使用的任务系统
dodo 是纯自托管、面向个人长期使用的任务与生活管理 PWA。当前包含任务/子任务、文件夹与清单、今日视图、重复任务、习惯、倒数日、Markdown 备忘录、附件、会话管理、审计和数据备份;不提供番茄钟、自然语言建任务或外部通知渠道
## 当前边界
## 技术与数据
- 首版只做本地开发验证,不部署。
- 首版不做通知渠道:Web Push、Telegram、SMTP 暂不实现。
- 首版附件只做本地存储,不实现 S3。
- 首版不做番茄钟。
- 首版不做自然语言创建任务。
## 技术栈
- Monorepo`frontend/``backend/`
- 前端:Vue 3 + TypeScript + Vite + Tailwind CSS + Shadcn-vue/Reka UI
- 后端:FastAPI + Pydantic v2 + SQLAlchemy 2 Async + Alembic
- 数据库:PostgreSQL,主键 UUIDv7,时间统一 UTC,用户配置时区
- 包管理:uv + pnpm
- 交付:单 Docker 镜像,外部 PostgreSQL
- 许可证:AGPL-3.0
## 数据库
本地开发数据库:
```text
postgresql+asyncpg://postgres:***@10.10.100.99:5433/dodo
```
已从默认 `postgres` 库迁移到独立 `dodo` 库。误建在 `postgres.public` 的 dodo 表已清理。
- MonorepoVue 3 + TypeScript + Vite 前端,FastAPI + Pydantic v2 + SQLAlchemy 2 Async + Alembic 后端
- PostgreSQL 生产、SQLite 测试;UUIDv7 主键,时间点使用 UTC,日历语义使用用户时区
- 单 Docker 镜像,外部 PostgreSQLAGPL-3.0
- 用户业务读写必须按归属过滤;更新任务/备忘录使用乐观锁
## 产品模型
### 任务
- 文件夹 → 清单 → 一层任务树;系统收集箱受保护
- 清单删除定义为归档:保留任务成员关系,归档期间隐藏,恢复后原样出现;永久删除仅允许作用于已归档清单
- 截止日期区分全天日期和具体时间;重复任务支持 RFC 5545 计划重复及“完成后重复”
- 习惯支持完成型/数值型、日/周/月/间隔计划、暂停、历史和归档
- 倒数日支持公历/农历、生日/纪念日、重复、置顶与归档
- 备忘录使用 Markdown,支持软删除、恢复及归档后永久删除
- 文件夹 → 清单 → 任务
- 系统内置收集箱,不允许删除
- 任务支持一层子任务
- 状态:未完成 / 已完成
- 优先级:无 / 低 / 中 / 高
- Markdown 描述
- 截止日期 + 具体时间
- 多提醒设计预留
- 删除为软删除,回收站手动清空
- 支持创建、修改、完成、恢复、删除操作历史
- 并发编辑使用原子乐观锁
## UI 决策
### 重复任务
- 桌面保留左导航/内容/可选详情三栏;移动端使用底部导航
- 手机底栏固定为“今天、习惯、倒数日、设置”,精确匹配当前页面;不使用“更多”中转
- 新建入口使用同一个普通圆形 Plus FAB,禁止装饰性光环或吉祥物
- 设置页使用连续分组:数据、账户与安全、登录设备、活动、危险操作
- 任务、习惯、倒数日、备忘录、操作菜单和确认框统一走 `AppSheet` / `AppDialog` 覆盖层栈;共享背景 inert、焦点陷阱、Escape、忙碌态和嵌套焦点恢复
- 桌面任务/备忘录详情可保持非模态,移动端由同一组件切为底部模态弹层
- RFC 5545 RRULE
- 模板 + 实例
- 修改范围:仅本次 / 本次及以后 / 全部
- 删除单次保存为例外
- 每月 31 日在无 31 日月份跳过
- 逾期完成不影响下次计划日期
## 备份决策
### 习惯
- 完成型 + 数值型
- 每天 / 每周 / 每月 / 间隔天数
- 数值型当日累计,达标后封顶
- 允许补打和修改历史
- 支持暂停区间,暂停期不破坏连续记录
- 归档后保留历史统计
### 倒数纪念日
- 支持倒数日、纪念日、生日
- 支持不重复、每周、每月、每年重复
- 未来显示“还有 N 天”,当天显示“就是今天”,过去显示“已经 N 天”
- 支持单一置顶、归档恢复、编辑和删除
## UI 方向
- 手账生活感
- 中高信息密度
- 1012px 中等圆角
- 细分割线为主,少量浅底色
- 强调色:`#F15A29`
- 只做浅色模式
- 系统字体栈
- 不使用猫猫元素
- 轻微动效
## 页面结构
- 桌面三栏:左导航 / 中任务列表 / 右任务详情
- 手机底部导航
- 顶部快速输入,手机悬浮新增按钮
- 桌面右侧详情栏,手机底部弹层
- 习惯首页:今日习惯列表 + 一周打卡格
- 搜索:顶部搜索框 + 全局搜索快捷键
- “完整备份”专指 `dodo-backup` ZIP version 2,而不是旧 JSON/CSV
- v2 覆盖全部用户业务实体、历史/例外、附件元数据与附件字节;manifest 记录实体数量和每个条目的 SHA-256
- 恢复必须先预检,再用绑定用户、文件摘要和模式的短期单次令牌执行
- 预检拒绝未知/缺失实体、不安全 ZIP 路径、重复条目、异常压缩比/容量、校验和错误、非法字段、破坏关系拓扑或一层任务树的数据
- `merge` 通过持久化 ID/摘要账本保证幂等与冲突可见;`replace` 仅替换当前用户业务数据
- 附件恢复采用同文件系统暂存/隔离与补偿;数据库提交后的清理失败可用同一令牌重试清理,不会再次导入
- 保留 JSON/CSV v1 恢复兼容,但明确其不包含日志、暂停、重复例外和附件字节,仅用于旧数据迁移
## 工程质量
- `/api/v1` API 路径
- 统一错误码、可读提示和字段详情
- 页面内诊断信息 + Toast
- readiness 检查数据库
- 首版不提供 Prometheus metrics
- 审计日志记录操作人、实体、动作、时间和变更摘要
- 手动 JSON 全量导出
- 附件默认 20MB,可用环境变量调整
- 默认允许常用文档与图片,拒绝危险文件类型
## 第一阶段验收
- 可初始化管理员
- 可登录
- 可创建清单和任务
- 后端测试通过
- 前端生产构建通过
- PostgreSQL 迁移成功
- 本地应用可以启动并访问
- API 基路径 `/api/v1`Cookie Session、同源 CSRF、安全响应头、登录限流
- 附件与备份均有容量限制、路径包含检查和用户归属校验
- 后端使用 pytest + ruff,前端使用 Vitest + vue-tsc/Vite;变更结束运行全量测试、构建和 `git diff --check`