Files
Enterprise-Knowledge-Base/docs/api/tenant.md
T
nullkey 1c7171b2c6 docs(api): rewrite markdown to match current routes
Refs #890 #1049 #1168.

按集成方视角全量审计 17 个 API markdown 文档与 internal/router/router.go
对齐。每个端点新增参数说明小节(path/query/body 字段含义)和响应字段
含义说明(#1168 的核心诉求)。

【与代码对齐】
- 删除已下线端点:system.md 中的 /system/minio/buckets(代码中已无对
  应路由)。
- 修正路径错误:chunk.md 中 /chunks/get-by-id/:id → /chunks/by-id/:id;
  /chunks/:id/delete-question → /chunks/by-id/:id/questions;
  organization.md 中 /organizations/preview/:invite_code → :code。
- 修正字段类型:faq tag_id / entry_id 由 string 改为 int64;
  knowledge.search 响应结构纠正。
- 补齐缺失端点(move-targets、batch-delete、move/progress、pin/unpin/
  stop/continue-stream、tool-approvals、organization agent-shares 等
  30+ 条)。

【精简】
- knowledge-base.md / model.md 把重复 5 次 / 3 次的完整对象样例
  收敛为指向首次出现("字段结构同 POST /xxx 响应"),节省约 400 行
  而不损失信息(仅去重,原作者写的每个字段定义都保留可达)。
- 示例 X-API-Key 统一为 sk-xxxxx(避免读者复制看似真实的 key)。

【清理】
- 删除内部实现细节引用:mcp-service.md 中 6 处 "issue #1173"、
  organization.md 中 "RegisterOrganizationRoutes" 等。

不动 initialization.md:其中端点(KB 配置、模型连通性测试、Ollama 管理)
对集成方有实用价值,保留原作者写好的内容不删。

格式统一遵循 web-search.md 重写后的范式(路由表 + 每端点方法/路径 +
参数表 + curl + 响应 JSON + 字段说明)。
2026-05-12 13:16:58 +08:00

511 lines
16 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.
# 租户管理 API
[返回目录](./README.md)
包含两组接口:
- 租户 CRUD(`/tenants`、`/tenants/:id`、`/tenants/:id/api-key`):当前认证用户对自己所属租户进行管理;跨租户访问需要管理员权限。
- 跨租户接口(`/tenants/all`、`/tenants/search`):**需要服务端启用 `EnableCrossTenantAccess` 且当前用户具备 `CanAccessAllTenants` 权限**,否则返回 403。
- 租户 KV 配置(`/tenants/kv/:key`):当前租户级别的通用配置项,**`tenant_id` 从认证上下文中获取,不在 URL 中传入**。
| 方法 | 路径 | 描述 |
| ------ | -------------------------- | ------------------------------------------------- |
| GET | `/tenants/all` | 获取所有租户列表(需跨租户权限) |
| GET | `/tenants/search` | 分页搜索租户(需跨租户权限) |
| POST | `/tenants` | 创建新租户 |
| GET | `/tenants/:id` | 获取指定租户信息 |
| PUT | `/tenants/:id` | 更新租户信息 |
| DELETE | `/tenants/:id` | 删除租户 |
| POST | `/tenants/:id/api-key` | 重置租户 API Key |
| GET | `/tenants` | 获取当前用户可见的租户列表 |
| GET | `/tenants/kv/:key` | 获取当前租户的 KV 配置(tenant 由认证上下文确定) |
| PUT | `/tenants/kv/:key` | 更新当前租户的 KV 配置(tenant 由认证上下文确定) |
## GET `/tenants/all` - 获取所有租户列表
获取系统中所有租户列表,需要跨租户权限。
**请求**:
```curl
curl --location 'http://localhost:8080/api/v1/tenants/all' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: sk-An7_t_izCKFIJ4iht9Xjcjnj_MC48ILvwezEDki9ScfIa7KA'
```
**响应**:
```json
{
"data": {
"items": [
{
"id": 10001,
"name": "weknora-1",
"description": "weknora tenants 1",
"status": "active",
"business": "wechat",
"created_at": "2025-08-11T20:37:28.39698+08:00",
"updated_at": "2025-08-11T20:37:28.405693+08:00"
},
{
"id": 10002,
"name": "weknora-2",
"description": "weknora tenants 2",
"status": "active",
"business": "wechat",
"created_at": "2025-08-11T20:52:58.05679+08:00",
"updated_at": "2025-08-11T20:52:58.060495+08:00"
}
]
},
"success": true
}
```
## GET `/tenants/search` - 搜索租户
按关键词搜索租户,需要跨租户权限。
**查询参数**:
- `keyword`: 搜索关键词(可选)
- `tenant_id`: 按租户ID筛选(可选)
- `page`: 页码(默认 1)
- `page_size`: 每页条数(默认 20)
**请求**:
```curl
curl --location 'http://localhost:8080/api/v1/tenants/search?keyword=weknora&page=1&page_size=10' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: sk-An7_t_izCKFIJ4iht9Xjcjnj_MC48ILvwezEDki9ScfIa7KA'
```
**响应**:
```json
{
"data": {
"items": [
{
"id": 10002,
"name": "weknora",
"description": "weknora tenants",
"status": "active",
"business": "wechat",
"created_at": "2025-08-11T20:52:58.05679+08:00",
"updated_at": "2025-08-11T20:52:58.060495+08:00"
}
],
"total": 1,
"page": 1,
"page_size": 10
},
"success": true
}
```
## POST `/tenants` - 创建新租户
创建一个新的租户,服务端会自动生成租户 ID 与 API Key。
**参数说明(请求体)**:
| 字段 | 类型 | 必填 | 说明 |
| ----------------- | ------ | ---- | ------------------------------------------------------ |
| name | string | 是 | 租户名称 |
| description | string | 否 | 租户描述 |
| business | string | 否 | 业务标识(如 `wechat`) |
| retriever_engines | object | 否 | 检索引擎组合配置(`engines` 数组:每项含 `retriever_type` 与 `retriever_engine_type`) |
| storage_quota | int | 否 | 存储配额(字节) |
**请求**:
```curl
curl --location 'http://localhost:8080/api/v1/tenants' \
--header 'Content-Type: application/json' \
--data '{
"name": "weknora",
"description": "weknora tenants",
"business": "wechat",
"retriever_engines": {
"engines": [
{
"retriever_type": "keywords",
"retriever_engine_type": "postgres"
},
{
"retriever_type": "vector",
"retriever_engine_type": "postgres"
}
]
}
}'
```
**响应**:
```json
{
"data": {
"id": 10000,
"name": "weknora",
"description": "weknora tenants",
"api_key": "sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG",
"status": "active",
"retriever_engines": {
"engines": [
{
"retriever_engine_type": "postgres",
"retriever_type": "keywords"
},
{
"retriever_engine_type": "postgres",
"retriever_type": "vector"
}
]
},
"business": "wechat",
"storage_quota": 10737418240,
"storage_used": 0,
"created_at": "2025-08-11T20:37:28.396980093+08:00",
"updated_at": "2025-08-11T20:37:28.396980301+08:00",
"deleted_at": null
},
"success": true
}
```
## GET `/tenants/:id` - 获取指定租户信息
获取指定 ID 的租户详情。只能访问自己所属租户;访问其他租户需要跨租户权限,否则返回 403。
**路径参数**:
| 字段 | 类型 | 说明 |
| ---- | ---- | ------- |
| id | int | 租户 ID |
**请求**:
```curl
curl --location 'http://localhost:8080/api/v1/tenants/10000' \
--header 'X-API-Key: sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG' \
--header 'Content-Type: application/json'
```
**响应**:
```json
{
"data": {
"id": 10000,
"name": "weknora",
"description": "weknora tenants",
"api_key": "sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG",
"status": "active",
"retriever_engines": {
"engines": [
{
"retriever_engine_type": "postgres",
"retriever_type": "keywords"
},
{
"retriever_engine_type": "postgres",
"retriever_type": "vector"
}
]
},
"business": "wechat",
"storage_quota": 10737418240,
"storage_used": 0,
"created_at": "2025-08-11T20:37:28.39698+08:00",
"updated_at": "2025-08-11T20:37:28.405693+08:00",
"deleted_at": null
},
"success": true
}
```
## PUT `/tenants/:id` - 更新租户信息
更新指定租户的基础信息。访问规则同 `GET /tenants/:id`。
**路径参数**:
| 字段 | 类型 | 说明 |
| ---- | ---- | ------- |
| id | int | 租户 ID |
**参数说明(请求体)**: 与 `POST /tenants` 相同字段;未传字段保持原值。
**请求**:
```curl
curl --location --request PUT 'http://localhost:8080/api/v1/tenants/10000' \
--header 'X-API-Key: sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG' \
--header 'Content-Type: application/json' \
--data '{
"name": "weknora new",
"description": "weknora tenants new",
"status": "active",
"retriever_engines": {
"engines": [
{
"retriever_engine_type": "postgres",
"retriever_type": "keywords"
},
{
"retriever_engine_type": "postgres",
"retriever_type": "vector"
}
]
},
"business": "wechat",
"storage_quota": 10737418240
}'
```
**响应**:
```json
{
"data": {
"id": 10000,
"name": "weknora new",
"description": "weknora tenants new",
"api_key": "sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG",
"status": "active",
"retriever_engines": {
"engines": [
{
"retriever_engine_type": "postgres",
"retriever_type": "keywords"
},
{
"retriever_engine_type": "postgres",
"retriever_type": "vector"
}
]
},
"business": "wechat",
"storage_quota": 10737418240,
"storage_used": 0,
"created_at": "2025-08-11T20:37:28.39698+08:00",
"updated_at": "2025-08-11T20:49:02.13421034+08:00",
"deleted_at": null
},
"success": true
}
```
## DELETE `/tenants/:id` - 删除租户
删除指定租户。访问规则同 `GET /tenants/:id`。
**路径参数**:
| 字段 | 类型 | 说明 |
| ---- | ---- | ------- |
| id | int | 租户 ID |
**请求**:
```curl
curl --location --request DELETE 'http://localhost:8080/api/v1/tenants/10000' \
--header 'X-API-Key: sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG' \
--header 'Content-Type: application/json'
```
**响应**:
```json
{
"message": "Tenant deleted successfully",
"success": true
}
```
## POST `/tenants/:id/api-key` - 重置租户 API Key
为指定租户生成新的 API Key,旧 Key 立即失效。访问规则同 `GET /tenants/:id`。
**路径参数**:
| 字段 | 类型 | 说明 |
| ---- | ---- | ------- |
| id | int | 租户 ID |
**请求**:
```curl
curl --location --request POST 'http://localhost:8080/api/v1/tenants/10000/api-key' \
--header 'X-API-Key: sk-aaLRAgvCRJcmtiL2vLMeB1FB5UV0Q-qB7DlTE1pJ9KA93XZG' \
--header 'Content-Type: application/json'
```
**响应**:
```json
{
"data": {
"api_key": "sk-IKtd9JGV4-aPGQ6RiL8YJu9Vzb3-ae4lgFkjFJZmhvUn2mLu"
},
"success": true
}
```
## GET `/tenants` - 获取租户列表
返回当前认证上下文对应的租户(普通用户为单条;管理员仍只返回自身租户)。
**请求**:
```curl
curl --location 'http://localhost:8080/api/v1/tenants' \
--header 'X-API-Key: sk-xxxxx' \
--header 'Content-Type: application/json'
```
**响应**:
```json
{
"data": {
"items": [
{
"id": 10002,
"name": "weknora",
"description": "weknora tenants",
"api_key": "sk-An7_t_izCKFIJ4iht9Xjcjnj_MC48ILvwezEDki9ScfIa7KA",
"status": "active",
"retriever_engines": {
"engines": [
{
"retriever_engine_type": "postgres",
"retriever_type": "keywords"
},
{
"retriever_engine_type": "postgres",
"retriever_type": "vector"
}
]
},
"business": "wechat",
"storage_quota": 10737418240,
"storage_used": 0,
"created_at": "2025-08-11T20:52:58.05679+08:00",
"updated_at": "2025-08-11T20:52:58.060495+08:00",
"deleted_at": null
}
]
},
"success": true
}
```
## GET `/tenants/kv/:key` - 获取租户 KV 配置
获取当前租户的 KV 配置项。**租户 ID 从认证上下文中获取**(即由 `X-API-Key` / Bearer Token 对应的租户决定),URL 中不需要也不接受 tenant_id。
**路径参数**:
| 字段 | 类型 | 说明 |
| ---- | ------ | ---------------------------------------------- |
| key | string | 配置键名(见下方支持的 key 列表,不支持的键返回 400) |
**支持的 key 值**:
| key | 说明 |
| ---------------------- | ----------------------------- |
| `agent-config` | Agent 配置(最大迭代次数、温度、System Prompt、可用工具等) |
| `web-search-config` | 网页搜索配置 |
| `conversation-config` | 普通模式会话/对话配置 |
| `prompt-templates` | 系统提示词模板(只读,按用户语言本地化) |
| `parser-engine-config` | 解析引擎配置(如 MinerU) |
| `storage-engine-config`| 存储引擎配置(Local/MinIO/COS) |
| `chat-history-config` | 聊天历史索引配置 |
| `retrieval-config` | 全局检索配置 |
**请求**:
```curl
curl --location 'http://localhost:8080/api/v1/tenants/kv/agent-config' \
--header 'X-API-Key: sk-xxxxx' \
--header 'Content-Type: application/json'
```
**响应(以 `agent-config` 为例)**:
```json
{
"data": {
"max_iterations": 10,
"allowed_tools": ["knowledge_search", "web_search"],
"temperature": 0.3,
"system_prompt": "...",
"use_custom_system_prompt": false,
"available_tools": [
{ "name": "knowledge_search", "label": "知识库检索", "description": "..." }
],
"available_placeholders": [
{ "name": "web_search_status", "label": "联网搜索状态", "description": "..." }
]
},
"success": true
}
```
失败时(不支持的键):
```json
{ "success": false, "error": "unsupported key" }
```
## PUT `/tenants/kv/:key` - 更新租户 KV 配置
更新当前租户的 KV 配置项。**租户 ID 从认证上下文中获取**,请求体结构按 `key` 不同而异。`prompt-templates` 为只读,不支持 PUT。
**路径参数**:
| 字段 | 类型 | 说明 |
| ---- | ------ | ----------------------------- |
| key | string | 配置键名(见 GET 接口的支持列表,`prompt-templates` 除外) |
**请求(以 `agent-config` 为例)**:
```curl
curl --location --request PUT 'http://localhost:8080/api/v1/tenants/kv/agent-config' \
--header 'X-API-Key: sk-xxxxx' \
--header 'Content-Type: application/json' \
--data '{
"max_iterations": 20,
"temperature": 0.3,
"system_prompt": ""
}'
```
**响应**:
```json
{
"data": {
"max_iterations": 20,
"allowed_tools": ["knowledge_search", "web_search"],
"temperature": 0.3,
"system_prompt": "",
"use_custom_system_prompt": false
},
"message": "Agent configuration updated successfully",
"success": true
}
```
**约束**:
- `agent-config`: `max_iterations` 取值范围 `(0, 30]`;`temperature` 取值范围 `[0, 2]`。
- `web-search-config`: `max_results` 取值范围 `[1, 50]`。
- `conversation-config`: 包含多项阈值校验(如 `keyword_threshold` / `vector_threshold` ∈ `[0, 1]`,`rerank_threshold` ∈ `[-10, 10]`,`temperature` ∈ `[0, 2]`,`max_completion_tokens` ∈ `[1, 100000]` 等)。
- `retrieval-config`: `embedding_top_k` / `rerank_top_k` ∈ `[0, 200]`;阈值范围同上。
- `storage-engine-config`: `default_provider` 必须在 `STORAGE_ALLOW_LIST` 允许的列表内。
- `chat-history-config`: 启用且设置了 `embedding_model_id` 而尚未关联知识库时,会自动创建一个隐藏知识库并将其 ID 写入配置。