# C端 消费 × A端 录入 · 对接盘点 —— 波波 2026-09-25

义父问：「是不是应该详细看一下 C端 代码，分析 A端 有没有完全对接上」。

铁律是「**业务数据一律 A端 录入，C端 只读、绝不写死**」。
要验证这条铁律是不是真的成立，不能看 A端 有多少页面——
得**从 C端 出发**：它读了什么、数据存在哪、A端 有没有对应的写入能力。
本报告按这个方向逐项核到底。

---

## 一、核对方法

1. 扫 `miniprogram-v2` 全部 API 调用（`apiGet/apiPost/...`），拿到 C端 消费的端点全集
2. 对每个端点找后端实现，确认它**读哪张表**
3. 反查后端有没有对应的 **admin 写接口**（POST/PUT/DELETE）
4. 再确认 A端 页面是否真的调了这个接口（避免"有接口没页面"或"有页面接错表"）

区分两类数据，避免误报：
- **业务数据**（文案/商品/攻略/路线…）⇒ **必须** A端 可录入
- **行为/交易数据**（订单/消息/评价/分销/福钥）⇒ 用户产生，本就不需要录入

---

## 二、逐项对照结果

### ✅ 已对齐（铁律成立）

| C端 消费 | 数据源 | A端 录入 | 备注 |
|---|---|---|---|
| `content/items`（文案） | `content_items` | 文案字典 + 业务数据配置 | 3069 键目录可搜可改，改完 C端 冷启动生效 |
| `products`（商品 50 条） | `packages` | 商品管理 `/products` | **同一张表**（`admin_backend.py:730` 也读 packages），我灌的 50 条 A端 能直接编辑 |
| `combo-cards`（首屏推荐） | `packages` + `routes` 派生 | 同上 + 内容资源/routes | 无需单独录入 |
| `merchant-pages/{id}` | `merchant_pages` | 商户页模板 | C端 拉已发布 DSL 树渲染，A端 配什么长什么样 |
| `kora-trackers` | `orders` 聚合 | 不需要 | 是行为数据（进行中订单统计），非业务配置 |
| orders / reviews / messages / distribution / key-tasks | 各业务表 | 不需要 | 用户产生的数据 |

### ❌ 硬缺口：C端 展示，但 A端 录不进去

| C端 消费 | 数据源 | 现状 |
|---|---|---|
| `guides`（攻略 10 条） | `guides` 表 | 后端只有读接口（`feed_demand.py`、`guides.py`），**无任何 admin 写接口** |
| `content/guide-articles`（攻略社区 20 条） | `guide_articles` 表 | 同上，**无 admin 写接口** |

这两处直接违反铁律：运营想改一条攻略、下线一篇社区文章，**只能找开发改库**。
而且它们是游客能看到的内容，属于白标"换皮"必须要能改的范围。

### ⚠️ 天气：数据源早就通了，卡在 C端 组件口径（**此处我第一版判断错了，已更正**）

**第一版我写成"天气是空壳"，是错的。** 义父指出"天气数据源很早之前就提供了"，
复查后确认：数据源确实早就就位并且在正常工作。

真实实现在 `services/qweather.py`（和风天气）+ `routers/weather.py`。
prod 实测 `GET /api/miniapp/weather`：

```json
{"temp":"6°","desc":"阴 · 西北风3级","pass":"通行","sunrise":"08:26",
 "source":"qweather",
 "sourceMeta":{"sourceName":"中国气象局·和风天气",
               "publishedAt":"2026-09-25T12:25+08:00","pointName":"塔钦"}}
```

温度/天气/风力/日出/通行状态齐全，且 `sourceMeta` 已经把
**来源机构（中国气象局·和风天气）+ 更新时间 + 观测点（塔钦）** 都挂上了
——正好满足设计红线"天气须来源机构 + 更新时间双挂"。

那为什么我第一版会看错？我只看了 `feed_demand.py` 的 `/weather/today`：

```python
# site_config 无 weather_today_default 键，返回配置零值
cfg = {}
```

