# 04 · RAG 对查报告（是否有出错）

> 方法：以 `/mnt/data/rag/polyv/`（762 篇官方文档）为权威源，逐项核对对话包内的 **代码（app.py）**、**对接指南（polyv-integration-guide.md）**、**需求清单** 中的保利威技术点。
> 严重度：P0=上线即失效/安全合规崩；P1=功能不完整/运维风险；P2=不一致/文档矛盾。

---

## 一、核对结论总表

| # | 技术点 | 项目中的表述 | RAG 权威结论 | 结果 | 严重度 |
|---|---|---|---|---|---|
| 1 | 创建频道接口 | 指南写 `create-init`；代码用 `/channel/create` | 两者都真实存在：`/live/v4/channel/create`（创建）、`/live/v4/channel/create-init`（创建并初始化） | 无错误，属取舍 | P2 |
| 2 | 创建响应含推流/观看地址 | `app.py` 读 `data.pushUrl/pullUrl/watchUrl` 回填 | 两篇创建文档 data 字段**均不含** pushUrl/watchUrl，须 `basic/get` 回填 | **代码错误** | P1 |
| 3 | 自定义授权校验签名 | `MD5(secret+id+secret+ts)` | `customauth_2.md` 一致 | 正确 | — |
| 4 | 自定义授权回签 | `MD5(secret+id+secret+ts+secret+userid)` | `customauth_2.md` 一致 | 正确 | — |
| 5 | 自定义鉴权识别观众 | 取 `User...first()` 放行 | 须基于**真实观众**身份，返回唯一 userid | **代码错误** | P0 |
| 6 | 频道绑定 custom 回调 | 创建请求体未带观看条件 | 须 `masterAuthSetting.authType=custom` + `customUri` | **代码错误** | P0 |
| 7 | 回放(VOD)授权 | 仅直播自定义授权，忽略 `vid` | 自定义授权含 `vid` 字段，回放同端点处理 | **功能缺失** | P0 |
| 8 | PolyV 凭证 | `app.py` 与 `需求清单` 各一套不同明文 | 官方强调 appSecret 严禁明文/客户端 | **风险** | P1 |
| 9 | view_limit_type 枚举 | app.py `none/code/phone/external/direct` vs 需求 `none/whitelist/password/level` | 文档无强制，但两处自相矛盾 | 不一致 | P2 |
| 10 | CORS 白名单 | `live.awulv.cn/qh.netf.top` | 实际前端 `claw.awulv.cn/netf.top` | 不匹配 | P1 |
| 11 | Mock/Real 状态 | 代码 `POLYV_MOCK=False`；总结仍写"Mock模式" | 状态说明矛盾 | 不一致 | P2 |

---

## 二、关键错误的 RAG 证据

### P0-① 自定义鉴权不识别真实观众（最致命）

`app.py` `/api/auth/custom-auth`：
```python
user = User.query.filter_by(status="active").first()   # 永远取第一个用户
```
RAG `live_api_web_watch_condition_customauth_2.md` 明确：
> 直播系统会将 id/ts/sign/url 等提交给用户自定义 API，用户需要对字符串 `secretkey + id + secretkey + ts` 进行 MD5 校验……通过校验和**自定义验证逻辑**后，将 **userid（学员唯一标识）** 等提交到回调 url。

即鉴权必须对应**具体观众**。当前实现让**任何观众都以"用户#1"身份通过**，等于适当性/VIP 闸门形同虚设。且页面 `/watch` 虽有前端 `/api/auth/check` 预校验，但保利威真正调用的回调并不读取观众身份。

### P0-② 创建频道未接 custom 回调

RAG `create-init` 文档的请求体含 `masterAuthSetting`：
```json
"masterAuthSetting": { "enabled":"Y", "authType":"custom", "customKey":"...", "customUri":"https://你的域名/api/auth/custom-auth" }
```
`app.py` 的 `polyv_create_channel` 只发 `name/newScene/template/channelPasswd/description`，**未设观看条件为 custom**。结果：即使在控台配了自定义授权密钥，PolyV 侧频道不会触发回调，闸门从根上没接上。

### P1 创建响应不含推流/观看地址

RAG `create` 与 `create-init` 两篇文档的 `data` 返回字段均为：`channelId / userId / channelPasswd / (seminarHostPassword) / (seminarAttendeePassword) / publisher / description / newScene / template ...` —— **没有 pushUrl / pullUrl / watchUrl**。正确做法（指南也提到）：创建后调 `GET /live/v4/channel/basic/get` 回填。
`app.py` 真实模式下 `data.get("pushUrl")` 恒为 `None`，生产部署后直播间推流/观看地址全空。

### P1 双套明文凭证

- `app.py` `POLYV_CONFIG`：appId `hlq0cj8b30`、appSecret、`customAuthSecret`（64位十六进制）
- `需求点清单.md` 末：用户ID `2fac0cc632`、密钥 `OyP6wMw8G4`

两套不一致，且均明文。RAG 反复强调 `appSecret` "严禁保存在客户端""所有 API 必须服务器中转"。须确认唯一有效套并外部化（见迁移方案 §4-①）。

---

## 三、必须修复清单（按严重度）

**P0（上线前必修）**
1. 自定义鉴权重做：从 PolyV 回调 `url` 中解析真实 viewer userid（观看页带 `?userid=` 跳转），移除 `first()`；正确回传并支持 `vid`。
2. 创建频道请求体加 `masterAuthSetting.authType=custom + customUri`，把回调接上。
3. 回放授权：复用自定义授权端点，识别 `vid` 走 VOD 校验。

**P1（迁移即修）**
4. 创建后补 `basic/get` 回填 pushUrl/watchUrl。
5. 密钥外部化（`.env`，600），删除两处明文，确认唯一有效套。
6. CORS origin 对齐实际前端域（`claw.awulv.cn` / `*.netf.top`）。

**P2（一致性收口）**
7. 统一 `view_limit_type` 枚举（建议 `none/whitelist/password/level`）。
8. 统一接口选择：保留 `/channel/create`（flat body）或升级 `create-init`（nested body），二选一并改对应请求体。
9. 修正 Mock/Real 状态说明，消除文档矛盾。

---

## 四、一句话总结

> **签名算法完全正确，鉴权"写对了公式、没接对链路"**：自定义授权的 MD5 公式与 RAG 一字不差，但工程既没把频道观看条件设为 custom（回调根本不被触发），回调里又不识别真实观众（闸门形同虚设），且创建后漏调 basic/get 导致地址为空。这些是"能跑 demo、不能上生产"的典型缺陷，已在 `03_迁移方案` 给出修复步骤。
