AstroResearch/docs/api.md
Asfmq 8cc2b74abc feat: 手动上传绕防爬、下载错误诊断与健康检查工具;模块化重构 API 与批量同步
后端:
  - 将 handlers.rs (1338行) 拆分为 helpers/papers/notes/sync 四模块
  - 将 batch_sync.rs 拆分为 batch/{mod,meta,asset} 三模块
  - 新增 POST /api/upload 多部件文件上传接口
  - 新增 POST /api/no_resource 标记文献"无全文资源"
  - 新增 GET/POST /api/active_bibcode 追踪活跃文献
  - StandardPaper 结构体扩展 pdf_error / html_error 错误诊断字段
  - download.rs 记录下载失败详情至数据库
  - 新增 health_check 二进制工具,支持只读扫描与 --fix 自动修复
  - 移除 scratch/ 目录、recovered_handlers.rs 及调试日志

  前端:
  - 新建 CustomSelect 可复用组件,替换全部原生 select
  - LibraryPanel:同步按钮反馈动画、下载失败/无资源状态筛选与计数、
    文献类型筛选、状态优先排序、搜索一键清空
  - 详情弹窗:错误诊断展示、手动 PDF/HTML 上传区、无资源标记/恢复
  - SearchPanel:扩展文献类型徽章、下载失败状态提示
  - SyncPanel:同步启动乐观 UI 更新、日志容器内自动滚动
  - Tab 状态 localStorage 持久化、弹窗 z-index 修复
2026-06-11 22:56:36 +08:00

560 lines
19 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.

