baodan/docs/用户上传产品小册子解析与留存实施计划.md

627 lines
25 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.

# 用户上传产品小册子解析与留存实施计划
> 文档版本v1.0
> 编制日期2026-07-30
> 适用范围:海报制作中的产品资料选择、产品小册子上传、解析、确认、留存和复用
> 建议优先级P0
> 预计工作量MVP 约 6 人日,建议预留 20% 风险缓冲
---
## 一、结论
本需求不应直接把普通用户上传的小册子写入现有公共 `PptProduct` 产品库。
推荐新增“我的产品资料库”:
1. 用户可以继续选择后台已审核产品;
2. 找不到产品时,可以上传产品小册子 PDF
3. 系统持久化保存原 PDF并异步解析产品名称、产品卖点、保障亮点、币种、投保规则和风险提示
4. 用户必须核对并确认解析结果,确认后才能生成文案和海报;
5. 已确认的小册子进入上传者的“我的产品资料”,以后可直接复用;
6. 用户资料默认私有,不对其他用户可见;
7. 只有显式提交并经管理员审核后,才允许转入公共产品库。
这一路径能复用现有 PDF 安全校验、小册子解析器、Celery、存储根目录和海报生成逻辑同时避免未经审核的数据污染公共产品库。
---
## 二、当前实现与问题定位
### 2.1 已有能力
| 能力 | 当前实现 | 可复用结论 |
|------|----------|------------|
| 公共产品和小册子 | `PptProduct.manual_file_url`、`manual_parsed_rules`、`manual_parse_status` | 可作为公共产品库继续使用 |
| 管理员上传小册子 | `PptAdminService.upload_manual()` | 可复用文件校验和存储思路 |
| 小册子解析 | `poster/manual_parser.py::parse_manual_pdf()` | 直接复用产品规则提取 Schema |
| 异步任务 | `parse_product_manual_task` + Celery | 新增用户资料解析任务,不另建队列 |
| 客户计划书上传 | `/poster/case-upload`、`PosterCaseUpload` | 继续保留,不能与产品小册子混用 |
| 海报文案和生成 | `PosterService.generate_copy()`、`generate_poster()` | 增加统一产品来源解析后复用 |
| PDF 安全校验 | `prepare_pdf_upload()` | 直接复用大小、魔数、页数、密码处理 |
| 持久化目录 | `get_storage_root()` | 用户小册子必须写入共享持久化卷 |
### 2.2 当前阻断点
1. `/poster/products` 只返回 `manual_parse_status=reviewed` 的公共产品。
2. 海报页面必须先选公共 `productId`,找不到产品时无法继续。
3. 当前 `/poster/case-upload` 上传的是客户计划书,并且强制绑定公共 `productId`
4. `generate_copy()``generate_poster()` 都直接查询 `PptProduct`,不认识用户上传资料。
5. 普通用户没有自己的产品资料实体、列表、详情、删除和复用能力。
6. 当前小册子解析只支持管理员维护的公共产品,没有用户所有权校验。
7. 前端 `localStorage` 只保存当前草稿,不等于服务端永久留存。
### 2.3 两类 PDF 必须分开
| 文件类型 | 主要内容 | 解析结果 | 生命周期 |
|----------|----------|----------|----------|
| 产品小册子 | 产品规则、卖点、币种、保障、风险提示 | `product_rules` | 可跨多个海报项目复用 |
| 客户计划书 | 年龄、性别、保额、保费、缴费年期、利益表 | `customer_data` | 与本次客户和海报项目绑定 |
前端文案也应统一使用“产品小册子”和“客户计划书”,避免两者都显示为“计划书”。
---
## 三、方案选择
### 3.1 方案对比
| 方案 | 优点 | 风险 | 结论 |
|------|------|------|------|
| 直接创建全局 `PptProduct` | 改动表面较少 | 私有数据可能被其他用户看到;未经审核资料混入公共库;现有所有查询都要补权限 | 不采用 |
| 给 `PptProduct` 增加 owner/visibility | 仍使用一个产品表 | 需要审计全项目中所有 `PptProduct` 查询,漏一处就可能越权 | 不建议作为首期 |
| 新建用户产品资料表 | 权限边界清晰;不影响公共产品;便于留存、复用和软删除 | 海报生成需要支持两种来源 | 推荐 |
| 仅保存为当前海报项目素材 | 与未来工作区模型一致 | 无法自然实现跨项目复用的“我的资料库” | 可作为项目快照,不作为主实体 |
### 3.2 推荐架构
```text
产品资料来源
├── 公共产品PptProduct管理员审核
└── 我的资料UserProductMaterial用户上传并确认
├── 原始 PDF持久化 storage
├── 解析结果parsed_rules
├── 用户确认结果confirmed_rules
└── 可选提交审核:进入公共产品库
统一 ProductSourceResolver
├── 校验来源存在、状态和所有权
├── 输出统一 ProductContext
└── 提供给文案生成、海报生成和项目恢复
```
统一的 `ProductContext` 至少包含:
```json
{
"sourceType": "library_product",
"sourceId": "aia_example",
"productName": "产品名称",
"companyId": "aia",
"companyName": "保司名称",
"planType": "savings",
"rules": {},
"confirmedAt": "2026-07-30T10:00:00"
}
```
`sourceType` 首期只支持:
- `library_product`:后台公共产品;
- `user_material`:当前用户上传的产品小册子。
---
## 四、数据模型与存储
### 4.1 新表 `insurance_user_product_materials`
建议新增 `api/insurance/models/user_product_material.py`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | BIGINT | 主键 |
| `owner_user_id` | VARCHAR(64) | 上传者,必须建立索引 |
| `tenant_id` | VARCHAR(64) | 租户隔离;无法可靠取得时首期使用 `default` |
| `company_id` | VARCHAR(50) | 可为空,确认时允许选择 |
| `company_name` | VARCHAR(100) | PDF 解析或用户确认的保司名称 |
| `product_name` | VARCHAR(150) | 解析或用户确认的产品名称 |
| `plan_type` | VARCHAR(20) | savings/ci/iul/other |
| `original_name` | VARCHAR(200) | 原文件名 |
| `file_key` | VARCHAR(500) | 相对 storage 根目录的对象键 |
| `file_size` | BIGINT | 文件字节数 |
| `page_count` | INTEGER | PDF 页数 |
| `sha256` | VARCHAR(64) | 用户内去重和审计 |
| `parse_status` | VARCHAR(20) | pending/queued/parsing/parsed/failed |
| `parse_message` | VARCHAR(500) | 进度提示 |
| `parse_error` | TEXT | 解析错误,返回前需要脱敏 |
| `parse_task_id` | VARCHAR(200) | Celery 任务 ID |
| `parsed_rules` | TEXT | 系统原始解析 JSON |
| `confirmed_rules` | TEXT | 用户核对后的最终 JSON |
| `confirmed_by` | VARCHAR(64) | 确认人 |
| `confirmed_at` | TIMESTAMP | 确认时间 |
| `review_status` | VARCHAR(20) | private/submitted/approved/rejected |
| `status` | SMALLINT | 1=可用0=停用 |
| `created_at` / `updated_at` | TIMESTAMP | 时间字段 |
| `deleted_at` | TIMESTAMP | 软删除 |
索引和约束:
- `INDEX(owner_user_id, deleted_at, updated_at)`
- `INDEX(owner_user_id, sha256)`
- `INDEX(parse_status)`
- 不做跨用户重复文件提示,避免侧信道泄露;
- `confirmed_rules` 为空的资料不得用于生成。
### 4.2 现有表兼容扩展
`poster_case_uploads``poster_records` 增加:
| 字段 | 用途 |
|------|------|
| `product_source_type` | `library_product` / `user_material` |
| `product_source_id` | 统一使用字符串保存来源 ID |
| `product_snapshot_json` | 提交生成时固化产品名称、保司、规则和确认时间 |
兼容规则:
- 旧记录没有 `product_source_type` 时,按 `library_product + product_id` 读取;
- 新代码继续接受旧请求中的 `productId`
- 新页面优先发送 `productSource`
- 已生成项目始终使用 `product_snapshot_json`,后台资料后续变化不能静默改变历史海报。
### 4.3 文件存储
推荐对象键:
```text
uploads/product-manuals/users/{safe_user_id}/{material_id}/{uuid}.pdf
```
要求:
- 只在数据库保存相对 `file_key`,读取时由统一存储服务拼接;
- API 和 Worker 必须挂载同一个 `INSURANCE_STORAGE_ROOT` 持久化卷;
- 下载接口必须鉴权并校验文件位于产品小册子目录内;
- PDF 密码仅用于本次解密,不写数据库、不写日志;
- 替换文件时生成新对象,不覆盖旧文件;新解析成功后再切换引用;
- 删除采用软删除;被历史海报快照引用的文件不得立即物理删除。
建议默认保留策略:
- 活跃资料:保留至用户主动删除;
- 用户删除:进入 30 天回收期;
- 已被海报使用:至少保留到相关海报项目过期;
- 最终期限需要由业务、法务和存储成本负责人确认。
---
## 五、后端接口
### 5.1 用户产品资料接口
| 方法 | URL | 用途 |
|------|-----|------|
| GET | `/insurance/poster/product-materials` | 查询“我的产品资料” |
| POST | `/insurance/poster/product-materials` | 上传 PDF创建记录并自动投递解析 |
| GET | `/insurance/poster/product-materials/{id}` | 查询详情和解析状态 |
| PUT | `/insurance/poster/product-materials/{id}/confirm` | 保存修正结果并确认 |
| POST | `/insurance/poster/product-materials/{id}/retry` | 解析失败后重试 |
| GET | `/insurance/poster/product-materials/{id}/file` | 鉴权预览原 PDF |
| DELETE | `/insurance/poster/product-materials/{id}` | 软删除本人资料 |
| POST | `/insurance/poster/product-materials/{id}/submit-review` | 可选:提交进入公共库审核 |
上传使用 `multipart/form-data`
| 字段 | 必填 | 说明 |
|------|:----:|------|
| `file` | 是 | PDF |
| `password` | 否 | PDF 打开密码,不保存 |
| `companyId` | 否 | 用户已知时可传 |
| `planType` | 否 | 用户已知时可传 |
### 5.2 产品来源接口
保留现有 `GET /poster/products`,新增:
```text
GET /insurance/poster/product-sources
```
返回:
```json
{
"code": 0,
"message": "success",
"data": {
"libraryProducts": [],
"myMaterials": []
}
}
```
“我的资料”只返回:
- 当前用户所有;
- 未删除且启用;
- `parse_status=parsed` 或已确认;
- 生成时仍必须再次检查 `confirmed_rules`
### 5.3 生成接口兼容
新请求:
```json
{
"productSource": {
"type": "user_material",
"id": "123"
},
"caseUploadId": 456,
"templateId": 1
}
```
兼容逻辑:
1.`productSource` 时使用新逻辑;
2. 只有 `productId` 时映射为 `library_product`
3. `ProductSourceResolver` 完成所有权、状态、确认状态和公司状态检查;
4. `generate_copy()`、`generate_poster()` 不再直接各自拼装产品规则;
5. 创建 `PosterRecord` 时保存产品快照。
建议错误码:
| 错误码 | 含义 |
|--------|------|
| 4101 | 小册子文件不合法 |
| 4102 | 小册子需要密码或密码错误 |
| 4103 | 小册子解析中 |
| 4104 | 小册子解析失败 |
| 4105 | 小册子尚未确认 |
| 4106 | 产品资料不存在或无权访问 |
| 4107 | 产品资料已删除或停用 |
---
## 六、解析与确认流程
```text
上传 PDF
→ prepare_pdf_upload 安全校验和解密
→ 计算 sha256
→ 持久化原文件
→ 创建 material状态 queued
→ Celery 解析
→ parse_manual_pdf
→ 保存 parsed_rules状态 parsed
→ 用户查看原 PDF + 修改结构化字段
→ 服务端 Schema 校验
→ 保存 confirmed_rules、确认人和确认时间
→ 可用于海报并进入“我的资料”
```
### 6.1 解析复用
直接复用:
- `insurance.utils.security.prepare_pdf_upload`
- `insurance.poster.manual_parser.parse_manual_pdf`
- `insurance.generation.celery_tasks` 的 Celery 基础设施;
- `insurance.config.get_storage_root`
- BaoDan 数据库、Redis、日志和认证。
新增 `parse_user_product_material_task(material_id)`,状态流转:
```text
pending → queued → parsing → parsed → confirmed
└→ failed
```
数据库字段仍使用 `parsed + confirmed_at` 表示最终确认,不必为了展示再增加 `confirmed` 状态值。
### 6.2 确认 Schema
首期至少要求:
- `product_name` 非空;
- `features` 为 18 项;
- 每项卖点包括 `title`、`summary`,尽量保留 `source_page`
- `currency_options` 为字符串数组;
- `coverage_highlights` 为字符串数组;
- `risk_warnings` 为字符串数组;
- `investment_rules` 为对象;
- 所有字符串限制长度,禁止把整份 PDF 原文写入结构化字段。
用户替换原 PDF 或重新解析后,必须清空旧 `confirmed_rules``confirmed_at`,强制重新确认。
### 6.3 Prompt 安全
- PDF 内容一律视为待抽取数据,不视为系统指令;
- 系统 Prompt 明确忽略 PDF 内的指令、链接和要求;
- 结构化输出必须做服务端 Schema 校验;
- 不把 PDF 全文、密码、客户敏感数据或模型密钥写入日志;
- 对超长 PDF 使用页级筛选和最大上下文限制;
- 解析失败应返回结构化错误,不向前端暴露内部堆栈。
---
## 七、前端交互
### 7.1 产品资料面板
将当前“选择产品”抽屉改为两个标签:
1. `系统产品`:现有后台已审核产品;
2. `我的资料`:当前用户已上传并确认的小册子。
固定提供:
- “上传产品小册子”按钮;
- 搜索无结果时显示“没有找到?上传小册子”;
- 我的资料卡片展示产品名、保司、解析状态、更新时间;
- 支持查看原 PDF、编辑确认结果、替换、删除。
### 7.2 上传对话框
步骤:
1. 选择 PDF可选输入密码
2. 上传并显示真实解析状态;
3. 左侧预览 PDF右侧核对解析字段
4. 点击“确认并使用”;
5. 自动加入“我的资料”并选中。
解析可能超过页面停留时间,用户关闭弹窗后任务仍应继续;再次进入“我的资料”可恢复状态。
### 7.3 草稿状态调整
`PosterDraft` 增加:
```ts
productSourceType: 'library_product' | 'user_material' | ''
productSourceId: string
productSourceConfirmedAt: string
```
兼容保留 `productId`,但新流程不再仅以 `productId` 判断是否完成产品选择。
当用户更换产品来源时:
- 清空已生成文案;
- 将合规确认置为未确认;
- 如果客户计划书与旧产品绑定,提示并要求重新确认;
- 不直接删除已上传客户计划书。
### 7.4 文案调整
当前“计划书与数据”建议改为“客户计划书与数据”,上传提示明确写“客户计划书 PDF”。
产品资料区域明确写“产品小册子”,避免用户把同一个文件传错入口。
---
## 八、代码改动清单
### 8.1 后端
| 文件 | 改动 |
|------|------|
| `api/insurance/db/migrate_026.py`(以开发分支启动时的下一个可用编号为准) | 新表、兼容字段、索引和幂等迁移 |
| `api/insurance/models/user_product_material.py` | 用户产品资料模型 |
| `api/insurance/models/__init__.py` | 注册模型 |
| `api/insurance/poster/product_material_service.py` | 上传、查询、确认、删除和所有权校验 |
| `api/insurance/poster/product_source_resolver.py` | 统一公共产品与用户资料 |
| `api/insurance/poster/routes.py` | 新增产品资料和产品来源接口 |
| `api/insurance/poster/service.py` | 文案/海报生成改用统一 resolver |
| `api/insurance/generation/celery_tasks.py` | 新增用户小册子解析任务 |
| `api/insurance/models/poster_case_upload.py` | 保存产品来源引用 |
| `api/insurance/models/poster_record.py` | 保存产品来源和产品快照 |
| `api/insurance/utils/security.py` | 仅在现有能力不足时补充限制,不重写上传校验 |
当前仓库的下一个迁移编号是 026但《海报生成工作台完整重构修复计划》也预留了该编号。若两项工作进入同一发布版本应合并为一个迁移若分支独立交付后合并的分支必须顺延编号。海报工作台 V2 的 `poster_project_assets` 已落地时,在生成项目时把用户资料注册为:
```text
asset_type=product_manual
source_type=library
source_ref_id={user_material_id}
```
### 8.2 前端
| 文件 | 改动 |
|------|------|
| `frontend/src/utils/poster-api.ts` | 产品资料上传、查询、确认、删除、重试接口 |
| `frontend/src/composables/usePosterWorkspace.ts` | 增加产品来源状态和兼容恢复 |
| `frontend/src/components/poster/workspace/PosterProductPanel.vue` | 系统产品/我的资料双标签 |
| `frontend/src/components/poster/workspace/UserProductMaterialDialog.vue` | 新增上传、轮询、核对弹窗 |
| `frontend/src/components/poster/workspace/PosterSourcePanel.vue` | 文案改为客户计划书,解除“必须先选公共 productId”假设 |
| `frontend/src/pages/PosterPage.vue` | 生成请求发送 `productSource` |
### 8.3 测试
建议新增:
```text
tests/poster_product_material_model_test.py
tests/poster_product_material_api_test.py
tests/poster_product_material_parse_test.py
tests/poster_product_source_resolver_test.py
tests/poster_product_material_permission_test.py
tests/poster_product_material_storage_test.py
tests/poster_user_manual_e2e_test.py
```
---
## 九、可执行排期
### Phase 0需求冻结和样例准备0.5 人日)
- [x] MANUAL-0001 确认“用户资料默认私有”;
- [x] MANUAL-0002 确认是否允许用户确认后立即生成;
- [ ] MANUAL-0003 准备 3 份脱敏样例:文本 PDF、扫描 PDF、加密 PDF
- [x] MANUAL-0004 固化解析字段 Schema 和验收期望;
- [ ] MANUAL-0005 确认保留期、单文件大小和页数上限。
完成标准:三份样例和预期 JSON 入库到测试夹具,关键产品决策有书面结论。
### Phase 1数据、存储和基础 API1.5 人日)
- [x] MANUAL-0101 编写幂等迁移;
- [x] MANUAL-0102 新增模型和 `to_dict()`
- [x] MANUAL-0103 实现用户内 SHA-256 去重;
- [x] MANUAL-0104 实现上传、列表、详情、预览和软删除;
- [x] MANUAL-0105 实现文件路径和所有权校验;
- [x] MANUAL-0106 增加迁移、存储和权限单元测试。
完成标准:重启 API/Worker 后文件仍存在,用户 A 无法查看、下载或删除用户 B 的资料。
### Phase 2异步解析和人工确认1.5 人日)
- [x] MANUAL-0201 新增用户资料 Celery 任务;
- [x] MANUAL-0202 复用 `parse_manual_pdf()`
- [x] MANUAL-0203 增加 Prompt 注入防护和输出 Schema 校验;
- [x] MANUAL-0204 实现轮询、失败原因和重试;
- [x] MANUAL-0205 实现确认接口和确认失效规则;
- [ ] MANUAL-0206 覆盖加密、损坏、空文本、超限和扫描件场景。
完成标准:上传后异步完成解析;失败可重试;未确认资料不能进入生成。
### Phase 3海报链路接入1.0 人日)
- [x] MANUAL-0301 实现 `ProductSourceResolver`
- [x] MANUAL-0302 改造 `generate_copy()`
- [x] MANUAL-0303 改造 `generate_poster()`
- [x] MANUAL-0304 为计划书和海报记录保存产品来源与快照;
- [x] MANUAL-0305 验证旧 `productId` 请求保持兼容;
- [x] MANUAL-0306 增加跨用户引用和历史快照测试。
完成标准:公共产品和本人资料均可生成;用户资料更新不改变已生成海报的产品快照。
### Phase 4前端交互1.0 人日)
- [x] MANUAL-0401 产品选择抽屉增加双标签;
- [x] MANUAL-0402 新增上传、解析进度、预览和核对弹窗;
- [x] MANUAL-0403 支持从“我的资料”复用、替换和删除;
- [x] MANUAL-0404 修正产品小册子/客户计划书文案;
- [x] MANUAL-0405 产品来源变化时清理失效草稿状态;
- [ ] MANUAL-0406 PC 和移动端基本回归。
完成标准:用户无需管理员帮助即可完成“上传小册子 → 解析 → 确认 → 生成海报 → 下次复用”。
### Phase 5测试、灰度和上线0.5 人日)
- [x] MANUAL-0501 执行后端权限、存储和兼容回归;
- [ ] MANUAL-0502 执行前端端到端流程;
- [x] MANUAL-0503 增加 `POSTER_USER_MANUAL_UPLOAD_ENABLED` 功能开关;
- [ ] MANUAL-0504 管理员和 5% 用户灰度;
- [ ] MANUAL-0505 观察解析成功率、耗时、重试率和存储增长;
- [x] MANUAL-0506 更新 API、测试、部署和任务清单文档。
完成标准P0/P1 用例通过;关闭功能开关可立即回到旧产品选择流程;旧海报可继续查看和下载。
### 可选 Phase 6提交公共库审核1.52 人日)
- [ ] MANUAL-0601 用户提交审核;
- [ ] MANUAL-0602 管理端待审列表和 PDF/解析结果对照;
- [ ] MANUAL-0603 管理员修改、批准和驳回;
- [ ] MANUAL-0604 批准后创建或合并 `PptProduct`
- [ ] MANUAL-0605 记录来源资料、审核人和审核时间;
- [ ] MANUAL-0606 同产品重复提交检测。
首期不应把该阶段作为“用户能生成海报”的阻断项,除非合规制度明确要求所有产品必须管理员预审。
---
## 十、测试与验收
### 10.1 P0 验收
- [ ] 不选择公共产品也能上传产品小册子;
- [ ] 原 PDF 保存在持久化 storage服务重启后仍可预览
- [ ] 加密 PDF 密码只用于本次请求;
- [ ] 解析任务页面关闭后继续执行;
- [ ] 用户可以修改并确认解析结果;
- [ ] 未确认资料不能生成文案或海报;
- [ ] 确认后的资料出现在“我的资料”并可跨项目复用;
- [ ] 用户 A 无法枚举、预览、引用、修改或删除用户 B 的资料;
- [ ] 公共产品原流程保持可用;
- [ ]`productId` API 调用保持兼容;
- [ ] 历史海报使用产品快照,不受资料后续修改影响。
### 10.2 P1 验收
- [ ] 同一用户重复上传相同 PDF 不重复调用模型;
- [ ] 替换 PDF 后旧确认自动失效;
- [ ] 解析失败可查看可理解原因并重试;
- [ ] 危险 PDF、伪造扩展名、超大小和超页数被拒绝
- [ ] PDF 中的 Prompt 注入文本不会改变解析任务;
- [ ] 日志中没有 PDF 密码、完整正文和模型密钥;
- [ ] 删除资料不会破坏历史海报;
- [ ] 解析成功率、P95 耗时和存储增长可监控。
### 10.3 建议性能指标
| 指标 | 建议目标 |
|------|----------|
| 上传接口 P95 | 小于 3 秒,不含客户端网络上传时间 |
| 解析任务成功率 | 大于 95%,扫描件单独统计 |
| 文本 PDF 解析 P95 | 小于 120 秒 |
| 重复上传模型调用 | 0 次 |
| 跨用户访问成功数 | 0 |
| 服务重启后文件丢失 | 0 |
---
## 十一、风险与处理
| 风险 | 影响 | 应对 |
|------|------|------|
| 用户资料被误当公共产品 | 数据泄露、合规风险 | 独立表、默认私有、所有权校验 |
| PDF 解析结果不准确 | 错误产品卖点进入文案 | 人工确认、来源页、未确认阻断 |
| 扫描 PDF 无文本 | 解析失败率高 | 首期明确提示P1 接入 OCR |
| 重复上传导致模型成本增加 | 成本浪费 | 用户内 SHA-256 去重 |
| 文件只存容器临时盘 | 重启后丢失 | 强制共享持久化卷和 readiness 检查 |
| 资料修改影响历史海报 | 审计不可追溯 | 生成时保存产品快照 |
| 用户删除资料导致历史断链 | 旧项目无法恢复 | 软删除、引用保护、延迟物理清理 |
| 在现有 `PptProduct` 上补权限遗漏 | 跨用户暴露 | 不复用全局产品表保存私有资料 |
| 与海报工作台 V2 迁移冲突 | 重复表和迁移编号 | 用户资料作为长期资料库,项目素材只保存引用和快照 |
---
## 十二、上线决策项
开发开始前必须确认:
| 编号 | 决策 | 推荐默认值 |
|------|------|------------|
| D-01 | 用户资料是否默认私有 | 是 |
| D-02 | 用户确认后能否立即生成 | 能,仅限本人使用 |
| D-03 | 是否自动进入公共产品库 | 否,必须显式提交并管理员审核 |
| D-04 | 扫描 PDF 是否首期支持 OCR | 否,先提示用户上传可检索 PDF |
| D-05 | 文件默认保留期 | 活跃资料保留至用户删除,删除后 30 天回收 |
| D-06 | 单文件大小和页数 | 沿用 `prepare_pdf_upload()` 当前配置 |
| D-07 | 是否允许无保司资料 | 允许上传,确认前必须补齐或选择“其他” |
| D-08 | 删除后历史海报是否保留文件 | 是,保留至项目生命周期结束 |
---
## 十三、完成定义
只有以下条件全部满足,本需求才可标记完成:
- 用户能在海报产品选择区上传系统中不存在的小册子;
- 小册子原文件、解析结果、确认结果和确认信息均保存在服务端;
- 上传资料默认只对本人可见;
- 用户确认后可以立即用于文案和海报生成;
- 下次新建海报时可以从“我的资料”直接选择;
- 公共产品和旧接口不受影响;
- 生成记录保存产品快照;
- 文件、权限、解析、兼容和端到端自动化测试通过;
- 生产环境 API 与 Worker 使用同一持久化存储;
- 功能支持灰度开关和无损回退。