# Resource 存储系统

## 概述

Resource 存储系统用于管理原始资源（代码片段、凭证、Cookie等），与 Knowledge 系统互补：
- **Knowledge**：结构化知识条目（任务场景 + 经验内容）
- **Content**：原始资源存储（代码、凭证、配置等）

Knowledge 可以通过 `resource_id` 引用 Content 资源。

---

## 数据结构

### 数据库表

实现位置：`knowhub/server.py:init_db`

```sql
CREATE TABLE resources (
    id            TEXT PRIMARY KEY,        -- 层级ID，如 "tools/selenium/login"
    title         TEXT DEFAULT '',
    body          TEXT NOT NULL,           -- 公开内容
    secure_body   TEXT DEFAULT '',         -- 敏感内容（加密存储）
    content_type  TEXT DEFAULT 'text',     -- text|code|credential|cookie
    metadata      TEXT DEFAULT '{}',       -- JSON: {language, acquired_at, expires_at}
    sort_order    INTEGER DEFAULT 0,
    submitted_by  TEXT DEFAULT '',
    created_at    TEXT NOT NULL,
    updated_at    TEXT DEFAULT ''
)
```

### 字段说明

- **id**: 层级标识符，支持路径格式（如 `tools/selenium/login`）
- **title**: 资源标题
- **body**: 公开内容（明文存储，可搜索）
- **secure_body**: 敏感内容（加密存储，需要组织密钥访问）
- **content_type**: 内容类型
  - `text`: 普通文本
  - `code`: 代码片段
  - `credential`: 账号密码
  - `cookie`: Cookie数据
- **metadata**: 元数据（JSON对象）
  - `language`: 代码语言（当 content_type=code）
  - `acquired_at`: 获取时间（ISO 8601格式）
  - `expires_at`: 过期时间（用于cookie）
- **sort_order**: 排序顺序（同级内容排序）
- **submitted_by**: 提交者标识
- **created_at**: 创建时间
- **updated_at**: 更新时间

---

## 加密机制

### 组织密钥

敏感内容使用 AES-256-GCM 加密，密钥从环境变量读取：

```bash
# .env
ORG_KEYS=org1:key1_base64,org2:key2_base64
```

每个 content 的 `id` 前缀决定使用哪个组织密钥（如 `org1/tools/...` 使用 `org1` 的密钥）。

### 加密存储格式

```
encrypted:AES256-GCM:{base64_encoded_data}
```

实现位置：`knowhub/server.py:encrypt_resource`, `decrypt_resource`

### 访问控制

读取包含 `secure_body` 的 content 时：
- 需要提供 `X-Org-Key` HTTP 头
- 验证通过后解密返回
- 验证失败返回 `[ENCRYPTED]` 占位符

---

## API 端点

### `POST /api/content`

提交新资源。

**请求体**：

```json
{
  "id": "tools/selenium/login",
  "title": "Selenium登录代码",
  "body": "使用undetected_chromedriver绕过检测",
  "secure_body": "账号：xxx 密码：xxx",
  "content_type": "credential",
  "metadata": {
    "acquired_at": "2026-03-06T10:00:00Z"
  },
  "submitted_by": "user@example.com"
}
```

实现位置：`knowhub/server.py:submit_resource`

### `GET /api/content/{resource_id}`

获取资源（支持层级路径）。

**请求头**（可选）：
```
X-Org-Key: your_org_key_here
```

**响应**：

```json
{
  "id": "tools/selenium/login",
  "title": "Selenium登录代码",
  "body": "使用undetected_chromedriver绕过检测",
  "secure_body": "账号：xxx 密码：xxx",  // 有密钥时解密
  "content_type": "credential",
  "metadata": {
    "acquired_at": "2026-03-06T10:00:00Z"
  },
  "toc": {"id": "tools", "title": "工具集"},
  "children": [
    {"id": "tools/selenium/login", "title": "登录代码"}
  ]
}
```

实现位置：`knowhub/server.py:get_resource`

### `PATCH /api/content/{resource_id}`

更新资源字段。

**请求体**（所有字段可选）：

```json
{
  "title": "新标题",
  "body": "新的公开内容",
  "secure_body": "新的敏感内容",
  "metadata": {
    "expires_at": "2026-03-07T10:00:00Z"
  }
}
```

实现位置：`knowhub/server.py:patch_resource`

### `GET /api/content`

列出所有资源（支持过滤）。

**参数**：
- `content_type`: 按类型过滤（可选）
- `limit`: 返回数量（默认100）

实现位置：`knowhub/server.py:list_resources`

---

## 使用场景

### 场景1：存储复杂代码

```json
{
  "id": "code/selenium/undetected",
  "title": "Selenium绕过检测",
  "body": "import undetected_chromedriver as uc\n\ndriver = uc.Chrome()\n...",
  "content_type": "code",
  "metadata": {
    "language": "python"
  }
}
```

### 场景2：存储账号密码

```json
{
  "id": "credentials/某网站",
  "title": "某网站登录凭证",
  "body": "使用方法：直接登录即可",
  "secure_body": "账号：user@example.com\n密码：SecurePass123",
  "content_type": "credential",
  "metadata": {
    "acquired_at": "2026-03-06T10:00:00Z"
  }
}
```

### 场景3：存储Cookie

```json
{
  "id": "cookies/某网站",
  "title": "某网站Cookie",
  "body": "适用于：已登录状态的API调用",
  "secure_body": "session_id=abc123; auth_token=xyz789",
  "content_type": "cookie",
  "metadata": {
    "acquired_at": "2026-03-06T10:00:00Z",
    "expires_at": "2026-03-07T10:00:00Z"
  }
}
```

### 场景4：Knowledge引用Content

```json
{
  "task": "登录某网站",
  "content": "使用Selenium + undetected_chromedriver绕过检测",
  "resource_id": "code/selenium/undetected",
  "secure_resource_id": "credentials/某网站"
}
```

---

## 层级结构

Content 通过 ID 路径实现树形组织：

```
tools/
├── selenium/
│   ├── login
│   └── scraping
└── api/
    └── requests

credentials/
├── 网站A
└── 网站B

cookies/
└── 网站A
```

获取 `tools/selenium/login` 时自动计算：
- **TOC**: 根节点 `tools`
- **Children**: 子节点列表
- **Prev/Next**: 同级节点导航

---

## 安全考虑

1. **加密存储**：敏感内容使用 AES-256-GCM 加密
2. **访问控制**：需要组织密钥才能解密
3. **密钥管理**：密钥存储在环境变量，不入库
4. **审计日志**：记录 `submitted_by` 和时间戳
5. **过期提醒**：Cookie 可设置 `expires_at`

---

## 与 Knowledge 的关系

| 维度 | Knowledge | Content |
|------|-----------|---------|
| 用途 | 结构化知识（经验、策略） | 原始资源（代码、凭证） |
| 存储 | task + content 字段 | body + secure_body 字段 |
| 搜索 | 语义搜索 + 质量排序 | 层级浏览 |
| 引用 | 可引用 resource_id | 被 knowledge 引用 |
| 加密 | 不加密（或整体加密） | 分离公开/敏感内容 |

---

## 实现位置

| 组件 | 文件路径 |
|------|---------|
| 数据库表 | `knowhub/server.py:init_db` |
| 加密/解密 | `knowhub/server.py:encrypt_resource`, `decrypt_resource` |
| POST /api/content | `knowhub/server.py:submit_resource` |
| GET /api/content/{id} | `knowhub/server.py:get_resource` |
| PATCH /api/content/{id} | `knowhub/server.py:patch_resource` |
| GET /api/content | `knowhub/server.py:list_resources` |
