Files
beige/plans/核销-第12环-归档.md
yangqianqian 6a2632da70 baseline: Clover 独立仓库首次基线提交
将 Clover 从上层产品包旧仓库中独立出来,建立专属版本控制。
当前状态=纵切片端到端已打通(登录→选品→出文出图→审核→下载包),
M1文案质量去套路化已验收。此提交作为后续按核销清单逐条修复的基线。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:30:22 +08:00

40 lines
4.2 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 核销表 · 第12环 归档
> 90分级验收孙总方法论·硬门禁。已吸收独立交叉验证修正。auto=机器判定human=目视。
## 模块目标
①history 按日期/品类筛选(现平铺) ②approved 下载交付包 zip 结构完整 ③多套打包(1-3套各独立笔记夹) ④客户输入物(产品/标杆)可导出(数据归属红线)。
## Ralph 修改步骤
| # | 改什么 | 落点 |
|---|--------|------|
| S1 | list_tasks 加 date_from/date_to/product_id query paramfromisoformat 转换invalid 返回 40001 | tasks.py:137-149 |
| S2 | _fmt_task 加 product_name(调用方传入)list_tasks 一次性 `Product.id.in_([...])` 建 id→name dict 避免N+1顶部补 `from app.models.product import Product`(当前无此import) | tasks.py:58-64 |
| S3 | history/page.tsx 加 dateFrom/dateTo state + 两个 `<input type=date>`(提 DateRangeFilter 子组件防超100行) | history/page.tsx:28-44 + JSX 50-94 |
| S4 | HistoryTable 表头/行加"产品"列(显 product_name ?? '-') | history/components.tsx:70-127 |
| S5 | TaskListItem 加 `product_name?:string` | dto.tasks.ts:8-16 |
| S6 | ⚠️多套打包:查所有 is_selected=True TextCandidate 按 angle_label 分组每组取第一notes 列表长度=选中套数(改 line 77-85 为 for loop)images_data 循环外查一次,每套传 `list(images_data)` 副本(退化:图共享复制进各套夹) | packaging_task.py:45-47,77-85 |
| S7 | 新建 GET /products/export + /benchmarks/export(format=json/csv)require_write_permissionbenchmarks/export 需 Product JOIN 填 product_name(复用 _fmt_benchmark 不够,只有 product_id) | products.py + benchmarks.py |
| S8 | 配置页产品 tab + 历史归档页各加"导出数据"按钮,通用 ExportButton(url,filename) 调 getBlob 下载 | history/components.tsx 或 config/ExportTab.tsx |
## 验收清单(做完一个勾一个)
- [ ] **A1**auto日期筛选传 date_from/date_to → items 全落区间;传 date_from=2099 → 空数组 total=0。⚠审计补:再验 `date_from=not-a-date` → code=40001(非500)。
- [ ] **A2**autoproduct_id 筛选:传 product_id=1 → 每条 product_id=1 且 product_name 非空。
- [ ] **A3**human前端产品列/history 表头有"产品"列,每行显产品名(非数字),与 GET /products/{id}.name 一致。
- [ ] **A4**human日期控件有开始/结束 date input填后表格刷新XHR URL 含 date_from/date_to结果≤全量。
- [ ] **A5**human下载交付包approved 任务点"下载交付包"≤60s 触发下载 delivery-{id}.zip(>1KB)`unzip -l` 含 note_01/文案.txt/发布清单/合规说明。
- [ ] **A6**autozip 结构完整:`unzip -l` grep 文案.txt/发布清单/合规说明/note_01//.jpg 全非空。⚠️审计补:若 .jpg 空先查 ImageCandidate.url 文件容器内可达(packaging_task.py:64-70 读失败静默跳过)。
- [ ] **A7**auto文案.txt 格式:`unzip -p note_01/文案.txt` 含"【标题】"、不以 `{` 开头(JSON 已解析)。
- [ ] **A8**human+auto多套打包审计改 human(需先 seed 3条 is_selected TextCandidate)→构造后 `unzip -l|grep 'note_0[1-3]/'|wc -l`≥3三套标题互不相同。
- [ ] **A9**auto产品 JSON 导出GET /products/export → 200,application/json,数组,每元素含 id/name/selling_points,且 selling_points 是数组(非JSON字符串)。
- [ ] **A10**auto标杆 CSV 导出GET /benchmarks/export?format=csv → 200,text/csv,首行表头含 product_id/highlights/created_at,行数≥已录标杆数。
- [ ] **A11**auto导出权限审计注——require_write_permission 当前只查 workspace_members 不分角色(workspace_guard.py:65-88);未登录调 → code=40101workspace 成员 → 200。
- [ ] **A12**human不显 token 余额(红线):⚠️审计改 human(curl 拿不到Next.js水合后DOM)——浏览器 Ctrl+F 搜"余额/用量/tokens/balance"无结果。
## 待北哥定义(不阻断代码)
- 多套打包图片套间对应ImageCandidate 无 set_index是否加列关联文案还是退化"图共享复制进每套夹"(本期默认退化)。
- 导出入口位置(产品管理 tab 按钮 / 历史归档页全局)。
- CSV 是否加 UTF-8 BOM(Windows Excel 不乱码)。