Files
cms-website/docs/evidence/media-map-export.md
T
浅念 a227cfac49 feat(source): 媒体映射侧车导出与登记
Plan 3 Task 0(评审 Issue 1):旧 cms 库 media_assets 的 source_url→file_path
映射只读导出为侧车 JSON(859 条,覆盖率对照 WXR 855 attachment_url:精确命中
836 / 归一命中 0 / 未命中 19,97.8%),register 新增 --media-map 输入通道
(kind=manual_url_list 快照,形状校验 INVALID_MEDIA_MAP,metadata 含条目数,
幂等复用)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-21 14:42:32 +08:00

88 lines
6.0 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.
# 媒体映射侧车导出证据(Plan 3 · Task 0,评审 Issue 1)
背景(评审实证):真实媒体目录 `D:/project/cms/storage/media/54f91c49-fffb-4c58-87c8-6c2cf6aaef79` 为扁平 GUID 命名(2625 文件,无 yyyy/mm 子目录),与 WXR attachment_url(`https://hesupipe.com/wp-content/uploads/<yyyy>/<mm>/<file>` 形态)**零精确命中**——唯一映射在旧 cms 库 `media_assets` 表(`source_url` → `file_path`)。本任务把该映射只读导出为侧车 JSON 并登记为 `manual_url_list` 快照,作为阶段 3 导入管道对拍三级中第二级的数据源。
## 导出
| 项 | 值 |
|---|---|
| 日期 | 2026-10-21 |
| 数据源 | 旧 cms PostgreSQL(容器 `infrastructure-postgres-1`,宿主 5433;凭证按 compose 只读环境 `cms`/`cms`) |
| 表/过滤 | `media_assets`,`site_id = '54f91c49-fffb-4c58-87c8-6c2cf6aaef79' AND source_url IS NOT NULL`(867 行中 8 行 source_url 为 NULL 不带出) |
| 导出行数 | **859**(与评审预期 859 一致;file_path 全部非空——另行只读核过 0 行空值) |
| 输出 | `storage/incoming/media-map-hesupipe.json`(143,945 B,SHA-256 `c935d444f52b6bb8d9fa5e511066cac5b0a684676986041882cfbc54a0da6a2e`;storage/ 已 gitignore) |
| 导出脚本 | `scripts/export-media-map.mjs`(幂等可重跑——重跑同 SELECT 覆写同路径,两次运行 SHA-256 一致已验证) |
实际执行的命令原文(仓库根 `D:\project\cms-one`):
```bash
pnpm exec node scripts/export-media-map.mjs --audit "D:/project/cms/storage/wxr/fd04d6ba8a1316b6.xml"
```
脚本内执行的唯一一条 cms 侧语句(经 `docker exec … psql --csv -t -c`,child_process execFile 参数数组传递、不经 shell):
```sql
SELECT source_url, file_path FROM media_assets
WHERE site_id = '54f91c49-fffb-4c58-87c8-6c2cf6aaef79' AND source_url IS NOT NULL
ORDER BY source_url
```
连接方式说明(任务给了二选一):选 `docker exec psql`——宿主无需装 pg 客户端、凭证由容器内环境承担;备选 node-postgres 直连 5433 需在脚本里钉死 compose 凭证,弃。
## 覆盖率预估(侧车 × WXR attachment_url 对照)
对照口径:WXR(`fd04d6ba8a1316b6.xml`,855 个 `<wp:attachment_url>`、去重后仍 855)逐条对侧车 `sourceUrl` 集合 join。归一化口径(估计用):去首尾空白 + 去尾斜杠 + 整串小写。
| 指标 | 值 |
|---|---|
| WXR attachment_url(去重) | 855 |
| 侧车条目 | 859 |
| **精确命中**(原文相等) | **836** |
| 仅归一后命中(大小写/尾斜杠救回) | **0**(本数据集无需归一化救援——未命中即真不在侧车) |
| **未命中** | **19** |
| 命中率(去重口径) | **97.8%**(836/855) |
| 侧车未被 WXR 引用的条目(悬空行) | 23(859 − 836;对拍三级用不上,仅记录) |
自洽核对:836 命中 + 19 未命中 = 855;859 侧车 − 836 被引用 = 23 悬空。
### 未命中清单(全部 19 条)
特征:**全部是 pdf/mp4/zip/txt/特殊字符文件名**,无常规 png/jpg——推测旧 cms 迁移时这批非图片资产未入 `media_assets`(或入在其他 site)。阶段 3 对拍时它们将落入第三级 missing 报告(按计划不插 media_assets 行,只进报告)。
```text
https://hesupipe.com/wp-content/uploads/2019/12/WPPOP-Introduction.pdf
https://hesupipe.com/wp-content/uploads/2019/12/WPPOP-Introduction.zip
https://hesupipe.com/wp-content/uploads/2019/12/WPPOP-Introduction.txt
https://hesupipe.com/wp-content/uploads/2019/12/wppop-ipad-pro-video.mp4
https://hesupipe.com/wp-content/uploads/2023/12/hesu-video.mp4
https://hesupipe.com/wp-content/uploads/2023/12/HESU-PIPE-ABOUNT.mp4
https://hesupipe.com/wp-content/uploads/2023/12/418311fef2a99d2b4bc018.mp4
https://hesupipe.com/wp-content/uploads/2023/12/hesuvideo.mp4
https://hesupipe.com/wp-content/uploads/2023/05/same-as-never_1_207_translate.pdf
https://hesupipe.com/wp-content/uploads/2023/12/Steel-Belt-Reinforced-PE-Corrugated-Pipe、-1.jpg
https://hesupipe.com/wp-content/uploads/2023/12/Steel-Belt-Reinforced-PE-Corrugated-Pipe、-1-1.jpg
https://hesupipe.com/wp-content/uploads/2023/12/Steel-Belt-Reinforced-PE-Corrugated-Pipe、-2.jpg
https://hesupipe.com/wp-content/uploads/2023/12/Steel-Belt-Reinforced-PE-Corrugated-Pipe、-3.jpg
https://hesupipe.com/wp-content/uploads/2023/12/Steel-Belt-Reinforced-PE-Corrugated-Pipe、-6.jpg
https://hesupipe.com/wp-content/uploads/2023/12/HDPE-Double-Wall-Corrugated-Pipe.pdf
https://hesupipe.com/wp-content/uploads/2023/12/HESU-PPR-PIPES-FITTINGS.pdf
https://hesupipe.com/wp-content/uploads/2023/12/HESU-PVC-PIPE-FITTINGS.pdf
https://hesupipe.com/wp-content/uploads/2023/12/HESU-HDPE-WATER-PIPES-FITTINGS.pdf
https://hesupipe.com/wp-content/uploads/2024/10/HDPE-carat-pipe-(2).jpg
```
## 登记冒烟(临时库,验后已 DROP)
`--media-map` 输入通道对真实侧车文件的 CLI 冒烟(临时库 `sf_smoke_mediamap_t0`,本项目 PG 5434,非 cms 库;验后 DROP 已执行):
```bash
DATABASE_URL_TEST="postgres://siteforge:siteforge_dev@localhost:5434/sf_smoke_mediamap_t0" \
pnpm sf source:register --site hesupipe-smoke --media-map storage/incoming/media-map-hesupipe.json
```
结果:`manual_url_list` 快照 1 行——sha256 `c935d444f52b…`(= 导出文件哈希)、byte_size 143945、metadata `entryCount=859`、adapter_version `manual-url-list@1`、storage_path 指向 content-addressed 副本;重跑复用(snapshot 复用/副本已存在,行数仍 1)。
## 只读声明
本任务对 `D:\project\cms`(旧 cms 仓库、其 PostgreSQL 容器、WXR 与媒体文件)**只执行了读取类操作**:`docker exec … psql` 上列 SELECT(及行数核对的 SELECT)与 WXR 文件读取(grep/哈希/正则抽取)。未对 cms 数据库执行任何写语句(INSERT/UPDATE/DELETE/DDL 均无)、未写 cms 文件系统、未挂载任何卷。本项目(cms-one)侧写入仅限自身 storage/ 与 artifacts/。连接凭证信息仅从 compose 文件读得,未修改任何配置。