Files
ozon-seller-kit/docs/v2.1/optimization-audit.md
T

168 lines
9.9 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.
# 前后端优化审查清单
> 审查日期:2026-08-29
> 状态:审查项持续跟踪;“图片原图与当前水印版管理”已于 2026-08-30 实施基础版本。
> 范围:商品试算页、图片生成/水印/导出链路,以及对应 FastAPI 服务端。
---
## 优先级说明
| 优先级 | 含义 |
|---|---|
| P0 | 若服务不再局限于本机,需优先处理的安全或资源风险 |
| P1 | 会影响数据可靠性、生成任务稳定性或存储成本 |
| P2 | 提升维护效率、性能与用户体验 |
---
## 1. 服务端:任务可靠性
### P1:生成任务应持久化并异步执行(第一阶段已实施)
- 已实施:新增 `background_jobs`、`background_job_items`,保存请求快照、状态、进度、逐图结果、错误、重试计数与第三方任务 ID;套图和单张编辑均已迁入。
- 已实施:`server/worker.py` 为独立 Worker;Pcore、RightAPI、通义万相在提交模型后先持久化外部任务 ID,再分次轮询,服务或 Worker 重启后继续原任务。
- 已实施:前端可恢复商品活动任务、取消任务、仅重试失败图。
- 边界:SQLite 适用于当前单机;跨机器/多实例前需迁移 PostgreSQL。同步供应商接口没有外部任务 ID,进程恰好中断时不能保证幂等。任务事件日志与历史清理策略留待后续。
### P1:单张 AI 编辑改为异步任务(已实施)
- 已实施:`POST /api/suite/image-edit` 创建并提交与套图共用的任务,立即返回 `suite_id`;单张编辑因此会走统一的模型、队列、水印、落库与追加素材链路。
- 已实施:弹窗提交后交由试算页统一任务区跟踪;请求不再受前端 120 秒 HTTP 超时影响,并支持取消、仅重试失败图与刷新恢复。
- 边界:任务事件日志、历史清理和供应商主动取消仍是后续项;同步供应商没有外部任务 ID 时无法保证中断后的幂等恢复。
### P2:前端轮询避免异步 `setInterval` 重叠(已实施)
- 已实施:套图和单张编辑均改为递归 `setTimeout`;只有前一次 `GET /api/suites/{id}` 完成后才安排下一次请求。
- 已实施:使用 `AbortController` 取消过期/卸载请求;网络失败采用最多 3 次、6s→12s 的指数退避;套图任务 ID 写入 `sessionStorage`,刷新页面后可恢复跟踪。
- 边界:状态已持久化,服务端重启不会导致 404;同步供应商恰在请求中断时需要重试,异步供应商则继续使用保存的外部任务 ID 轮询。
---
## 2. 服务端:图片、水印与存储生命周期
### P1:统一管理原图与当前水印版(已实施基础版本)
- 已实施:素材记录保存原图、当前展示图、对象 key 与水印配置;未加水印时原图即当前图,加水印时仅保留一张当前水印版,不保留水印历史。
- 已实施:采集、上传、AI 生成图片统一迁入 `products/{product_id}/assets/{asset_id}/`;重新加水印在提交后回收旧水印对象,移除水印回到原图。
- 已实施:删除单图清理素材目录,硬删除商品清理商品目录,并兼容清理旧路径引用。详见 [`image-asset-lifecycle.md`](./image-asset-lifecycle.md)。
- 后续:可增加定期扫描与清理孤儿对象的后台任务,用于处理存储服务瞬时失败后的残留。
### P1:批量水印改后台任务(第二阶段已实施)
- 已实施:`POST /api/assets/watermark` 只创建 `watermark_batch` 持久化任务并返回任务 ID;Worker 逐图从原图合成、上传、切换当前展示版本和回收旧水印对象。
- 已实施:页面独立轮询水印任务,刷新可恢复,支持取消、重试全部失败项和按单张重试;等待期间素材被修改时会拒绝旧任务覆盖,单项重试会重新冻结最新版本。
- 边界:移除水印目前仍是同步短操作;若未来单次处理规模继续提高,可迁入同一 Worker 框架。
### P2:统一图片格式、尺寸和元数据校验
- 现状:存储层主要依据 URL 后缀或 Content-Type 推断格式,未统一校验文件大小、像素、实际 MIME 类型和方向信息。
- 涉及:`server/services/storage.py`、`server/api/materials.py`。
- 建议:上传/下载后用图片库校验真实格式,限制像素与文件大小,按需要压缩、纠正 EXIF 方向并记录宽高。
---
## 3. 服务端:安全与资源保护
### P0:限制图片代理和导出 URL,防止 SSRF
- 现状:图片代理、单图下载、ZIP 导出会请求客户端传入的 HTTP(S) URL,并跟随重定向。
- 涉及:`server/api/proxy.py`、`server/api/export.py`、`server/services/storage.py`。
- 风险:若服务可被非本机访问,可能被用于读取内网地址、云元数据地址,或下载超大文件。
- 建议:解析并拒绝回环、内网、链路本地与保留 IP;每次重定向后再次校验;设置域名白名单/允许列表、最大响应体、连接与总耗时上限。
### P0:限制上传与 ZIP 导出的内存占用(已实施基础版本)
- 已实施:上传与远程下载按块读取,默认单张限制 20 MB;超限返回 HTTP 413 和可读错误。限制可通过 `.env` 覆盖。
- 已实施:每次采集最多 100 张;图片导出最多 50 张;ZIP 源图片总量和成品最大 200 MB。
- 已实施:ZIP 使用 `SpooledTemporaryFile`,超过 2 MB 自动转临时磁盘,响应以 64 KB 分块输出,不再使用无上限 `BytesIO`。
- 后续:若部署为多实例/容器,需要为临时目录增加独立容量配额与定期清理监控。
### P0:服务脱离本机后补鉴权与资源归属
- 现状:V2.1 按决策未启用鉴权,商品、素材、生成、导出、代理接口都可直接访问。
- 涉及:`server/main.py`、全部业务路由。
- 建议:上线局域网/公网前先接入认证、商品/素材归属校验、请求限流和审计日志。
- 备注:若服务始终只绑定本机回环地址,可作为后续事项,但不应暴露端口。
---
## 4. 前端:可维护性与交互
### P2:拆分 TrialSuitePanel
- 现状:`TrialSuitePanel.tsx` 已约 1,400 行,采集图和生成图卡片、悬浮操作、选择、下载等逻辑有重复。
- 建议:拆分为素材网格、结果网格、图片动作层、预览下载、水印设置、套图轮询等子组件/hooks。
- 收益:降低后续 UI 修改遗漏风险,便于复用和测试。
### P2:图片多时采用懒加载/虚拟化
- 现状:图片网格会一次性创建全部 Ant Design Image 与预览节点。
- 建议:大量历史生成图时采用分页、虚拟列表或按需加载;缩略图使用合适尺寸和 `loading="lazy"`。
### P2:补触屏与键盘操作
- 现状:删除、下载、AI 编辑等操作多为 hover 展示。
- 建议:增加焦点可见性、键盘标签与快捷操作;移动端使用常显按钮或“更多”菜单。
### P2:将水印设置按商品或用户保存
- 现状:水印设置写入浏览器全局 localStorage,同一浏览器的所有商品共享。
- 涉及:`trialWatermark`。
- 建议:明确产品语义:若按店铺/用户通用则服务端保存偏好;若按商品不同则保存到商品配置。
---
## 5. 数据、导出与接口契约
### P1:登记表与批量 CSV 服务端化
- 现状:登记记录保存在 `trialRegisterRecords` localStorage,不跨设备、清理浏览器数据后丢失,也无法多人/多窗口协作。
- 涉及:`studio/src/pages/trial/TrialExportPanel.tsx`。
- 建议:建立登记记录表,并实现服务端批量 CSV 导出;保留当前本地模式作为离线兜底(如有需要)。
### P2:减少前后端手工接口类型重复
- 现状:前端服务层与 FastAPI schema 分别维护,请求字段随功能增加后容易漂移。
- 涉及:`studio/src/services/*.ts`、`server/schemas/*.py`。
- 建议:从 OpenAPI 自动生成 TypeScript 客户端,或至少以契约测试校验关键请求/响应。
### P2:补充高频查询组合索引
- 现状:商品与素材已有单列索引;随着数据增长,按商品、分组、排序、状态组合查询会变多。
- 涉及:`server/models/product.py`、`server/models/asset.py`。
- 建议:在真实数据库和访问量出现后,用慢查询确认并增加如 `(product_id, group_key, sort_order)` 的组合索引;避免过早添加无效索引。
---
## 6. 测试、交付与可观测性
### P1:建立自动化测试基础
- 现状:未发现前后端单测、契约测试或端到端测试目录;`studio` 仅提供 dev/build/preview 脚本。
- 建议:
1. 后端:计价、水印、文件名、任务状态、URL 安全校验、导出。
2. 前端:价格计算、选择/导出、水印设置、图片操作组件。
3. E2E:采集素材 → 试算 → 单张/套图生成 → 水印 → 导出。
### P2:统一日志、指标和错误码
- 现状:生成失败主要保存在任务错误文本或日志中,缺少 provider、模型、耗时、重试、存储失败等聚合指标。
- 建议:结构化日志中加入 task_id、product_id、provider、model、耗时、错误类别;健康检查补充存储与关键第三方状态。
### P1:先提交当前已验证改动,再做重构
- 现状:工作区存在多个未提交的前后端改动。
- 建议:按“水印/图片交互”“提示词”“导出”等模块提交;后续优化在独立提交或分支完成,便于回滚与定位。
---
## 建议实施顺序
1. **P0 资源与 URL 防护**:SSRF、文件大小、ZIP 限制。
2. **P1 任务与文件可靠性**:异步持久化任务、图片版本和清理策略。
3. **P1 测试基础**:先覆盖水印、导出、任务、URL 安全。
4. **P1 登记表服务端化**:持久化登记记录和批量导出。
5. **P2 前端拆分与性能**:拆 TrialSuitePanel、图片虚拟化、触屏/键盘体验。
6. **P2 契约、索引、可观测性**:依据真实使用量逐步完善。