# AstroResearch REST API Documentation / REST API 接口文档
AstroResearch 后端服务运行于 Rust Axum 框架之上,默认基准 URL 为 `http://localhost:8000/api`
---
## 1. 共享类型定义 (TypeScript Type Definitions)
为了前后端类型一致,以下是主要的 TypeScript 数据接口定义:
```typescript
// 标准文献元数据
export interface StandardPaper {
bibcode: string;
title: string;
authors: string[];
year: string;
pub_journal: string;
keywords: string[];
abstract_text: string;
doi: string;
arxiv_id: string;
citation_count: number;
reference_count: number;
is_downloaded: boolean;
has_markdown: boolean;
has_translation: boolean;
doctype: string;
pdf_error?: string; // PDF 下载失败诊断信息(如存在)
html_error?: string; // HTML 下载失败诊断信息(如存在)
}
// 笔记记录
export interface NoteRecord {
id: number;
bibcode: string;
paragraph_index: number;
note_text: string;
highlight_color: string; // 'yellow' | 'green' | 'blue' | 'pink'
selected_text: string;
created_at: string;
}
// 引文网络
export interface CitationNetwork {
bibcode: string;
title: string;
citation_count: number;
reference_count: number;
references: string[];
citations: string[];
citation_counts?: Record<string, number>;
}
// 已保存的同步检索条件
export interface SavedSyncQuery {
id: number;
query: string;
source: string;
limit_count: number;
last_run: string;
}
```
### 1.1 错误诊断字段说明
`pdf_error``html_error` 字段用于传递文献下载失败的具体原因:
- 当数据库中对应的 `pdf_path``html_path``error:` 前缀存储时,前端会自动提取前缀后的内容作为诊断信息。
- 特殊值 `no_resource`:表示用户手动标记了该文献为"无有效全文资源",后续批量下载任务将自动跳过此文献。
- 其他值为系统自动检测到的下载失败原因如网络超时、Cloudflare 拦截、404 等)。
---
## 2. 接口分模块详述 (API Endpoints)
### 2.1 检索与引文导出模块 (Search & Citations Export)
#### 2.1.1 跨源文献统一搜索
- **Endpoint**: `GET /api/search`
- **Description**: 同时从 NASA ADS 与 arXiv XML 接口检索文献,返回去重并标准化后的文献元数据。
- **Query Parameters**:
- `q` (string, required): 检索关键词。
- `source` (string, optional): 指定源,取值为 `all` | `ads` | `arxiv`,默认 `all`
- `rows` (number, optional): 返回条数限制,默认 10。
- `start` (number, optional): 分页起始偏移量,默认 0。
- `sort` (string, optional): 排序字段,取值为 `relevance` | `date_desc` | `date_asc` | `citations_desc`,默认 `relevance`
- **Response Schema (`Vec<StandardPaper>`)**:
- HTTP `200 OK`
- **cURL 示例**:
```bash
curl -G "http://localhost:8000/api/search" \
--data-urlencode "q=Hertzsprung-Russell diagram" \
--data-urlencode "source=all" \
--data-urlencode "start=0" \
--data-urlencode "rows=10" \
--data-urlencode "sort=citations_desc"
```
#### 2.1.2 批量引文 BibTeX 导出
- **Endpoint**: `POST /api/export`
- **Description**: 将选中的文献 Bibcode 批量提交给 NASA ADS 接口,返回拼接的标准 BibTeX 文本。
- **Request Body**:
```json
{
"bibcodes": ["2024arXiv241011663H", "1984AJ.....89..374B"]
}
```
- **Response Schema**:
```json
{
"bibtex": "@ARTICLE{2024arXiv241011663H, ...}\n\n@ARTICLE{1984AJ.....89..374B, ...}"
}
```
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/export" \
-H "Content-Type: application/json" \
-d '{"bibcodes": ["2024arXiv241011663H"]}'
```
---
### 2.2 馆藏管理与物理文件模块 (Library & Local Storage)
#### 2.2.1 获取馆藏文献列表
- **Endpoint**: `GET /api/library`
- **Description**: 查询本地 SQLite 数据库中已收藏入库的所有文献列表,后端会自动**实时感应物理文件是否存在**来修正 `is_downloaded` / `has_markdown` 等布尔状态。同时读取并返回 `pdf_error` / `html_error` 诊断字段。
- **Response Schema (`Vec<StandardPaper>`)**:
- HTTP `200 OK`
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/library"
```
#### 2.2.2 触发并行文献下载
- **Endpoint**: `POST /api/download`
- **Description**: 触发后台线程拉取文献的 PDF 及 HTML。如果是 arXiv 来源优先官方 HTML 兜底 ar5iv并支持强制更新。下载失败时会在数据库中以 `error:` 前缀记录具体原因。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H",
"force": false
}
```
- **Response Schema (`StandardPaper`)**: Returns the updated paper structure with `is_downloaded: true` (on success) or `pdf_error`/`html_error` populated (on failure).
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/download" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H", "force": true}'
```
#### 2.2.3 手动上传文献物理文件
- **Endpoint**: `POST /api/upload`
- **Description**: 手动上传用户离线下载的 HTML 或 PDF 物理文件以便系统进行结构化解析和双语翻译。此接口常用于前端手动上传或浏览器书签直推同步支持绕过防爬与验证码限制。上传时会自动进行文件格式校验PDF 校验 `%PDF` 文件头),并支持通过 DOI 或 arXiv ID 自动匹配 Bibcode。
- **Request Body (Multipart Form Data)**:
- `bibcode` (string, required): 文献唯一标识符Bibcode、DOI 或 arXiv ID。
- `type` (string, required): 文件类别,取值为 `pdf` | `html`
- `file` (file binary, required): 上传的 PDF 或 HTML 文件。
- **Response Schema (`StandardPaper`)**: 返回已更新下载状态(`is_downloaded: true`)的文献标准化元数据。
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/upload" \
-F "bibcode=2024arXiv241011663H" \
-F "type=pdf" \
-F "file=@/path/to/downloaded.pdf"
```
#### 2.2.4 标记/取消"无有效全文资源"
- **Endpoint**: `POST /api/no_resource`
- **Description**: 将文献标记为"无有效全文资源"或清除该标记。标记后,后续批量下载/解析任务将自动跳过此文献。此操作会将数据库中的 `pdf_path``html_path` 设置为(或清除)`error:no_resource`。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H",
"clear": false
}
```
- `bibcode` (string, required): 文献唯一标识符。
- `clear` (boolean, optional): 设为 `true` 清除标记(恢复自动下载),默认 `false`(标记无资源)。
- **Response Schema (`StandardPaper`)**: 返回更新后的文献标准化元数据。
- **cURL 示例**:
```bash
# 标记为无资源
curl -X POST "http://localhost:8000/api/no_resource" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H"}'
# 清除标记(恢复自动下载)
curl -X POST "http://localhost:8000/api/no_resource" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H", "clear": true}'
```
#### 2.2.5 触发文献结构化解析
- **Endpoint**: `POST /api/parse`
- **Description**: 将本地下载的 HTML/PDF 清洗为 Markdown。支持 `force` 强制重新执行。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H",
"force": false
}
```
- **Response Schema**:
```json
{
"markdown": "# 论文标题\n\n## 1. 绪论\n..."
}
```
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/parse" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H", "force": false}'
```
---
### 2.3 阅读器与翻译模块 (Reader & LLM Translation)
#### 2.3.1 获取文献阅读详情
- **Endpoint**: `GET /api/paper`
- **Description**: 获取某篇文献的标准元数据和已缓存的英文正文 Markdown 以及翻译后 Markdown。
- **Query Parameters**:
- `bibcode` (string, required): 文献唯一标识符。
- **Response Schema**:
```json
{
"paper": { ... },
"english_content": "# Abstract...", // 若未解析,返回 null
"translation_content": "# 摘要..." // 若未翻译,返回 null
}
```
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/paper?bibcode=2024arXiv241011663H"
```
#### 2.3.2 触发 LLM 对照翻译
- **Endpoint**: `POST /api/translate`
- **Description**: 将英文 Markdown 提取本地词典名词注入 Glossary 提示词,并调用大模型进行学术翻译,最后写回本地物理文件并入库。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H",
"force": false
}
```
- **Response Schema**:
```json
{
"translation": "# 翻译结果..."
}
```
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/translate" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H"}'
```
---
### 2.4 引文网络拓扑模块 (Citation Galaxy Map)
#### 2.4.1 查询文献的引文拓扑
- **Endpoint**: `GET /api/citations`
- **Description**: 获取某篇文献的参考文献 (References) 和施引文献 (Citations) 的 Bibcode 数组列表,用于渲染拓扑关系网。
- **Query Parameters**:
- `bibcode` (string, required): 目标文献 Bibcode。
- **Response Schema**:
```json
{
"bibcode": "2024arXiv241011663H",
"title": "...",
"citation_count": 12,
"reference_count": 48,
"references": ["bibcode1", "bibcode2"],
"citations": ["bibcode3", "bibcode4"],
"citation_counts": { "bibcode3": 5, "bibcode4": 120 }
}
```
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/citations?bibcode=2024arXiv241011663H"
```
---
### 2.5 笔记高亮模块 (Notes & Highlights)
#### 2.5.1 创建笔记与高亮
- **Endpoint**: `POST /api/notes`
- **Description**: 对指定文献的特定段落位置创建高亮选段,并记录文字备注。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H",
"paragraph_index": 12,
"note_text": "这是一个重要的物理模型",
"highlight_color": "yellow",
"selected_text": "the standard model of galaxy formation"
}
```
- **Response Schema (`NoteRecord`)**: Returns the created note details containing auto-incremented `id` and creation timestamp.
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/notes" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H", "paragraph_index": 12, "note_text": "My Note", "highlight_color": "green", "selected_text": "original text"}'
```
#### 2.5.2 获取单篇文献下的全部笔记
- **Endpoint**: `GET /api/notes`
- **Description**: 查询某篇文献关联的所有笔记。
- **Query Parameters**:
- `bibcode` (string, required): 目标文献。
- **Response Schema (`Vec<NoteRecord>`)**:
- HTTP `200 OK`
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/notes?bibcode=2024arXiv241011663H"
```
#### 2.5.3 删除笔记
- **Endpoint**: `DELETE /api/notes`
- **Description**: 物理删除指定 ID 的笔记高亮记录。
- **Query Parameters**:
- `id` (number, required): 笔记记录的唯一自增 id。
- **Response Schema**:
```json
{
"status": "success"
}
```
- **cURL 示例**:
```bash
curl -X DELETE "http://localhost:8000/api/notes?id=5"
```
---
### 2.6 批量同步与文献处理模块 (Batch Sync & Processing)
#### 2.6.1 预估元数据同步匹配总量
- **Endpoint**: `GET /api/sync/meta/count`
- **Description**: 向 ADS 或 arXiv 发送带 rows=0 的检索请求,快速获取该关键词匹配到的文献总量,而不拉取实际正文。
- **Query Parameters**:
- `q` (string, required): 检索词。
- `source` (string, required): 数据源,支持 `all` | `ads` | `arxiv`
- **Response Schema**:
```json
{
"total": 1285
}
```
- **cURL 示例**:
```bash
curl -G "http://localhost:8000/api/sync/meta/count" \
--data-urlencode "q=hot subdwarf" \
--data-urlencode "source=all"
```
#### 2.6.2 启动后台元数据同步
- **Endpoint**: `POST /api/sync/meta/run`
- **Description**: 后台异步启动对指定关键词的文献元数据的大批量增量检索与同步入库。若当前已有同步任务在运行中,将返回 `409 Conflict`
- **Request Body**:
```json
{
"q": "hot subdwarf",
"source": "all",
"limit": 200
}
```
- **Response Schema**: Returns HTTP `200 OK` (plain text success message) 或 `409 Conflict` (已有任务运行)。
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/sync/meta/run" \
-H "Content-Type: application/json" \
-d '{"q": "hot subdwarf", "source": "all", "limit": 200}'
```
#### 2.6.3 查询元数据同步运行状态与进度
- **Endpoint**: `GET /api/sync/meta/status`
- **Description**: 获取当前后台正在运行或最近一次运行的元数据同步任务的详细状态和进度百分比。
- **Response Schema**:
```json
{
"active": false,
"query": "hot subdwarf",
"source": "all",
"synced": 200,
"total": 200
}
```
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/sync/meta/status"
```
#### 2.6.4 启动后台文献资源批量下载/解析
- **Endpoint**: `POST /api/sync/asset/run`
- **Description**: 后台异步启动文献物理资源 (PDF/HTML) 的批量下载及结构化 Markdown 转换任务。支持按文献 Bibcode 列表或按状态范围筛选处理目标。
- **Request Body**:
```json
{
"action": "all",
"scope": "undownloaded",
"sort_order": "default",
"limit_count": 50
}
```
- `action` (string): `"all"` (下载并解析) | `"download"` (仅下载) | `"parse"` (仅解析) | `"translate"` (仅翻译)。
- `scope` (string): `"all"` (全部) | `"undownloaded"` (仅未下载) | `"unparsed"` (仅未解析)。
- `sort_order` (string, optional): `"default"` | `"pub_year_desc"` | `"created_at_desc"`
- `limit_count` (number, optional): 批量处理上限,默认处理全部匹配文献。
- **Response Schema**: Returns HTTP `200 OK` (plain text success message) 或 `409 Conflict` (已有任务运行)。
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/sync/asset/run" \
-H "Content-Type: application/json" \
-d '{"action": "all", "scope": "undownloaded"}'
```
#### 2.6.5 停止正在运行的物理资源处理任务
- **Endpoint**: `POST /api/sync/asset/stop`
- **Description**: 中断并停止当前后台正在执行的批量下载与解析流水线任务。
- **Response Schema**: Returns HTTP `200 OK` (plain text status message).
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/sync/asset/stop"
```
#### 2.6.6 查询批量处理任务状态与日志
- **Endpoint**: `GET /api/sync/asset/status`
- **Description**: 获取当前后台批量下载与解析任务的状态、总匹配文献数、已下载数、已解析数、失败数、当前处理的 Bibcode以及实时流转的终端日志最多保留最新 100 条)。
- **Response Schema**:
```json
{
"active": false,
"total": 12,
"downloaded": 12,
"parsed": 12,
"download_failed": 0,
"parse_failed": 0,
"current_bibcode": "2020A&A...635A..38C",
"logs": [
"[INFO] 批量处理任务初始化成功",
"[INFO] 开始下载文献: 2020A&A...635A..38C...",
"[INFO] 文献 2020A&A...635A..38C 下载完成"
],
"action": "all"
}
```
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/sync/asset/status"
```
#### 2.6.7 获取已保存的同步检索条件
- **Endpoint**: `GET /api/sync/queries`
- **Description**: 获取用户保存的所有同步检索条件列表,用于快速重新同步。
- **Response Schema (`Vec<SavedSyncQuery>`)**:
- HTTP `200 OK`
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/sync/queries"
```
#### 2.6.8 删除已保存的同步检索条件
- **Endpoint**: `DELETE /api/sync/queries/:id`
- **Description**: 删除指定 ID 的已保存同步检索条件。
- **Path Parameters**:
- `id` (number, required): 同步检索条件的唯一自增 ID。
- **Response Schema**: Returns HTTP `200 OK` (plain text success message).
- **cURL 示例**:
```bash
curl -X DELETE "http://localhost:8000/api/sync/queries/1"
```
---
### 2.7 活跃文献追踪 (Active Bibcode Tracking)
#### 2.7.1 获取当前活跃文献
- **Endpoint**: `GET /api/active_bibcode`
- **Description**: 获取当前用户正在查看/操作的文献 Bibcode。前端在用户点击文献外部链接如 ADS、DOI、arXiv时自动上报。
- **Response Schema**:
```json
{
"bibcode": "2024arXiv241011663H"
}
```
若无活跃文献,`bibcode` 为 `null`
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/active_bibcode"
```
#### 2.7.2 设置当前活跃文献
- **Endpoint**: `POST /api/active_bibcode`
- **Description**: 设置当前正在查看的文献 Bibcode用于浏览器书签直推等场景。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H"
}
```
- **Response Schema**: Returns HTTP `200 OK`.
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/active_bibcode" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H"}'
```
---
## 3. 完整路由表 (Route Summary)
| 方法 | 路径 | 说明 |
|:---|:---|:---|
| `GET` | `/api/search` | 跨源文献统一搜索 |
| `POST` | `/api/download` | 触发文献下载 |
| `POST` | `/api/upload` | 手动上传文献文件 |
| `POST` | `/api/no_resource` | 标记/取消"无有效全文资源" |
| `POST` | `/api/parse` | 触发文献结构化解析 |
| `POST` | `/api/translate` | 触发 LLM 对照翻译 |
| `GET` | `/api/citations` | 查询引文拓扑网络 |
| `GET` | `/api/paper` | 获取文献阅读详情 |
| `GET` | `/api/library` | 获取馆藏文献列表 |
| `POST` | `/api/export` | 批量 BibTeX 导出 |
| `POST` | `/api/notes` | 创建笔记与高亮 |
| `GET` | `/api/notes` | 获取文献笔记列表 |
| `DELETE` | `/api/notes` | 删除笔记 |
| `GET` | `/api/sync/meta/count` | 预估元数据同步总量 |
| `POST` | `/api/sync/meta/run` | 启动元数据同步 |
| `GET` | `/api/sync/meta/status` | 查询元数据同步状态 |
| `POST` | `/api/sync/asset/run` | 启动资源批量处理 |
| `POST` | `/api/sync/asset/stop` | 停止资源批量处理 |
| `GET` | `/api/sync/asset/status` | 查询资源处理状态 |
| `GET` | `/api/sync/queries` | 获取已保存检索条件 |
| `DELETE` | `/api/sync/queries/:id` | 删除已保存检索条件 |
| `GET` | `/api/active_bibcode` | 获取当前活跃文献 |
| `POST` | `/api/active_bibcode` | 设置当前活跃文献 |
---
## 4. 常见 HTTP 状态码与异常处理 (Error Codes)
系统基于标准的 HTTP Status Codes 返回错误原因,响应的 Response Body 中通常为纯文本提示String
| 状态码 | 错误类型 | 触发常见场景及原因说明 |
| :--- | :--- | :--- |
| **`400 Bad Request`** | 业务请求不合规 | - 文献未下载/解析却直接调用 `translate`<br>- 上传文件格式不合法(如 PDF 文件头校验失败)。<br>- 缺少必需参数(如 `bibcode` 为空)。 |
| **`404 Not Found`** | 资源未找到 | - 数据库中没有该 Bibcode 的收藏记录。 |
| **`409 Conflict`** | 状态冲突 | - 已有批量同步任务在后台运行中,重复启动时触发。 |
| **`500 Internal Error`**| 服务器内部错误 | - 第三方 LLM / ADS 接口通信超时或返回异常。<br>- 本地磁盘 IO 失败(如写入文件权限受阻)。<br>- 数据库查询异常。 |