# 产品档案与清理运行手册 ## 1. 服务启动 产品档案要求三类持久卷全部存在: ```bash docker compose up -d --build docker compose ps docker compose logs --tail=80 backend ``` `docker-compose.yml` 中必须挂载: - `wordcloud_products:/app/service_products` - `wordcloud_metadata:/app/service_metadata` - `wordcloud_orders:/app/service_orders` 首次上线或更新后,先检查健康接口: ```bash docker compose exec backend curl -fsS http://localhost:8000/api/health ``` ## 2. 外部产品同步 首期外部系统可以先使用创建/更新产品接口做幂等同步: ```http POST /api/products Authorization: Bearer <生产订单管理口令> Content-Type: application/json { "source": "external", "external_product_id": "PROD-123", "name": "产品名称", "sku": "SKU-123", "specification": "规格" } ``` 同步以 `(source, external_product_id)` 合并,不按名称合并。后续产品接口字段稳定后,可以在现有模型上补适配层,不必改档案结构。 产品列表和详情默认展示产品名称、SKU、规格、状态与归档数量;完整 `product_id` 只在产品详情页的“系统信息”折叠区暴露。 ## 3. 清理 dry-run 物理清理默认关闭。上线后先只看候选,不删除数据: ```bash docker compose exec backend python -m service.storage_metrics --max-age-days 30 ``` 输出 JSON 中重点检查: - `archive_protected_job_ids`: 已归档进产品档案的源任务,不会被临时清理。 - `asset_referenced_job_ids`: 普通画布素材引用,只反映当前引用,不是永久保护。 - `temporary_jobs`: 成功生成、30 天以上、未被产品档案保护的任务。 - `pending_product_ids`: 已进入 30 天待清理期的产品。 - `failed_cleanup` 产品不会出现在 `pending_product_ids`,需要人工检查后恢复或重新排队。 - `reclaimable_bytes`: 预计可回收空间。 服务启动和每 24 小时也会运行一次 `CleanupService.preview()`。没有设置清理开关时,它只计算候选,不删除。 ## 4. 启用物理清理 确认 dry-run 报告没有误删对象后,再在部署环境中显式开启: ```bash CLEANUP_APPLY_ENABLED=true docker compose up -d --build ``` 或在既有运维体系中通过 secret/env manager 提供同名变量。开启后仍必须传入 `--apply` 才会真正删除: ```bash docker compose exec backend python -m service.storage_metrics --max-age-days 30 --apply ``` 同一 API 也可以触发,但必须同时满足: 1. `CLEANUP_APPLY_ENABLED=true` 2. `POST /api/maintenance/cleanup-run` body 为 `{"confirm": true}` 3. 使用生产订单管理口令鉴权 清理规则: - 只清理成功生成、超过 30 天、带位置库、且当前仍不在 `product_wordcloud_archives` 中的任务。 - 每次执行前会重新检查归档引用;在预览和删除之间新归档的任务会被跳过。 - 归档保护来自产品词云档案表,不来自普通素材引用。 - 产品物理清理只在 `purge_after` 到期后发生;到期前可以恢复。 ## 5. 恢复待清理产品 产品进入待清理状态后,30 天内可恢复: ```http POST /api/products/{product_id}/restore Authorization: Bearer <生产订单管理口令> ``` 前端产品档案页会显示: ```text 待清理 · 将于 YYYY/MM/DD 删除 ``` 点击“恢复产品”后,产品回到 `active`,原清理记录标记为 `restored`。 删除按钮只是软删除,进入下一个 30 天可恢复窗口;真正的物理删除由清理服务执行。 ## 6. `failed_cleanup` 处置 物理删除失败时,服务不会假装文件仍完整,也不会自动重试。产品进入: ```text failed_cleanup ``` 处置步骤: 1. 打开产品档案详情,确认产品状态。 2. 检查服务器上的产品目录: ```bash docker compose exec backend sh -lc 'find /app/service_products/ -maxdepth 2 -type f -printf "%p %s\n"' ``` 3. 如果目录完整且可继续使用,调用恢复接口或点击“恢复产品”。 4. 如果目录不完整,先人工恢复或确认业务上放弃该产品,再恢复后重新软删除。 5. 不要直接修改 `product_archive.db`,也不要直接把失败状态改成 `pending_cleanup`。 已放弃且确认可安全删除的失败记录,应由管理员按上述恢复/重排队流程处理;系统不会自动把它当作完整产品重试。 ## 7. 回滚与部署注意 - 新版本上线前保留现有 `service_products`、`service_metadata`、`service_orders` 卷。 - 若当前环境曾把产品档案写入旧的未挂载目录,先停写并复制目录到挂载卷,再启动新版本。 - `CLEANUP_APPLY_ENABLED` 回到 `false` 后,调度器恢复为只 dry-run。 - 回滚不会自动恢复已物理删除的数据;因此首次启用物理清理必须先审查 dry-run。