98 lines
2.1 KiB
Markdown
98 lines
2.1 KiB
Markdown
# dodo 数据模型
|
||
|
||
所有业务实体使用 UUIDv7 主键并按 `user_id` 隔离。生产使用 PostgreSQL,测试使用 SQLite;模型保持两者兼容。
|
||
|
||
## app_state
|
||
|
||
- `key` 主键
|
||
- `created_at`
|
||
|
||
## users
|
||
|
||
- `id`
|
||
- `username` 唯一
|
||
- `password_hash`
|
||
- `timezone`
|
||
- `created_at`
|
||
|
||
## sessions
|
||
|
||
- `id`
|
||
- `token_hash` 唯一
|
||
- `user_id` → users,级联删除
|
||
- `expires_at`
|
||
- `created_at`
|
||
|
||
## folders
|
||
|
||
- `id`
|
||
- `user_id` → users
|
||
- `name`
|
||
- `position`
|
||
- `created_at`
|
||
- `deleted_at`,非空表示软删除
|
||
|
||
删除文件夹不会删除清单;清单的 `folder_id` 被置空。
|
||
|
||
## task_lists
|
||
|
||
- `id`
|
||
- `user_id` → users
|
||
- `folder_id` → folders,可空
|
||
- `name`
|
||
- `is_inbox`,每个用户初始化时创建一个受保护的系统收集箱
|
||
- `position`
|
||
- `created_at`
|
||
- `deleted_at`,非空表示软删除
|
||
|
||
删除普通清单时,其未删除任务原子移动到系统收集箱。系统收集箱不可重命名或删除。
|
||
|
||
## tags
|
||
|
||
- `id`
|
||
- `user_id` → users
|
||
- `name`,同一用户内唯一
|
||
- `color`
|
||
- `created_at`
|
||
|
||
标签是用户级全局实体,不隶属于清单。
|
||
|
||
## task_tags
|
||
|
||
- `task_id` → tasks
|
||
- `tag_id` → tags
|
||
- `(task_id, tag_id)` 联合主键
|
||
|
||
## tasks
|
||
|
||
- `id`
|
||
- `user_id` → users
|
||
- `list_id` → task_lists
|
||
- `parent_id` → tasks,可空;仅允许一层子任务且必须与父任务同清单
|
||
- `title`
|
||
- `description`
|
||
- `priority`(0–3)
|
||
- `completed`
|
||
- `due_at`,可空
|
||
- `version`,乐观锁版本;单任务更新用 `id + user_id + version` 原子比较更新
|
||
- `position`
|
||
- `created_at`
|
||
- `updated_at`
|
||
- `deleted_at`,非空表示进入回收站
|
||
|
||
顶层任务软删除、恢复或永久删除时同步处理直接子任务。列表与回收站使用 `(created_at, id)` 作为稳定游标排序键。
|
||
|
||
## 迁移
|
||
|
||
- `0001_initial.py`:已部署的初始模式,不修改
|
||
- `0002_task_management.py`:新增文件夹/清单软删除列、标签表、任务标签关联表及游标/回收站索引
|
||
|
||
## 后续阶段预留
|
||
|
||
- task_reminders
|
||
- task_recurrence_templates
|
||
- task_recurrence_exceptions
|
||
- habits / habit_logs / habit_reminders
|
||
- attachments
|
||
- audit_logs
|