# 内部回写端点(internal 族,pricebot / 发布流程 → app-server)

> 所属:internal 组(前缀 `/internal`,源 `app/api/internal/`) | 鉴权:**`X-Internal-Secret` 头**(== `settings.INTERNAL_API_SECRET`) | [← 返回 API 索引](../README.md)

**不是给客户端的接口**:不走用户 JWT。`§6` 是 app-server 透传给 pricebot,这里反过来——pricebot(及发布流程)把少量数据 server→server 回写 app-server 落库。

## 鉴权(所有 internal 端点共用)
请求头带 `X-Internal-Secret: <密钥>`,服务端常量时间比对 `settings.INTERNAL_API_SECRET`:
- 密钥**未配置**(默认空)→ `503`(挡裸奔写端点)。
- 不匹配 / 缺失 → `401`。
- 需 pricebot 与 app-server 两边 `.env` 配**同一** `INTERNAL_API_SECRET` 才生效(未配则 pricebot 侧跳过上报、不影响比价/领券)。

## 端点

| 方法 + 路径 | 落库 | 说明 |
|---|---|---|
| `POST /internal/price-observation` | [`price_observation`](../../database/price_observation.md) | 比价 done 帧整批价格事实上报;`(trace_id, platform, scope)` 幂等,返回 `{inserted, skipped}` |
| `GET /internal/store-mapping/lookup` | (只读 [`store_mapping`](../../database/store_mapping.md)) | 比价前按 `source_platform`+`name`(+`lat`/`lng`)反查各目标平台已沉淀的店铺 id/deeplink;命中→pricebot 直接 deeplink 省现场搜店 |
| `POST /internal/store-mapping` | `store_mapping` | 跨平台「同一家店」身份映射上报;`trace_id` 幂等、填空合并,返回 `{inserted, row_id}` |
| `POST /internal/store-mapping/invalidate` | `store_mapping` | 标记某平台 `shop_id` 的缓存 deeplink 失效(pricebot 撞错误页回退时报);当前支持 `taobao`/`jd`,其它平台 no-op,返回 `{ok, affected}` |
| `POST /internal/launch-confirm-sample` | [`launch_confirm_sample`](../../database/launch_confirm_sample.md) | 启动确认窗 LLM 兜底放行后回写样本(host 包 + 弹窗树 + plan + locale);**都上报、不去重**,返回 `{id}` |
| `GET /internal/launch-confirm-samples` | (只读 `launch_confirm_sample`) | 样本列表(#91,供 pricebot `distill_launch_confirm.py` 聚合沉淀回静态规则);可选筛 `exec_success` / `host_package` / `since_days`,`limit` 默认 1000 |
| `POST /internal/app-version` | [`app_config`](../../database/app_config.md)(key=`latest_app_version`) | **发布流程**(非 pricebot)出 APK 后写最新版本号/下载链接/sha256;客户端再 `GET /api/v1/platform/app-version` 读做 OTA。也是应急改版本信息(紧急下线/改 `apk_url`)入口 |

## 错误
- `401` 密钥不匹配 / 缺失。
- `503` `INTERNAL_API_SECRET` 未配置。
- `422` 请求体字段校验失败。

## 说明
- 与不鉴权的比价透传(`compare.py` / `coupon.py`)无关:那两个是**客户端→server** 的透传壳,这里是 **server→server** 的内部写库。
- `launch-confirm-sample` 的样本供研发**人工**定期沉淀进 pricebot 的 `launch_confirm.PROFILES` 静态规则(让以后同款启动窗回到快路径,不必再调 LLM)。
