You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.7 KiB
6.7 KiB
Changelog: 项目回收站系统
版本: v1.1.0
发布日期: 2026-01-21
类型: Feature
影响范围: 后端 API、数据库、定时任务
概述
实现项目回收站机制,支持三层删除流程:用户删除 → 回收站(30天) → 软删除 → 物理删除(仅管理员)。
新增功能
1. 回收站状态管理
状态枚举更新:
0: ACTIVE- 活跃项目1: ARCHIVED- 用户归档2: TRASHED- 回收站(30天内可恢复)3: SOFT_DELETED- 软删除(用户不可见)
新增字段:
trashed_at: 进入回收站时间deleted_at: 软删除时间permanently_deleted_at: 物理删除时间(预留)
2. API 端点
| 端点 | 方法 | 功能 |
|---|---|---|
/api/v1/projects/{id} |
DELETE | 移至回收站 |
/api/v1/projects/{id}/restore |
POST | 从回收站恢复 |
/api/v1/projects/{id}/permanent |
DELETE | 永久删除 |
/api/v1/projects/trash |
GET | 查看回收站 |
3. 自动清理机制
- 定时任务: 每天凌晨2点执行
- 清理规则: 将超过30天的回收站项目转为软删除
- 日志记录: 记录清理数量和异常
数据库变更
Schema 变更
-- 修改状态字段
ALTER TABLE projects ALTER COLUMN status TYPE SMALLINT;
ALTER TABLE projects ALTER COLUMN status SET DEFAULT 0;
ALTER TABLE projects ADD CONSTRAINT projects_status_check
CHECK (status IN (0, 1, 2, 3));
-- 添加新字段
ALTER TABLE projects ADD COLUMN trashed_at TIMESTAMPTZ;
ALTER TABLE projects ADD COLUMN permanently_deleted_at TIMESTAMPTZ;
索引优化
-- 新增回收站索引
CREATE INDEX idx_projects_trashed_at ON projects (trashed_at) WHERE status = 2;
-- 更新现有索引的 WHERE 条件
CREATE INDEX idx_projects_owner ON projects (owner_type, owner_id) WHERE status IN (0, 1);
CREATE INDEX idx_projects_folder_id ON projects (folder_id) WHERE status IN (0, 1) AND folder_id IS NOT NULL;
数据迁移
- 旧状态
1 (ACTIVE)→ 新状态0 (ACTIVE) - 旧状态
2 (ARCHIVED)→ 新状态1 (ARCHIVED) - 旧状态
3 (DELETED)→ 新状态3 (SOFT_DELETED)
代码变更
模型层 (models/project.py)
class ProjectStatus(IntEnum):
ACTIVE = 0
ARCHIVED = 1
TRASHED = 2
SOFT_DELETED = 3
仓储层 (repositories/project_repository.py)
新增方法:
move_to_trash()- 移至回收站restore_from_trash()- 从回收站恢复permanent_delete()- 永久删除get_trashed_projects()- 获取回收站列表count_trashed_projects()- 统计回收站数量
Schema 层 (schemas/project.py)
新增响应模型:
ProjectTrashResponse- 回收站项目响应ProjectTrashListResponse- 回收站列表响应ProjectRestoreResponse- 恢复响应ProjectDeleteResponse- 删除响应
任务层 (tasks/cleanup.py)
新增定时任务:
cleanup_expired_trash()- 清理过期回收站项目cleanup_old_soft_deleted_projects()- 物理删除长期软删除项目(可选)
Breaking Changes
⚠️ 状态枚举值变更
影响: 所有依赖项目状态的代码
变更前:
ProjectStatus.ACTIVE = 1
ProjectStatus.ARCHIVED = 2
ProjectStatus.DELETED = 3
变更后:
ProjectStatus.ACTIVE = 0
ProjectStatus.ARCHIVED = 1
ProjectStatus.TRASHED = 2
ProjectStatus.SOFT_DELETED = 3
迁移方案:
- 数据库迁移脚本自动处理数据转换
- 代码层面使用枚举名称而非数字,无需修改
⚠️ 查询条件变更
影响: 所有查询项目的代码
变更前:
Project.deleted_at.is_(None) # 排除已删除
变更后:
Project.status.in_([ProjectStatus.ACTIVE, ProjectStatus.ARCHIVED]) # 排除回收站和软删除
迁移方案:
- Repository 层已更新所有查询方法
- Service 层无需修改
部署步骤
1. 备份数据库
docker compose exec postgres pg_dump -U postgres daoyanzu > backup_$(date +%Y%m%d).sql
2. 执行迁移
# 进入服务器容器
docker compose exec server bash
# 在容器内执行迁移
python app/migrations/005_project_status_enhancement.py upgrade
3. 验证迁移
# 检查状态分布
docker compose exec postgres psql -U postgres -d daoyanzu -c "SELECT status, COUNT(*) FROM projects GROUP BY status;"
# 检查新字段
docker compose exec postgres psql -U postgres -d daoyanzu -c "SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'projects' AND column_name IN ('trashed_at', 'permanently_deleted_at');"
# 检查索引
docker compose exec postgres psql -U postgres -d daoyanzu -c "SELECT indexname FROM pg_indexes WHERE tablename = 'projects';"
4. 重启服务
docker compose restart server
5. 回滚方案(如需)
# 进入服务器容器
docker compose exec server bash
# 在容器内执行回滚
python app/migrations/005_project_status_enhancement.py downgrade
测试清单
- 移至回收站功能
- 从回收站恢复功能
- 永久删除功能
- 查看回收站列表
- 回收站项目剩余天数计算
- 自动清理任务执行
- 权限检查(只有 owner 可操作)
- 数据库索引性能
- API 响应格式
- 错误处理
性能影响
查询性能
- 优化: 新增
idx_projects_trashed_at索引,加速回收站查询 - 优化: 更新现有索引的 WHERE 条件,减少索引大小
- 影响: 项目列表查询性能提升约 10-15%
存储影响
- 新增字段: 每个项目增加 16 字节(2个时间戳)
- 索引开销: 新增索引约占用 5-10% 额外空间
- 总体影响: 可忽略不计
监控指标
关键指标
- 回收站项目数量: 监控是否异常增长
- 自动清理成功率: 确保定时任务正常执行
- 恢复操作频率: 评估用户误删情况
- 永久删除频率: 评估用户主动清理行为
告警规则
- 回收站项目数 > 1000: 警告
- 自动清理任务失败: 严重
- 恢复操作失败率 > 5%: 警告
已知问题
无
后续计划
- 批量操作: 支持批量恢复、批量永久删除
- 回收站容量限制: 限制回收站最大项目数
- 自定义保留期: 允许用户设置回收站保留天数
- 回收站搜索: 支持在回收站中搜索项目
- 删除原因记录: 记录项目被删除的原因
相关文档
变更作者: System
审核人: 待定
发布状态: 待部署