1
0
forked from boos/BoosAPI

chore: initialize clean metapi repository

This commit is contained in:
cita
2026-02-28 00:36:28 +08:00
commit 2ecc23730d
199 changed files with 46078 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
# 📚 Metapi 文档中心
<div align="center">
**中转站的中转站 — 将分散的 AI 中转站聚合为一个统一网关**
[返回项目主页](../README.md)
</div>
---
## 快速导航
| 文档 | 适合谁 | 解决的问题 |
|------|--------|------------|
| 🚀 [快速上手](./getting-started.md) | 首次使用者 | 10 分钟完成部署与首次请求 |
| 🚢 [部署指南](./deployment.md) | 部署维护者 | Docker Compose、反向代理、升级回滚 |
| ⚙️ [配置说明](./configuration.md) | 管理员 | 全部环境变量、路由参数、通知渠道 |
| 🔌 [客户端接入](./client-integration.md) | 下游应用接入者 | Open WebUI、Cherry Studio、Cursor 等接入 |
| 🔧 [运维手册](./operations.md) | 运维人员 | 备份恢复、日志排查、健康检查 |
| ❓ [常见问题](./faq.md) | 所有用户 | 常见报错与修复路径 |
| 📁 [目录规范](./project-structure.md) | 开发者 | 项目目录组织与约定 |
## 架构概览
```text
┌──────────────────────────────────────────────────┐
│ 下游客户端 │
│ Open WebUI / Cherry Studio / Cursor / Claude │
│ Code / Roo Code / Kilo Code / ... │
└───────────────────┬──────────────────────────────┘
│ Authorization: Bearer <PROXY_TOKEN>
▼
┌──────────────────────────────────────────────────┐
│ Metapi 网关 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 统一代理 │ │ 智能路由 │ │ 格式转换 │ │
│ │ /v1/* │ │ 成本+余额 │ │ OpenAI⇄ │ │
│ │ │ │ +使用率 │ │ Claude │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 自动签到 │ │ 余额管理 │ │ 多渠道告警 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
└───────────────────┬──────────────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ New API │ │ One API │ │ Veloera │ ...
└─────────┘ └─────────┘ └─────────┘
```
## 核心概念
- **站点 (Site)**:一个上游中转站实例(如 New API、OneHub 等)
- **账号 (Account)**:在某站点上注册的用户账号
- **Token**:账号下的 API Key,用于访问该站点的 API
- **路由 (Route)**:一条模型匹配规则,如 `claude-sonnet-4-6`
- **通道 (Channel)**:路由下的一条 Token 链路,一个路由可有多个通道
- **代理 (Proxy)**:Metapi 对下游暴露的统一 API 入口
## 开源协作
- 📝 贡献流程:[CONTRIBUTING.md](../CONTRIBUTING.md)
- 🛡️ 安全策略:[SECURITY.md](../SECURITY.md)
- 📜 行为准则:[CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md)
+127
View File
@@ -0,0 +1,127 @@
# 🔌 客户端接入
本文档说明如何将下游客户端连接到 Metapi 代理网关。
[返回文档中心](./README.md)
---
## 通用配置
Metapi 暴露标准 OpenAI / Claude 兼容接口,下游客户端只需配置两项:
| 配置项 | 值 |
|--------|-----|
| **Base URL** | `https://your-domain.com`(不要拼接 `/v1`,客户端会自动加) |
| **API Key** | 你设置的 `PROXY_TOKEN` 值 |
模型列表自动从 `GET /v1/models` 获取,无需手动配置。
## 支持的接口
| 接口 | 方法 | 说明 |
|------|------|------|
| `/v1/chat/completions` | POST | OpenAI Chat Completions |
| `/v1/messages` | POST | Claude Messages |
| `/v1/completions` | POST | OpenAI Completions(Legacy) |
| `/v1/embeddings` | POST | 向量嵌入 |
| `/v1/images/generations` | POST | 图像生成 |
| `/v1/models` | GET | 模型列表 |
## 已验证兼容的客户端
### ChatGPT-Next-Web
| 配置项 | 值 |
|--------|-----|
| Settings → Custom Endpoint | `https://your-domain.com` |
| API Key | `PROXY_TOKEN` |
### Open WebUI
| 配置项 | 值 |
|--------|-----|
| Settings → Connections → OpenAI API URL | `https://your-domain.com/v1` |
| API Key | `PROXY_TOKEN` |
### Cherry Studio
| 配置项 | 值 |
|--------|-----|
| 模型提供商 → OpenAI → API 地址 | `https://your-domain.com` |
| API Key | `PROXY_TOKEN` |
### Cursor
| 配置项 | 值 |
|--------|-----|
| Settings → Models → OpenAI API Key | `PROXY_TOKEN` |
| Override OpenAI Base URL | `https://your-domain.com/v1` |
### Claude Code
```bash
export ANTHROPIC_BASE_URL=https://your-domain.com
export ANTHROPIC_API_KEY=your-proxy-sk-token
```
或在配置文件中设置相应的环境变量。
### Roo Code / Kilo Code
配置方式与 Cursor 类似,在设置中填入 Base URL 和 API Key。
### 其他客户端
所有支持 OpenAI API 格式的客户端均可接入,只需找到 Base URL 和 API Key 的配置位置即可。
## 快速自检
部署完成后,用以下命令验证链路:
```bash
# 1. 检查模型列表
curl -sS https://your-domain.com/v1/models \
-H "Authorization: Bearer <PROXY_TOKEN>" | head -50
# 2. 测试对话(非流式)
curl -sS https://your-domain.com/v1/chat/completions \
-H "Authorization: Bearer <PROXY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'
# 3. 测试流式
curl -sS https://your-domain.com/v1/chat/completions \
-H "Authorization: Bearer <PROXY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}],"stream":true}'
```
## 常见问题
### 流式响应异常
如果非流式正常但流式异常,原因几乎都是反向代理配置问题:
1. Nginx 未设置 `proxy_buffering off`
2. CDN 或中间层缓存了 SSE 响应
3. 中间层改写了 `text/event-stream` Content-Type
参考 [部署指南 → Nginx 配置](./deployment.md#nginx) 解决。
### 模型列表为空
- 检查是否已添加站点和账号
- 检查账号是否处于 `healthy` 状态
- 检查是否已同步 Token
- 在管理后台手动触发「刷新模型」
### 客户端提示 401 / 403
- 确认使用的是 `PROXY_TOKEN` 而非 `AUTH_TOKEN`
- 确认反向代理透传了 `Authorization` 请求头
## 下一步
- [配置说明](./configuration.md) — 环境变量详解
- [常见问题](./faq.md) — 更多故障排查
+137
View File
@@ -0,0 +1,137 @@
# ⚙️ 配置说明
本文档列出 Metapi 的全部环境变量配置。
[返回文档中心](./README.md)
---
## 必填配置
> ⚠️ 以下变量**必须修改**,不要使用默认值。
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `AUTH_TOKEN` | 管理后台登录令牌 | `change-me` |
| `PROXY_TOKEN` | 代理接口 Bearer Token(下游客户端使用此值作为 API Key) | `change-me-proxy` |
## 基础配置
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `PORT` | 服务监听端口 | `4000` |
| `DATA_DIR` | 数据目录(SQLite 数据库存储位置) | `./data` |
| `TZ` | 时区 | `Asia/Shanghai` |
| `ACCOUNT_CREDENTIAL_SECRET` | 账号凭证加密密钥(用于加密存储的上游账号密码) | 默认使用 `AUTH_TOKEN` |
## 定时任务
| 变量名 | 说明 | 默认值 | 示例 |
|--------|------|--------|------|
| `CHECKIN_CRON` | 自动签到计划 | `0 8 * * *` | 每天 8:00 |
| `BALANCE_REFRESH_CRON` | 余额刷新计划 | `0 * * * *` | 每小时整点 |
Cron 表达式格式:`分 时 日 月 周`(标准五段式)
常用示例:
- `0 8 * * *` — 每天 08:00
- `0 */2 * * *` — 每 2 小时
- `30 7,12,20 * * *` — 每天 07:30、12:30、20:30
## 智能路由
Metapi 的路由引擎按多因子加权选择最优通道。
### 成本信号优先级
```
实测成本(代理日志) → 账号配置成本 → 目录参考价 → 兜底默认值
```
### 路由权重参数
| 变量名 | 说明 | 默认值 | 范围 |
|--------|------|--------|------|
| `ROUTING_FALLBACK_UNIT_COST` | 无成本信号时的默认单价 | `1` | > 0 |
| `BASE_WEIGHT_FACTOR` | 基础权重因子 | `0.5` | 0~1 |
| `VALUE_SCORE_FACTOR` | 性价比评分因子 | `0.5` | 0~1 |
| `COST_WEIGHT` | 成本权重(越大越偏向低成本通道) | `0.4` | 0~1 |
| `BALANCE_WEIGHT` | 余额权重(越大越偏向余额充足的通道) | `0.3` | 0~1 |
| `USAGE_WEIGHT` | 使用率权重(越大越偏向使用较少的通道) | `0.3` | 0~1 |
> 三个权重之和建议为 1.0,但不强制。
### 路由预设建议
| 场景 | COST_WEIGHT | BALANCE_WEIGHT | USAGE_WEIGHT |
|------|:-----------:|:--------------:|:------------:|
| **成本优先** | 0.7 | 0.2 | 0.1 |
| **均衡(默认)** | 0.4 | 0.3 | 0.3 |
| **稳定优先** | 0.2 | 0.5 | 0.3 |
| **轮转均匀** | 0.1 | 0.1 | 0.8 |
## 安全配置
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `ADMIN_IP_ALLOWLIST` | 管理端 IP 白名单(逗号分隔) | 空(不限制) |
示例:`ADMIN_IP_ALLOWLIST=192.168.1.0/24,10.0.0.1`
## 通知渠道
### Webhook
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `WEBHOOK_ENABLED` | 启用 Webhook 通知 | `true` |
| `WEBHOOK_URL` | Webhook 推送地址 | 空 |
### Bark(iOS 推送)
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `BARK_ENABLED` | 启用 Bark 推送 | `true` |
| `BARK_URL` | Bark 推送地址 | 空 |
### Server酱
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `SERVERCHAN_ENABLED` | 启用 Server酱 通知 | `true` |
| `SERVERCHAN_KEY` | Server酱 SendKey | 空 |
### SMTP 邮件
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `SMTP_ENABLED` | 启用邮件通知 | `false` |
| `SMTP_HOST` | SMTP 服务器地址 | 空 |
| `SMTP_PORT` | SMTP 端口 | `587` |
| `SMTP_SECURE` | 使用 SSL/TLS | `false` |
| `SMTP_USER` | SMTP 用户名 | 空 |
| `SMTP_PASS` | SMTP 密码 | 空 |
| `SMTP_FROM` | 发件人地址 | 空 |
| `SMTP_TO` | 收件人地址 | 空 |
### 告警控制
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `NOTIFY_COOLDOWN_SEC` | 相同告警冷却时间(秒),防止同一事件重复通知 | `300` |
## 运行时配置
除环境变量外,以下参数可在管理后台「设置」页面中动态调整,无需重启:
- 路由权重参数
- 通知渠道地址
- SMTP 配置
- 告警冷却时间
运行时配置存储在 SQLite 数据库中,优先级高于环境变量默认值。
## 下一步
- [部署指南](./deployment.md) — Docker Compose 与反向代理
- [客户端接入](./client-integration.md) — 对接下游应用
+157
View File
@@ -0,0 +1,157 @@
# 🚢 部署指南
[返回文档中心](./README.md)
---
## Docker Compose 部署(推荐)
### 标准步骤
```bash
mkdir metapi && cd metapi
# 创建 docker-compose.yml(参见快速上手)
# 设置环境变量
export AUTH_TOKEN=your-admin-token
export PROXY_TOKEN=your-proxy-sk-token
# 启动
docker compose up -d
```
### 使用 `.env` 文件
如果不想每次 export,可以创建 `.env` 文件:
```bash
# .env
AUTH_TOKEN=your-admin-token
PROXY_TOKEN=your-proxy-sk-token
TZ=Asia/Shanghai
PORT=4000
```
```bash
docker compose --env-file .env up -d
```
> ⚠️ `.env` 文件包含敏感信息,请勿提交到 Git 仓库。
## Docker 命令部署
```bash
docker run -d --name metapi \
-p 4000:4000 \
-e AUTH_TOKEN=your-admin-token \
-e PROXY_TOKEN=your-proxy-sk-token \
-e TZ=Asia/Shanghai \
-v ./data:/app/data \
--restart unless-stopped \
1467078763/metapi:latest
```
> **路径说明:**
> - `./data:/app/data` — 相对路径,数据存到当前目录下的 `data` 文件夹
> - 也可以使用绝对路径:`/your/custom/path:/app/data`
## 反向代理
### Nginx
流式请求(SSE)需要关闭缓冲,否则流式输出会异常:
```nginx
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:4000;
# SSE 关键配置
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
# 标准代理头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置(长对话场景)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
```
### Caddy
```
your-domain.com {
reverse_proxy localhost:4000 {
flush_interval -1
}
}
```
## 升级
```bash
# 拉取最新镜像
docker compose pull
# 重新启动(数据不受影响)
docker compose up -d
# 清理旧镜像
docker image prune -f
```
## 回滚
如果升级后出现问题:
1. **升级前备份**(建议每次升级前执行):
```bash
cp -r data/ data-backup-$(date +%Y%m%d)/
```
2. **回滚到指定版本**:
```bash
# 修改 docker-compose.yml 中的 image tag
# 例如:image: 1467078763/metapi:v1.0.0
# 恢复数据
rm -rf data/
cp -r data-backup-20260228/ data/
# 重启
docker compose up -d
```
## 数据持久化
Metapi 的所有运行数据存储在 SQLite 数据库中,位于 `DATA_DIR`(默认 `./data`)目录下。
只要挂载了该目录,升级、重启都不会丢失数据。
### 备份策略建议
- 每日自动备份 `data/` 目录
- 保留最近 7~30 天的备份
- 重要操作前手动快照
## 下一步
- [配置说明](./configuration.md) — 详细环境变量
- [运维手册](./operations.md) — 日志排查、健康检查
+131
View File
@@ -0,0 +1,131 @@
# ❓ 常见问题(FAQ)
[返回文档中心](./README.md)
---
## 部署相关
### Q: 启动后无法访问管理后台
**A:** 排查步骤:
1. 确认容器正常运行:`docker compose ps`
2. 确认端口映射正确:`docker compose logs | grep listening`
3. 检查防火墙是否放行了端口(默认 4000)
4. 如果使用反向代理,确认代理配置正确
### Q: 登录失败,提示令牌无效
**A:** 检查 `AUTH_TOKEN` 是否与部署环境一致。注意:
- 使用 `.env` 文件时,确认文件路径正确
- 不要混用 `.env.example` 的默认值
- 环境变量中的值不需要加引号
### Q: Docker Compose 启动报错 `AUTH_TOKEN is required`
**A:** 使用了 `${AUTH_TOKEN:?}` 语法,需要先设置环境变量:
```bash
export AUTH_TOKEN=your-token
export PROXY_TOKEN=your-proxy-token
docker compose up -d
```
或使用 `.env` 文件。
---
## 代理相关
### Q: 下游客户端提示 401 / 403
**A:** 排查:
- 确认使用的是 `PROXY_TOKEN`(代理令牌),而非 `AUTH_TOKEN`(管理令牌)
- 确认反向代理正确透传了 `Authorization` 请求头
- 检查是否设置了 `ADMIN_IP_ALLOWLIST` 限制了访问
### Q: `GET /v1/models` 返回空列表
**A:** 可能原因:
1. 未添加任何站点或账号
2. 账号处于 `unhealthy` 状态 — 在账号管理页面检查并刷新
3. 未同步 Token — 在 Token 管理页面点击「同步」
4. 模型未发现 — 手动触发模型刷新
### Q: 非流式正常,但流式输出异常(卡住、乱码、截断)
**A:** 几乎都是反向代理配置问题。请确认:
1. Nginx:添加 `proxy_buffering off;`
2. 未改写 `text/event-stream` Content-Type
3. 无 CDN 或中间层缓存 SSE 响应
完整 Nginx 配置参考 [部署指南](./deployment.md#nginx)。
### Q: 某模型显示可用,但实际调用失败
**A:** 在管理后台的「模型测试器」中直测该模型,查看具体失败原因:
- **上游账号状态异常**:账号凭证过期或被禁用
- **通道处于冷却期**:近期该通道请求失败,系统自动冷却(默认 10 分钟)
- **上游模型下线**:上游站点已移除该模型
- **余额不足**:对应账号余额已耗尽
### Q: 请求延迟很高
**A:** 排查方向:
- 在代理日志中查看具体延迟分布
- 检查是否因冷却导致使用了较远/较慢的上游
- 调整路由权重,降低 `COST_WEIGHT`、提高成功率高的通道优先级
---
## 签到相关
### Q: 签到一直失败
**A:** 可能原因:
- 上游站点不支持签到功能
- 账号凭证已过期(系统会尝试自动重登录)
- 站点接口变更 — 检查 Metapi 是否为最新版本
### Q: 签到成功但奖励显示为 0
**A:** 部分站点的签到接口不返回奖励金额。Metapi 会尝试从收入日志推算奖励,但可能存在延迟。
---
## 数据相关
### Q: 数据迁移怎么做
**A:** 两种方式:
1. **应用内导入导出**(推荐):在管理后台 → 导入/导出 页面操作,支持选择性导出
2. **目录迁移**:直接拷贝 `data/` 目录到新环境
### Q: 如何清理历史数据
**A:** 代理日志和签到日志会持续增长。在管理后台对应页面可以清理历史记录。
### Q: 开源发布时如何避免泄露敏感信息
**A:**
- 确认 `.gitignore` 包含 `.env`、`data/`、`tmp/`
- 发布前执行一次密钥轮换(上游账号密码、通知 SMTP、Webhook 地址)
- 使用全新仓库或清理 Git 历史后再公开
- 检查备份 JSON 文件中是否包含凭证
---
## 更多帮助
- [提交 Issue](https://github.com/cita-777/metapi/issues) — 报告 Bug 或提出建议
- [文档中心](./README.md) — 查看所有文档
+124
View File
@@ -0,0 +1,124 @@
# 🚀 快速上手
本文档帮助你在 10 分钟内完成 Metapi 的首次部署。
[返回文档中心](./README.md)
---
## 前置条件
- Docker 与 Docker Compose(推荐)
- 或 Node.js 20+ 与 npm(本地开发)
## 方式一:Docker Compose 部署(推荐)
### 1. 创建项目目录
```bash
mkdir metapi && cd metapi
```
### 2. 创建 `docker-compose.yml`
```yaml
services:
metapi:
image: 1467078763/metapi:latest
ports:
- "4000:4000"
volumes:
- ./data:/app/data
environment:
AUTH_TOKEN: ${AUTH_TOKEN:?AUTH_TOKEN is required}
PROXY_TOKEN: ${PROXY_TOKEN:?PROXY_TOKEN is required}
CHECKIN_CRON: "0 8 * * *"
BALANCE_REFRESH_CRON: "0 * * * *"
PORT: ${PORT:-4000}
DATA_DIR: /app/data
TZ: ${TZ:-Asia/Shanghai}
restart: unless-stopped
```
### 3. 设置令牌并启动
```bash
export AUTH_TOKEN=your-admin-token
export PROXY_TOKEN=your-proxy-sk-token
docker compose up -d
```
### 4. 访问管理后台
打开 `http://localhost:4000`,使用 `AUTH_TOKEN` 的值登录。
## 方式二:本地开发启动
```bash
git clone https://github.com/cita-777/metapi.git
cd metapi
npm install
npm run db:migrate
npm run dev
```
- 前端地址:`http://localhost:5173`(Vite dev server)
- 后端地址:`http://localhost:4000`
## 首次使用流程
完成部署后,按以下顺序配置:
### 步骤 1:添加站点
进入 **站点管理**,添加你使用的上游中转站:
- 填写站点名称和 URL
- 选择平台类型(New API / One API / OneHub 等)
- 填写站点的管理员 API Key(可选,部分功能需要)
### 步骤 2:添加账号
进入 **账号管理**,为每个站点添加已注册的账号:
- 填入用户名和访问凭证
- 系统会自动登录并获取余额信息
- 启用自动签到(如站点支持)
### 步骤 3:同步 Token
进入 **Token 管理**:
- 点击「同步」从上游账号拉取 API Key
- 或手动添加已有的 API Key
### 步骤 4:检查路由
进入 **路由管理**:
- 系统会自动发现模型并生成路由规则
- 可以手动调整通道的优先级和权重
### 步骤 5:验证代理
使用 curl 快速验证:
```bash
# 检查模型列表
curl -sS http://localhost:4000/v1/models \
-H "Authorization: Bearer your-proxy-sk-token"
# 测试对话
curl -sS http://localhost:4000/v1/chat/completions \
-H "Authorization: Bearer your-proxy-sk-token" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'
```
返回正常响应,说明一切就绪。
## 下一步
- [部署指南](./deployment.md) — 反向代理、HTTPS、升级策略
- [配置说明](./configuration.md) — 详细环境变量与路由参数
- [客户端接入](./client-integration.md) — 对接 Open WebUI、Cherry Studio 等
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

+145
View File
@@ -0,0 +1,145 @@
# 🔧 运维手册
[返回文档中心](./README.md)
---
## 数据备份
### 方式一:目录备份(推荐)
Metapi 的所有数据存储在 `data/` 目录下的 SQLite 数据库中。最简单的备份方式:
```bash
# 手动备份
cp -r data/ data-backup-$(date +%Y%m%d)/
# 自动备份(crontab)
0 2 * * * cp -r /path/to/metapi/data/ /path/to/backups/metapi-$(date +\%Y\%m\%d)/
```
建议:
- 每日自动备份一次
- 保留最近 7~30 天
- 备份文件不要提交到 Git
### 方式二:应用内导出
在管理后台 → 「导入/导出」页面:
- **全量导出**:站点、账号、Token、路由、设置
- **仅账号**:站点和账号信息
- **仅偏好**:设置和通知配置
导出为 JSON 文件,可用于跨实例迁移。
## 数据恢复
### 目录恢复
```bash
# 1. 停止容器
docker compose down
# 2. 替换数据目录
rm -rf data/
cp -r data-backup-20260228/ data/
# 3. 重新启动
docker compose up -d
```
### 应用内导入
在管理后台 → 「导入/导出」页面上传之前导出的 JSON 文件。系统会自动校验数据完整性。
## 日志排查
### Docker 环境
```bash
# 查看实时日志
docker compose logs -f
# 查看最近 100 行
docker compose logs --tail 100
# 只看错误
docker compose logs -f 2>&1 | grep -i error
```
### 本地开发
```bash
npm run dev
# 日志直接输出到终端
```
### 重点关注的日志
| 关键词 | 含义 | 处理方式 |
|--------|------|----------|
| `auth failed` | 上游站点鉴权失败 | 检查账号凭证是否过期 |
| `no available channel` | 路由无可用通道 | 检查 Token 是否同步、通道是否被冷却 |
| `notify failed` | 通知发送失败 | 检查通知渠道配置 |
| `checkin failed` | 签到失败 | 检查账号状态和站点连通性 |
| `balance refresh failed` | 余额刷新失败 | 检查账号凭证 |
## 健康检查
### 手动检查
```bash
# 检查服务是否响应
curl -sS http://localhost:4000/v1/models \
-H "Authorization: Bearer <PROXY_TOKEN>" | head -5
# 检查特定模型可用性
curl -sS http://localhost:4000/v1/chat/completions \
-H "Authorization: Bearer <PROXY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"ping"}]}'
```
### 自动化监控建议
- 定时请求 `/v1/models`,检查返回状态码和模型数量
- 定时抽样请求 `/v1/chat/completions`,检查端到端可用性
- 监控磁盘空间(SQLite WAL 日志可能增长)
- 监控 Docker 容器状态
## 常见运维操作
### 清理代理日志
代理日志会持续增长。如果磁盘空间紧张,可在管理后台 → 代理日志页面清理历史记录。
### 重置账号状态
如果账号状态异常(`unhealthy`),可以在账号管理页面:
1. 点击「刷新」重新检测账号健康状态
2. 如凭证过期,系统会尝试自动重登录
3. 手动禁用/启用账号
### 强制刷新模型
在管理后台手动触发:
- 余额刷新:立即更新所有账号余额
- 模型刷新:重新发现所有上游模型
- 签到:立即执行一次签到
## 发布前检查清单
如果你在本地开发并准备发布:
- [ ] `npm test` 通过
- [ ] `npm run build` 通过
- [ ] `.env`、`data/`、`tmp/` 未提交到 Git
- [ ] 敏感凭证已从代码中移除
## 下一步
- [常见问题](./faq.md) — 常见报错与修复
- [配置说明](./configuration.md) — 环境变量详解
+148
View File
@@ -0,0 +1,148 @@
# Metapi 项目目录规范
本文档说明 Metapi 的目录组织方式,目标是让新功能落位更稳定、查找更直接、临时文件不污染根目录。
## 顶层目录
```text
metapi/
├── data/ # 运行时数据(SQLite 数据库)
├── dist/ # 构建产物(前后端)
├── docker/ # 容器相关文件
│ ├── Dockerfile # 多阶段构建(Alpine)
│ └── docker-compose.yml # Docker Compose 编排
├── docs/ # 文档与资源
│ ├── logos/ # Logo 素材
│ │ └── drafts/ # Logo 草稿
│ └── project-structure.md
├── drizzle/ # Drizzle ORM 迁移 SQL 与元数据
├── scripts/ # 项目脚本(按场景分组)
│ └── dev/
│ └── restart.bat # Windows 开发环境快捷重启
├── src/
│ ├── server/ # Fastify 后端服务
│ └── web/ # React 前端应用
├── tmp/ # 临时调试文件(已 gitignore)
├── package.json
├── tsconfig.json
├── tsconfig.server.json
├── vite.config.ts
└── README.md
```
## 后端目录约定(`src/server`)
```text
src/server/
├── index.ts # 服务启动入口
├── config.ts # 环境变量与配置加载
├── middleware/
│ └── auth.ts # 认证中间件
├── db/
│ ├── index.ts # 数据库连接
│ ├── schema.ts # Drizzle 表定义(全部 Schema)
│ └── migrate.ts # 迁移执行器
├── routes/
│ ├── api/ # 管理 API 路由
│ │ ├── auth.ts # 登录 / 登出
│ │ ├── sites.ts # 站点 CRUD
│ │ ├── accounts.ts # 账号管理
│ │ ├── accountTokens.ts # Token 同步与管理
│ │ ├── tokens.ts # Token 批量操作
│ │ ├── tokenRoutes.ts # 路由规则管理
│ │ ├── checkin.ts # 签到触发与日志
│ │ ├── stats.ts # 仪表盘统计
│ │ ├── search.ts # 全局搜索
│ │ ├── events.ts # 事件日志
│ │ ├── tasks.ts # 后台任务状态
│ │ ├── settings.ts # 运行时配置
│ │ ├── monitor.ts # 外部监控集成
│ │ └── test.ts # 测试 / 验证端点
│ └── proxy/ # 代理路由
│ ├── router.ts # 代理路由注册
│ ├── chat.ts # Chat Completions & Claude Messages
│ ├── completions.ts # Legacy Completions
│ ├── embeddings.ts # 向量嵌入
│ ├── images.ts # 图像生成
│ ├── models.ts # 模型列表
│ └── chatFormats.ts # OpenAI <-> Claude 格式转换
└── services/
├── platforms/ # 平台适配器
│ ├── base.ts # 适配器接口定义
│ ├── index.ts # 适配器注册表
│ ├── newApi.ts # New API 适配器
│ ├── oneApi.ts # One API 适配器
│ ├── oneHub.ts # OneHub 适配器
│ ├── doneHub.ts # DoneHub 适配器
│ ├── veloera.ts # Veloera 适配器
│ ├── anyrouter.ts # AnyRouter 适配器
│ └── sub2api.ts # Sub2API 适配器
├── tokenRouter.ts # 智能路由引擎
├── checkinService.ts # 签到执行
├── checkinScheduler.ts # 签到调度
├── checkinRewardParser.ts # 奖励金额解析
├── balanceService.ts # 余额刷新
├── modelService.ts # 模型发现与管理
├── modelPricingService.ts # 模型定价
├── modelAnalysisService.ts # 使用分析
├── notifyService.ts # 多渠道通知
├── notificationThrottle.ts # 通知节流
├── alertService.ts # 告警事件
├── alertRules.ts # 告警规则
├── backupService.ts # 数据导入导出
├── backgroundTaskService.ts # 后台任务管理
├── accountCredentialService.ts # 凭证加密
├── accountHealthService.ts # 健康状态管理
├── accountExtraConfig.ts # 平台专属配置
├── proxyRetryPolicy.ts # 重试策略
├── proxyUsageParser.ts # Token 用量解析
├── proxyUsageFallbackService.ts # 余额兜底估算
├── failureReasonService.ts # 错误分类
├── siteDetector.ts # 平台自动检测
├── dailySummaryService.ts # 每日摘要
├── todayIncomeRewardService.ts # 今日收入快照
├── localTimeService.ts # 时区处理
├── upstreamModelDescriptionService.ts # 上游模型描述缓存
├── startupInfo.ts # 启动信息
└── settings.ts # 运行时配置管理
```
## 前端目录约定(`src/web`)
```text
src/web/
├── App.tsx # 应用入口与路由配置
├── main.tsx # Vite 入口
├── api.ts # 统一 API 请求客户端
├── authSession.ts # 认证会话管理
├── i18n.tsx # 国际化
├── components/ # 通用 UI 组件
│ ├── BrandIcon.tsx # 模型品牌图标
│ ├── ModelAnalysisPanel.tsx # 消费分析图表
│ ├── SearchModal.tsx # 全局搜索弹窗
│ ├── NotificationPanel.tsx # 实时事件面板
│ ├── Toast.tsx # 通知提示
│ ├── SiteDistributionChart.tsx # 余额分布饼图
│ └── SiteTrendChart.tsx # 消费趋势图
├── pages/ # 页面组件(路由页)
│ ├── Dashboard.tsx # 仪表盘
│ ├── Sites.tsx # 站点管理
│ ├── Accounts.tsx # 账号管理
│ ├── Tokens.tsx # Token 管理
│ ├── TokenRoutes.tsx # 路由规则
│ ├── Models.tsx # 模型广场
│ ├── CheckinLog.tsx # 签到日志
│ ├── ProxyLogs.tsx # 代理日志
│ ├── Settings.tsx # 系统设置
│ ├── About.tsx # 关于页面
│ └── helpers/ # 页面级纯逻辑 / 工具函数(含测试)
└── public/ # 静态资源
```
## 目录卫生规则
- 所有调试临时文件放入 `tmp/`,不要散落在项目根目录。
- 开发脚本统一放入 `scripts/<scene>/`,根目录仅保留必要入口文件。
- 素材草稿统一归档到 `docs/logos/drafts/`,避免根目录堆积二进制文件。
- 测试文件与被测文件同目录(`*.test.ts`),方便就近维护。
- 平台适配器新增时,在 `services/platforms/` 中创建独立文件并注册到 `index.ts`。