Files
ai-contract-platform/project-docs/V2-contract-file-repository-mvp-2026-06-24.md
T
yuqei a3bb78e06b
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 16m35s
release: freeze V2 release candidate
2026-07-12 15:32:24 +08:00

67 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 合同平台 V2 - T4 合同仓库 MVP 闭环记录
日期:2026-06-24
## 目标
对照《AI 合同平台 V2 重构版开发方案》,本轮进入 T4:合同仓库 MVP。目标不是做复杂企业网盘,而是服务合同主流程,让用户能完成:
- 查看合同附件列表。
- 在线预览可读文本内容。
- 下载原始附件。
- 从附件直接进入关联合同详情。
- 附件上传、下载行为进入合同审计链。
## 本轮完成
### 后端
- 新增文件详情接口:`GET /api/v1/files/{file_id}`。
- 新增文件预览接口:`GET /api/v1/files/{file_id}/preview`。
- 新增文件下载接口:`GET /api/v1/files/{file_id}/download`。
- 新增响应模型:
- `FilePreview`
- `FileDownload`
- SQLite 仓储支持从配置的 `file_storage_dir` 读取附件内容。
- 读取文件时校验存储路径必须位于配置的附件目录内,避免误读仓库外文件。
- 下载关联合同附件时写入 `file_downloaded` 审计事件。
- 内存仓储同步支持上传内容暂存、预览和下载,保持本地模式行为一致。
### 前端
- 合同仓库 `/files` 的“预览”按钮接入真实预览接口。
- “下载”按钮接入真实下载接口,前端根据 base64 内容生成浏览器下载。
- 关联合同标题仍作为进入合同详情的主入口。
- 预览内容使用表格内轻量展开,不新增复杂文件系统页面。
### 契约和测试
- `yuqei-contract-platform/packages/contract-openapi/openapi.yaml` 已补齐文件详情、预览、下载接口。
- `ContractAuditEvent.event_type` 增加 `file_downloaded`。
- 新增测试覆盖:
- 文件详情读取。
- 文本预览。
- 下载内容一致。
- 附件下载审计回写到合同详情。
## 简化原则检查
本轮继续遵循“企业主线轻量化”原则:
- 文件仓库只围绕合同附件,不做独立复杂网盘。
- 文件列表里标题/合同名是主要入口,预览和下载是两个明确动作。
- 审计存在,但不压到普通操作前面。
- 后端保留可扩展点,后续可替换为对象存储或流式下载,但当前 API 对前端足够稳定。
## 验证结果
- `python -m pytest yuqei-contract-platform\services\contract-api\tests -q`:18 passed。
- `python -m compileall yuqei-contract-platform\services\contract-api\src\yuqei_contract_api`:通过。
- `python -c "import yaml; ... openapi.yaml ..."`:通过。
- `npm --prefix yuqei-contract-platform\apps\contract-web run build`:通过。
- `npm --prefix yuqei-contract-platform\apps\contract-web run typecheck`:通过。
## 后续建议
下一步可以继续 T5:统一搜索 MVP,把合同、文件、审查任务统一接到真实查询入口,并保持“结果标题作为主入口、少按钮、按更新时间排序”的简单体验。