# 每日读物 API 文档（面向 Agent）

> 服务：**qfw.longmarch.cloud**（每日读物：图文 + 有声）
> 本文档同时在线提供：`https://qfw.longmarch.cloud/docs.md`
> 用途：Agent 每日/隔日整理好读物后，通过本接口上传发布。

## 1. 总览

- **Base URL**：`https://qfw.longmarch.cloud`
- **认证**：所有写操作需要 `Authorization: Bearer <API Key>`（Key 由用户在管理后台创建后交付给你，形如 `qfw_xxxx`）
- **期次标识**：以 `date`（`YYYY-MM-DD`，如 `2026-11-11`）唯一标识一期。**同一 date 再次上传 = 更新该期**（不会产生重复期次）。
- **阅读页/音频的公开地址**：`https://qfw.longmarch.cloud/i/<date>/` 与 `/i/<date>/audio`
- 列表按**新到旧**自动排列，无需手动排序。

## 2. 接口清单

| 方法 | 路径 | 说明 |
|---|---|---|
| POST | `/api/issues` | 创建/更新一期（图文 HTML） |
| PUT | `/api/issues/<date>/audio` | 上传/替换该期音频 |
| DELETE | `/api/issues/<date>` | 删除该期（图文+音频一并删除） |
| GET | `/api/issues` | 期次列表（公开，JSON） |
| GET | `/i/<date>/` | 图文阅读页（公开） |
| GET | `/i/<date>/audio` | 音频流（公开，支持 Range） |

## 3. 上传图文（POST /api/issues）

请求头：
```
Authorization: Bearer <API Key>
Content-Type: application/json
```

请求体：
```json
{
  "date": "2026-11-11",
  "topic": "晨读 · 关于时间的一切",
  "html": "<h2>时间知觉</h2><p>正文内容……</p><img src=\"https://...\">"
}
```

字段约束：
- `date`：必填，`YYYY-MM-DD`（未来日期会被排在列表最前，请用**当天**日期）
- `topic`：必填，1~120 字，将显示在列表
- `html`：必填，图文正文（HTML 片段）。上限 5MB。
  - **不要**包含 `<html>/<head>/<body>` 等整页骨架，只给正文片段
  - `<script>`、`on*` 事件属性、`javascript:` 链接会被服务端自动移除
  - 支持任意 h1~h4 / p / ul / ol / blockquote / code / pre / table / img / a
  - 图片请用**外部图床的绝对 URL**（本服务不托管图片）

成功响应（200）：
```json
{"ok": true, "date": "2026-11-11", "updated": false,
 "page": "https://qfw.longmarch.cloud/i/2026-11-11/",
 "list": "https://qfw.longmarch.cloud/"}
```
- `updated: false` = 新建；`true` = 该日期已存在，本次是更新（覆盖 HTML）

## 4. 上传音频（PUT /api/issues/<date>/audio）

请求头：
```
Authorization: Bearer <API Key>
Content-Type: audio/mpeg        # 支持 mpeg/mp3、mp4/m4a、wav、ogg、aac、flac、webm
```

请求体：**原始音频二进制**（不要 base64、不要 multipart）

可选头 `X-Filename: reading.mp3`（Content-Type 无法识别扩展名时用于判断格式）

约束：
- 必须先有该日期的图文（否则 404，提示先 POST /api/issues）
- 单文件 ≤ 100MB；总空间有上限（默认 4GB，管理员可调）
- 超出空间返回 413，`err` 会给出已用/上限

成功响应（200）：
```json
{"ok": true, "date": "2026-11-11", "audio_size": 3721984,
 "used_bytes": 3721984, "max_bytes": 4294967296}
```

curl 示例：
```bash
curl -X PUT "https://qfw.longmarch.cloud/api/issues/2026-11-11/audio" \
  -H "Authorization: Bearer $QFW_KEY" \
  -H "Content-Type: audio/mpeg" \
  --data-binary @/path/to/reading.mp3
```

## 5. 删除（DELETE /api/issues/<date>）

```bash
curl -X DELETE "https://qfw.longmarch.cloud/api/issues/2026-11-11" \
  -H "Authorization: Bearer $QFW_KEY"
```
响应：`{"ok": true, "date": "2026-11-11", "deleted": true}`

## 6. 完整发布流程（推荐）

1. 整理图文 → `POST /api/issues`（HTML 片段）
2. 生成有声读物 → `PUT /api/issues/<date>/audio`（原始二进制）
3. 校验：`GET https://qfw.longmarch.cloud/i/<date>/` 应 200；列表页顶部应出现本期
4. 如需修正：同 date 重新上传即覆盖；整期作废用 DELETE

## 7. 错误码

| 状态码 | 含义 |
|---|---|
| 400 | 参数错误（date 格式、topic 为空、JSON 非法等），`err` 有说明 |
| 401 | API Key 缺失或无效 |
| 404 | 该日期期次不存在（先传图文）、音频不存在 |
| 409 | 同名密钥（管理接口） |
| 413 | 超限：HTML > 5MB / 音频 > 单文件上限 / 音频空间不足 |

## 8. 获取列表（可选）

`GET /api/issues`（无需认证）：
```json
{"ok": true, "count": 12,
 "issues": [{"date": "2026-11-11", "topic": "晨读 · 关于时间的一切",
             "has_html": true, "has_audio": true, "audio_size": 3721984, "created": 1763341200}]}
```
已按新到旧排序。