它是空壳没错，但**它不是给 C端 现在用的**。查 `docs/structure/contracts/sources.json`：

> `bff.weather_today` 的唯一消费者是 **`weather-strip` 组件，而该组件为 pending
> （14/15 类口径未定）⇒ 口径落地前该 source 实际不可引用，引用即 E_TYPE_PENDING**

所以准确结论是：

- 数据源 ✅ 早就通了（和风天气，含来源与时间双挂）
- 真实端点 ✅ `GET /api/miniapp/weather` 工作正常
- **真缺口**：C端 v2 目前消费的 `/api/miniapp/weather/today` 是给未定组件的占位；
  且真实端点 `GET /api/miniapp/weather` **需要登录**，游客首屏若要免登录看天气，
  还缺一个免登录的天气出口

**教训（同"截断输出就下结论"一类）**：我只 grep 到一处实现就断言"没接"，
没查 `services/` 层、也没读 `sources.json` 的组件口径说明。
判断"有没有接"之前，必须确认**是不是只看到了局部**。

### ❌ 孤岛：A端 能录，但 C端 不看

| A端 页面 | 管的表 | C端 是否消费 |
|---|---|---|
| 内容管理 `/cms`（含发布/下线流程） | `cms_posts` | **完全不消费**（全仓无引用） |

运营在这个页认真录文章、走发布下线流程，**C端 一个字都不显示**。
这是最浪费的一类错配——流程齐全、数据沉淀，但接错了头。

### ⚠️ 待确认（未下定论，需归属方核）

| 项 | 疑点 |
|---|---|
| 场景管理 `/scenes` | 库里 **`scenes` 表不存在**；C端 只用 `POST /scenes/checkin`（打卡动作），不读场景列表 ⇒ A端 该页产出疑似无人消费 |
| 故事管理 `/stories` | `dsl-sources.ts` 明确写着：stories **未登记**，引用将被拒绝（`E_SOURCE_UNKNOWN`），差异已上报 P2 ⇒ C端 实际不消费 |

---

## 三、结论

**A端 没有完全对接上。** 按"从 C端 反查"的口径：

- 对齐的：**6 类**（文案/商品/推荐/商户页 + 两类本就不需要录入的行为数据）
- **硬缺口 2 个**：`guides`、`guide_articles`（违反铁律，游客可见，白标必须能改）
  —— 已复核确认：后端 admin 层确实无任何写接口（`admin_content.py` 只有 POI/路线/规则/攻略知识/配置项）
- **天气**：数据源与真实端点均正常，**非**空壳；真缺口是 C端 v2 消费的占位端点未接真实数据，且真实端点需登录
- **孤岛 1 个**：`cms_posts`（运营白录）
- **待确认 2 个**：`scenes`、`stories`

也就是说，A端 页面数量不少，但**与 C端 真正消费的数据对得上的只是一部分**；
最讽刺的是两头都断：能录的没人看、要看的录不了。

---

## 四、修复优先级（按"游客是否直接受影响"排）

| 优先级 | 事项 | 为什么 |
|---|---|---|
| **P0** | 天气：把 C端 消费的 `/weather/today` 接上 qweather 真实数据（或让游客端改用已就绪的真实端点，并补一个免登录出口） | 数据源早已就位，只差最后一米；游客首屏看不到真实天气 |
| **P0** | 给 `guides` / `guide_articles` 补 admin CRUD + A端 录入页 | 违反"业务数据 A端 录入"铁律；白标必须能改 |
| P1 | `cms_posts` 要么让 C端 消费、要么下线该页 | 避免运营继续白录 |
| P2 | 确认 `scenes` / `stories` 归属后处置 | 疑似孤岛，需归属方确认 |

---

## 五、备注

本次盘点只做**只读核对**，未改动任何 C端 或他人域代码。
涉及 `guides` / `guide_articles` / `cms_posts` / `scenes` / `stories` 的修复，
按跨域纪律需确认归属后再动。
