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.
7.4 KiB
7.4 KiB
Changelog: 文件夹服务规范符合度修复
日期: 2026-01-28
类型: 文档修复
影响范围: docs/requirements/backend/04-services/project/folder-service.md
版本: v3.4
修复概述
完整修复 folder-service.md 文档的技术栈规范符合度问题,包括数据库设计、应用层实现、职责划分等多个方面。
修复内容
阶段 1: 基础规范修复(v3.3)
1.1 移除物理外键约束
问题: 使用了 FOREIGN KEY 物理约束,违反项目规范
修复:
- 移除所有
FOREIGN KEY约束 - 改为逻辑外键(仅注释说明关联关系)
- 在应用层(Service/Repository)实现引用完整性校验
影响表:
folders表:parent_folder_id,owner_id,cover_image_idfolder_members表:folder_id,user_id,invited_byfolder_shares表:folder_id,shared_with_user_id,created_byfolder_export_jobs表:folder_id,user_idprojects表:folder_id
1.2 修复时间戳字段
问题: 使用了 now() 函数,不符合规范
修复:
- SQL 层:
DEFAULT now()→DEFAULT CURRENT_TIMESTAMP - Python 层:
datetime.now(timezone.utc)→datetime.now(UTC)
影响字段:
created_atupdated_atjoined_atstarted_atcompleted_atexpires_at
1.3 修复枚举类型定义
问题:
- 缺少 Python IntEnum 定义
- 缺少枚举值映射表
修复:
- 添加
FolderCategory(IntEnum)定义 - 添加
MemberRole(IntEnum)定义 - 添加成员角色枚举值映射表
- 添加导出状态枚举值映射表
1.4 添加 SQL 注释
问题: 缺少表和字段的 SQL 注释
修复:
- 为所有表添加
COMMENT ON TABLE - 为所有字段添加
COMMENT ON COLUMN - 注释中说明逻辑外键关系
- 注释中说明枚举值含义
影响表:
foldersfolder_membersfolder_sharesfolder_export_jobs
1.5 移除 SQLModel foreign_key 参数
问题: SQLModel 模型中使用了 foreign_key 参数
修复:
- 移除所有
foreign_key参数 - 仅保留类型注解和字段定义
1.6 增强引用完整性校验
问题: 缺少应用层的引用完整性校验
修复:
- 添加
_validate_user_exists()方法 - 添加
_validate_folder_exists()方法 - 添加
_validate_attachment_exists_and_owned()方法 - 在所有相关操作中调用校验方法
1.7 补充完整的 Repository 实现
问题: FolderRepository 实现不完整
修复:
- 补充所有 CRUD 方法
- 添加权限检查方法
- 添加循环引用检测方法
- 添加树形结构查询方法
1.8 添加日志记录
问题: 缺少操作日志
修复:
- 在关键操作中添加
logger.info()记录 - 记录创建、更新、删除、移动等操作
阶段 2: 深度问题修复(v3.4)
2.1 修复 UUID 生成方式
问题: 使用了 DEFAULT gen_uuid_v7(),违反规范
修复:
- 移除所有表的
DEFAULT gen_uuid_v7() - 改为应用层生成:
id=generate_uuid() - 添加注释:
-- UUID 由应用层生成
影响表:
foldersfolder_membersfolder_sharesfolder_export_jobs
2.2 修复 SQL 触发器函数分隔符
问题: 使用单个 $ 作为函数分隔符,语法错误
修复:
RETURNS TRIGGER AS $→RETURNS TRIGGER AS $$END; $ LANGUAGE plpgsql;→END; $$ LANGUAGE plpgsql;
影响函数:
update_folder_path()inherit_folder_category()
2.3 修复唯一约束处理 NULL 值
问题: 普通唯一约束无法正确处理 NULL 值
修复:
- 使用部分唯一索引(Partial Unique Index)
- 根文件夹和非根文件夹分别创建索引
- 添加
WHERE条件过滤 NULL 值
修复前:
CONSTRAINT folders_name_unique UNIQUE (parent_folder_id, owner_id, name)
修复后:
-- 非根文件夹
CREATE UNIQUE INDEX idx_folders_name_unique_with_parent
ON folders (parent_folder_id, owner_id, name)
WHERE parent_folder_id IS NOT NULL AND deleted_at IS NULL;
-- 根文件夹
CREATE UNIQUE INDEX idx_folders_name_unique_root
ON folders (owner_id, name)
WHERE parent_folder_id IS NULL AND deleted_at IS NULL;
2.4 明确职责划分(数据库 vs 应用层)
问题: 数据库层和应用层职责不清晰
修复:
数据库层(触发器):
- ✅ 自动更新时间戳(
update_updated_at_column()) - ✅ 自动计算路径和层级(
update_folder_path()) - ✅ 自动继承分类(
inherit_folder_category())
应用层(Service):
- ✅ 权限检查(
check_user_permission()) - ✅ 循环引用检测(
would_create_cycle()) - ✅ 名称唯一性检查(
exists_by_name()) - ✅ 引用完整性校验(
_validate_*_exists())
移除的 SQL 函数:
- ❌
check_folder_permission()- 改为应用层实现 - ❌
check_folder_cycle()- 改为应用层实现 - ❌
get_accessible_folders()- 改为应用层实现
2.5 双重保护机制
策略: 应用层主动检查 + 数据库索引兜底
实现:
- 应用层:在
create_folder()和update_folder()中主动调用exists_by_name()检查 - 数据库层:使用部分唯一索引作为最后防线
- 优势:
- 应用层检查提供友好错误提示
- 数据库索引确保数据完整性
- 防止并发场景下的数据冲突
符合度评分
| 阶段 | 版本 | 评分 | 说明 |
|---|---|---|---|
| 初始状态 | v3.2 | 60/100 | 存在多个严重问题 |
| 基础修复 | v3.3 | 95/100 | 修复外键、时间戳、枚举等问题 |
| 深度排查 | v3.3 | 45/100 | 发现 UUID、SQL 语法等新问题 |
| 完整修复 | v3.4 | 95/100 | 所有问题已修复 |
当前扣分项(5分)
- 文档完整性(-3分):部分高级功能(克隆、导出、分享)的实现细节需要补充
- 测试用例(-2分):缺少单元测试和集成测试示例
验证结果
✅ 已验证项
- UUID 生成: 所有表均无
DEFAULT gen_uuid_v7() - SQL 语法: 触发器函数使用正确的
$$分隔符 - 唯一约束: 使用部分唯一索引处理 NULL 值
- 时间戳: 所有时间字段使用
CURRENT_TIMESTAMP - 枚举类型: 使用 SMALLINT 存储,代码层使用 IntEnum
- 外键约束: 无物理外键,仅逻辑关联
- SQL 注释: 所有表和字段均有完整注释
- 职责划分: 数据完整性用触发器,业务逻辑在应用层
📊 统计数据
- 修复表数量: 4 个(folders, folder_members, folder_shares, folder_export_jobs)
- 移除 UUID 默认值: 4 处
- 修复触发器函数: 2 个
- 添加部分唯一索引: 2 个
- 移除 SQL 函数: 3 个
- 添加应用层校验方法: 3 个
- 添加 SQL 注释: 50+ 条
相关文件
- 主文档:
docs/requirements/backend/04-services/project/folder-service.md - 技术栈规范:
.claude/skills/jointo-tech-stack/references/database.md - 服务文档规范:
docs/requirements/backend/04-services/README.md - 数据库规范:
docs/architecture/datetime-timezone-standards.md
后续建议
- 补充测试用例:为 FolderService 和 FolderRepository 编写完整的测试
- 性能优化:考虑为高频查询添加缓存(Redis)
- 监控告警:添加关键操作的监控指标
- API 文档:使用 OpenAPI 规范生成完整的 API 文档
- 实现高级功能:完善克隆、导出、分享功能的实现细节