mirror of
https://github.com/JetSprow/J-Board-Lite.git
synced 2026-05-01 01:14:10 +05:30
docs: improve deployment and agent guides
This commit is contained in:
53
AGENTS.md
53
AGENTS.md
@@ -3,3 +3,56 @@
|
|||||||
|
|
||||||
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
||||||
<!-- END:nextjs-agent-rules -->
|
<!-- END:nextjs-agent-rules -->
|
||||||
|
|
||||||
|
# Repository Notes For Coding Agents
|
||||||
|
|
||||||
|
This file is for agents working in this repository. Product, deployment, API, and operations documentation belongs in `README.md`, `docs/API.md`, and `agent/jboard-agent/README.md`.
|
||||||
|
|
||||||
|
## Project Shape
|
||||||
|
|
||||||
|
J-Board is a Next.js App Router application backed by Prisma/PostgreSQL and Redis. It integrates with 3x-ui rather than replacing it:
|
||||||
|
|
||||||
|
- J-Board owns users, orders, plans, subscriptions, payments, support, notifications, audit logs, settings, and risk review.
|
||||||
|
- 3x-ui owns actual inbound runtime configuration and Xray clients.
|
||||||
|
- `agent/jboard-agent` is a read-only sidecar for latency, route trace, and optional Xray access log telemetry.
|
||||||
|
|
||||||
|
Do not add a new node control plane or Xray process manager unless the user explicitly changes the product direction.
|
||||||
|
|
||||||
|
## Next.js Work
|
||||||
|
|
||||||
|
Before editing App Router files, route handlers, server actions, metadata, or caching behavior, read the relevant docs from `node_modules/next/dist/docs/` for the installed Next.js version.
|
||||||
|
|
||||||
|
Common areas to check:
|
||||||
|
|
||||||
|
- App Router file conventions.
|
||||||
|
- Route Handler request/response behavior.
|
||||||
|
- Server Actions and `use server` requirements.
|
||||||
|
- Caching, `revalidatePath`, and dynamic rendering rules.
|
||||||
|
|
||||||
|
## Version And Release Policy
|
||||||
|
|
||||||
|
Panel and Agent versions are not forced to move together.
|
||||||
|
|
||||||
|
- Website/admin/UI/docs/server-only changes can be committed and pushed to `main` without creating a GitHub Release.
|
||||||
|
- Only create a new Agent tag and GitHub Release when Agent code, Agent install/upgrade behavior, or Agent release artifacts change.
|
||||||
|
- Agent releases must include `jboard-agent-linux-amd64`, `jboard-agent-linux-arm64`, and `SHA256SUMS`.
|
||||||
|
- Agent runtime version is in `agent/jboard-agent/cmd/agent/main.go`.
|
||||||
|
- Agent build version is in `agent/jboard-agent/Makefile`.
|
||||||
|
- Panel package version is in `package.json` and does not need to match the Agent version.
|
||||||
|
|
||||||
|
## Documentation Policy
|
||||||
|
|
||||||
|
When changing behavior, update docs in the same change:
|
||||||
|
|
||||||
|
- User/deployment/admin docs: `README.md`.
|
||||||
|
- HTTP API and Server Actions: `docs/API.md` and, for public HTTP changes, `docs/openapi.yaml`.
|
||||||
|
- Agent install, runtime, logs, and release behavior: `agent/jboard-agent/README.md`.
|
||||||
|
- Agent-facing repository rules: this file.
|
||||||
|
|
||||||
|
Keep docs factual and operational. Avoid promising features that are not implemented.
|
||||||
|
|
||||||
|
## Risk And Privacy Notes
|
||||||
|
|
||||||
|
Subscription risk and node access telemetry contain sensitive evidence: user IPs, locations, Xray client email, target hosts, timestamps, and admin review decisions. Treat these as sensitive data in logs, docs, screenshots, and tests.
|
||||||
|
|
||||||
|
Agent Xray log telemetry must remain read-only. It may read access logs and post aggregates to J-Board; it must not mutate 3x-ui or Xray runtime configuration.
|
||||||
|
|||||||
525
README.md
525
README.md
@@ -1,176 +1,156 @@
|
|||||||
# J-Board
|
# J-Board
|
||||||
|
|
||||||
J-Board(也称 JB面板)是一个面向代理订阅售卖与流媒体共享的全栈应用。节点运行、入站和客户端配置由 3x-ui 面板维护;J-Board 负责售卖、订单、订阅、用户、支付、工单和探测展示;自带 Go 程序只做延迟与线路探测上报。
|
J-Board(也称 JB 面板)是一个面向代理订阅售卖与流媒体共享的全栈管理面板。它负责用户、套餐、订单、支付、订阅、工单、邮件、公告、审计、探测展示与订阅风控;节点实际运行、入站协议、Xray 客户端配置仍由 3x-ui 维护。
|
||||||
|
|
||||||
## 架构
|
J-Board 的定位很明确:它不是新的节点控制面,也不替代 3x-ui。它把售卖、开通、订阅交付、售后和风险审查做成一个完整面板,并通过只读 Agent 从节点侧采集延迟、路由和 Xray access log 证据。
|
||||||
|
|
||||||
|
## 快速认识
|
||||||
|
|
||||||
```text
|
```text
|
||||||
用户浏览器
|
用户浏览器 / 客户端订阅
|
||||||
↓
|
↓
|
||||||
Next.js App Router 面板
|
Next.js App Router 面板
|
||||||
├─ PostgreSQL / Redis
|
├─ PostgreSQL:用户、订单、套餐、订阅、审计、风控事件
|
||||||
├─ 3x-ui API:同步入站、开通/暂停/删除客户端
|
├─ Redis:限流、后台任务与缓存辅助
|
||||||
└─ Probe API:接收 jboard-agent 的延迟与路由上报
|
├─ 3x-ui API:同步入站、开通/暂停/删除代理客户端
|
||||||
|
└─ Agent API:接收 jboard-agent 上报的延迟、路由、节点真实连接日志
|
||||||
|
|
||||||
|
节点 VPS
|
||||||
|
├─ 3x-ui / Xray:真实入站、客户端、流量限制与代理运行
|
||||||
|
└─ jboard-agent:旁路只读探测与日志聚合,不修改 3x-ui 配置
|
||||||
```
|
```
|
||||||
|
|
||||||
J-Board 只保存售卖和展示所需的节点、入站、客户端镜像数据,不下发 Xray/Hy2 配置,也不维护自建节点控制面。
|
J-Board 只保存售卖和展示需要的节点镜像数据。入站协议、端口、Reality/TLS、Xray 运行状态和客户端真实配置仍以 3x-ui 为准。
|
||||||
|
|
||||||
## 功能
|
## 功能概览
|
||||||
|
|
||||||
用户端:
|
用户端:
|
||||||
|
|
||||||
- 注册、登录、Cloudflare Turnstile 人机验证
|
- 注册、登录、邮箱验证、忘记密码、邮箱变更验证。
|
||||||
- 代理套餐与流媒体套餐购买、续费、增流量
|
- 支持 Cloudflare Turnstile 人机验证。
|
||||||
- 线路体验:三网延迟、延迟历史、三网路由追踪详情
|
- 代理套餐和流媒体套餐购买、续费、增流量。
|
||||||
- 代理订阅查看、订阅链接下载、订阅访问重置
|
- 购物车、订单、支付状态查询和支付方式切换。
|
||||||
- 流媒体订阅查看与凭据展示
|
- 代理订阅查看、订阅链接下载、订阅访问重置。
|
||||||
- 通知中心、工单售后、账号资料、邀请码
|
- 线路体验展示:三网延迟、延迟历史、三网路由追踪。
|
||||||
- 响应式移动端适配
|
- 流媒体订阅凭据展示。
|
||||||
|
- 通知中心、工单售后、账号资料、邀请码。
|
||||||
|
- 暗色/夜间模式和移动端适配。
|
||||||
|
|
||||||
管理端:
|
管理端:
|
||||||
|
|
||||||
- 3x-ui 节点管理:保存面板地址、账号、密码,测试连接并同步入站
|
- 3x-ui 节点管理:保存面板地址、账号、密码,测试连接并同步入站。
|
||||||
- 本地入站展示名称维护,套餐绑定同步后的入站线路
|
- 本地入站展示名维护,套餐绑定同步后的入站线路。
|
||||||
- 探测 Token 管理:仅用于 `/api/agent/latency` 与 `/api/agent/trace`
|
- 探测 Token 管理:用于 Agent 上报延迟、路由和节点日志。
|
||||||
- 用户、订单、套餐、订阅、流媒体服务、支付配置
|
- 用户、订单、套餐、订阅、流媒体服务、支付配置。
|
||||||
- 公告、工单、系统设置、审计日志、任务中心、备份恢复
|
- SMTP 邮件服务设置、注册邮箱验证开关、邮件模板发送。
|
||||||
- 流量视图:基于本地订阅与 3x-ui 同步结果展示客户端用量
|
- 公告、工单、系统设置、审计日志、任务中心、备份恢复。
|
||||||
|
- 支持工单上限配置,默认每个用户最多开启 2 个未关闭工单。
|
||||||
|
- 流量视图:基于本地订阅与 3x-ui 同步结果展示客户端用量。
|
||||||
|
- 订阅访问风控:IP、城市、省/地区、国家变化审查。
|
||||||
|
- 节点日志风控:基于 Xray access log 分析真实来源 IP、连接数、不同目标数。
|
||||||
|
- 风控人工处理:查看用户、订阅、地图、IP、分析日志,生成风险报告,选择解除限制或保持封禁/暂停。
|
||||||
|
|
||||||
节点侧:
|
节点侧:
|
||||||
|
|
||||||
- 3x-ui 负责入站、客户端、协议配置和节点运行
|
- 3x-ui 负责入站、客户端、协议配置和节点运行。
|
||||||
- J-Board 通过 3x-ui API 同步入站并执行客户端增删改
|
- J-Board 通过 3x-ui API 同步入站并执行客户端增删改。
|
||||||
- `agent/jboard-agent` 只负责三网 TCP 延迟和三网路由追踪
|
- `agent/jboard-agent` 负责三网 TCP 延迟、三网路由追踪和可选 Xray access log 风控上报。
|
||||||
|
- Agent 只读日志文件,不重启 Xray,不修改 3x-ui 配置。
|
||||||
|
|
||||||
## 核心流程
|
## 版本与发布规则
|
||||||
|
|
||||||
节点接入:
|
J-Board 面板和 Agent 使用相对独立的版本节奏。
|
||||||
|
|
||||||
1. 管理员在 3x-ui 中创建真实入站。
|
- 面板代码变更可以只提交到 `main`,不一定创建 GitHub Release。
|
||||||
2. 管理员在 J-Board 添加节点并填写 3x-ui 面板地址、用户名、密码。
|
- Agent 二进制发生变化时,才需要升级 Agent 版本、打 tag、创建 Release,并上传 `jboard-agent-linux-amd64`、`jboard-agent-linux-arm64`、`SHA256SUMS`。
|
||||||
3. J-Board 登录 3x-ui,读取入站列表并写入 `NodeInbound`。
|
- Agent 安装/升级脚本默认下载 GitHub 最新 Release 中的 Agent 产物。
|
||||||
4. 管理员将套餐绑定到已同步入站。
|
- 不要为了普通网站页面或后台文案改动强行更新 Agent tag。
|
||||||
5. 用户购买代理套餐后,J-Board 调用 3x-ui API 创建客户端,并保存 `NodeClient`。
|
|
||||||
6. 订阅暂停、恢复、删除、重置访问时,同步调用 3x-ui API 更新客户端。
|
|
||||||
|
|
||||||
支付开通:
|
当前项目版本写在 `package.json`,Agent 运行时版本写在 `agent/jboard-agent/cmd/agent/main.go`,Agent 构建版本写在 `agent/jboard-agent/Makefile`。
|
||||||
|
|
||||||
1. 用户选择套餐、入站和流量规格并创建订单。
|
|
||||||
2. 支付平台回调后,`src/services/payment/process.ts` 标记订单已支付。
|
|
||||||
3. `src/services/provision.ts` 创建或更新 `UserSubscription`。
|
|
||||||
4. 代理订阅通过 `src/services/node-panel` 调用 3x-ui 创建或更新客户端。
|
|
||||||
5. 流媒体订阅分配 `StreamingSlot`。
|
|
||||||
|
|
||||||
探测上报:
|
|
||||||
|
|
||||||
1. 管理员为节点生成探测 Token。
|
|
||||||
2. 节点运行 `agent/jboard-agent`,配置 `SERVER_URL` 和 `AUTH_TOKEN`。
|
|
||||||
3. 探测程序定时调用 `POST /api/agent/latency` 和 `POST /api/agent/trace`。
|
|
||||||
4. J-Board 按 Token 匹配节点并更新延迟、历史和路由数据。
|
|
||||||
|
|
||||||
## 技术栈
|
## 技术栈
|
||||||
|
|
||||||
- Next.js 16 App Router + React 19
|
- Next.js 16 App Router + React 19
|
||||||
- Prisma 7 + PostgreSQL 16
|
- Prisma 7 + PostgreSQL 16
|
||||||
- NextAuth 4 Credentials + Cloudflare Turnstile
|
- NextAuth 4 Credentials
|
||||||
- Redis 7
|
- Redis 7
|
||||||
- Tailwind CSS 4 + Base UI + Sonner + Recharts
|
- Tailwind CSS 4 + Base UI + Sonner + Recharts
|
||||||
- Go probe agent
|
- Nodemailer SMTP 邮件
|
||||||
|
- MaxMind MMDB GeoIP
|
||||||
|
- Go jboard-agent
|
||||||
- Docker / Docker Compose
|
- Docker / Docker Compose
|
||||||
|
|
||||||
## 目录
|
注意:本项目使用的 Next.js 版本包含和旧版本不同的约定。开发前请阅读 `AGENTS.md`,并按 `node_modules/next/dist/docs/` 中的当前文档实现。
|
||||||
|
|
||||||
- `src/app`:页面、布局、Route Handlers
|
## 目录结构
|
||||||
- `src/actions`:Server Actions,负责写操作、权限校验、审计和缓存刷新
|
|
||||||
- `src/services`:领域服务与第三方适配
|
| 路径 | 说明 |
|
||||||
- `src/services/node-panel`:3x-ui 面板适配层
|
| --- | --- |
|
||||||
- `src/services/provision.ts`:支付成功后的订阅开通与 3x-ui 客户端同步
|
| `src/app` | 页面、布局、Route Handlers。 |
|
||||||
- `src/services/subscription.ts`:订阅内容生成
|
| `src/actions` | Server Actions,负责写操作、权限校验、审计和缓存刷新。 |
|
||||||
- `src/lib`:Prisma、鉴权、加密、Turnstile、通用工具
|
| `src/services` | 领域服务与第三方适配。 |
|
||||||
- `prisma/schema.prisma`:数据模型事实源
|
| `src/services/node-panel` | 3x-ui 面板适配层。 |
|
||||||
- `agent/jboard-agent`:延迟与线路探测程序
|
| `src/services/provision.ts` | 支付成功后的订阅开通与 3x-ui 客户端同步。 |
|
||||||
- `docs/API.md`:HTTP 接口与 Server Actions 参考
|
| `src/services/subscription-risk.ts` | 订阅访问与节点日志风控判定。 |
|
||||||
- `docs/openapi.yaml`:对外 HTTP 接口的 OpenAPI 描述
|
| `src/services/subscription-risk-review.ts` | 风控事件证据整理、报告生成辅助。 |
|
||||||
|
| `src/lib` | Prisma、鉴权、加密、Turnstile、GeoIP、工具函数。 |
|
||||||
|
| `prisma/schema.prisma` | 数据模型事实源。 |
|
||||||
|
| `data/GeoLite2-City.mmdb` | 默认 GeoIP 城市库。 |
|
||||||
|
| `agent/jboard-agent` | Go Agent 源码、构建脚本和 Agent 文档。 |
|
||||||
|
| `scripts/install-jboard-panel.sh` | 面板一键安装向导。 |
|
||||||
|
| `scripts/upgrade-jboard-panel.sh` | 面板升级脚本。 |
|
||||||
|
| `scripts/install-jboard-agent.sh` | Agent 安装脚本。 |
|
||||||
|
| `scripts/upgrade-jboard-agent.sh` | Agent 升级脚本。 |
|
||||||
|
| `docs/API.md` | HTTP 接口与 Server Actions 参考。 |
|
||||||
|
| `docs/openapi.yaml` | 对外 HTTP 接口 OpenAPI 描述。 |
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
以 `.env.example` 为准。生产部署推荐直接使用一键脚本生成 `.env`,手动配置时请重点确认这些值:
|
以 `.env.example` 为准。生产部署推荐使用一键脚本生成 `.env`,手动配置时重点确认下列变量。
|
||||||
|
|
||||||
| 变量 | 用途 | 说明 |
|
| 变量 | 用途 | 说明 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `APP_PORT` | 面板监听端口 | 默认 `3000`。反向代理应转发到 `http://127.0.0.1:APP_PORT`。 |
|
| `APP_PORT` | 面板监听端口 | 默认 `3000`。反向代理应转发到 `http://127.0.0.1:APP_PORT`。 |
|
||||||
| `SITE_NAME` | 站点名称 | 初始化系统设置和邮件模板会使用。 |
|
| `SITE_NAME` | 站点名称 | 初始化系统设置和邮件模板会使用。 |
|
||||||
| `NEXTAUTH_URL` | 网站访问地址 | 必须填写你准备反代到面板的正式域名,例如 `https://panel.example.com`。不要填容器内地址。 |
|
| `NEXTAUTH_URL` | 网站访问地址 | 必须填写准备反代到面板的正式域名,例如 `https://panel.example.com`。不要填 `localhost`、容器名或内网地址。 |
|
||||||
| `SUBSCRIPTION_URL` | 订阅访问地址 | 可选。用于生成客户端订阅链接,例如 `https://sub.example.com`;留空时复用 `NEXTAUTH_URL`。如果使用独立订阅域名,也要反代到同一个面板服务。 |
|
| `SUBSCRIPTION_URL` | 订阅访问地址 | 可选。用于生成客户端订阅链接,例如 `https://sub.example.com`;留空时复用 `NEXTAUTH_URL`。 |
|
||||||
| `NEXTAUTH_SECRET` | 登录会话密钥 | 生产环境必须使用随机长字符串。 |
|
| `NEXTAUTH_SECRET` | 登录会话密钥 | 生产环境必须使用随机长字符串。 |
|
||||||
| `ENCRYPTION_KEY` | 敏感信息加密密钥 | 至少 32 字节。生产使用后不要更换,否则 3x-ui 密码、探测 Token、流媒体凭据等已加密数据会无法解密。 |
|
| `ENCRYPTION_KEY` | 敏感信息加密密钥 | 至少 32 字节。生产使用后不要更换,否则 3x-ui 密码、探测 Token、SMTP 密码、流媒体凭据等已加密数据会无法解密。 |
|
||||||
| `DATABASE_URL` | PostgreSQL 连接 | 本地工具使用;Docker 部署时 Compose 会覆盖为容器内数据库地址。 |
|
| `DATABASE_URL` | PostgreSQL 连接 | 本地工具使用;Docker 部署时 Compose 会覆盖为容器内数据库地址。 |
|
||||||
| `POSTGRES_PASSWORD` | Docker PostgreSQL 密码 | 一键脚本会自动生成。 |
|
| `POSTGRES_PASSWORD` | Docker PostgreSQL 密码 | 一键脚本会自动生成。 |
|
||||||
| `REDIS_URL` | Redis 连接 | 本地工具使用;Docker 部署时 Compose 会覆盖为容器内 Redis 地址。 |
|
| `REDIS_URL` | Redis 连接 | 本地工具使用;Docker 部署时 Compose 会覆盖为容器内 Redis 地址。 |
|
||||||
|
| `GEOIP_MMDB_PATH` | GeoIP 城市库 | 默认 `data/GeoLite2-City.mmdb`。可换成自己的 MaxMind City MMDB。 |
|
||||||
| `ADMIN_EMAIL` / `ADMIN_PASSWORD` / `ADMIN_NAME` | 初始管理员 | 首次 `db:seed` 创建管理员账号。已有数据库不会强制重置旧管理员密码。 |
|
| `ADMIN_EMAIL` / `ADMIN_PASSWORD` / `ADMIN_NAME` | 初始管理员 | 首次 `db:seed` 创建管理员账号。已有数据库不会强制重置旧管理员密码。 |
|
||||||
|
|
||||||
SMTP 邮件服务、注册邮箱验证开关、支付方式、3x-ui 节点等业务配置都在管理后台填写,不建议写进 `.env`。
|
SMTP 邮件服务、注册邮箱验证开关、支付方式、3x-ui 节点等业务配置在管理后台填写,不建议写进 `.env`。
|
||||||
|
|
||||||
## 本地开发
|
## 一键部署
|
||||||
|
|
||||||
|
适合全新 Linux 服务器。脚本会安装基础依赖、安装 Docker 与 Compose 插件、拉取代码、生成 `.env`、初始化数据库并启动面板。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
bash <(curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/install-jboard-panel.sh)
|
||||||
cp .env.example .env
|
|
||||||
npm run db:push
|
|
||||||
npm run db:seed
|
|
||||||
npm run dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
默认管理员账号:
|
脚本会交互询问:
|
||||||
|
|
||||||
- 邮箱:`admin@jboard.local`
|
| 问题 | 如何填写 |
|
||||||
- 密码:`admin123`
|
|
||||||
|
|
||||||
常用检查:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx prisma generate
|
|
||||||
npx tsc --noEmit
|
|
||||||
npm run lint
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
数据库变更:
|
|
||||||
|
|
||||||
- 修改 `prisma/schema.prisma` 后运行 `npx prisma generate`
|
|
||||||
- 使用 `npm run db:push` 同步 schema 到数据库
|
|
||||||
- 不维护 Prisma migrations,不提交迁移脚本
|
|
||||||
- 删除字段或模型时同步清理引用、文档和导出逻辑
|
|
||||||
|
|
||||||
## 部署
|
|
||||||
|
|
||||||
### 一键部署(推荐)
|
|
||||||
|
|
||||||
适合全新的 Linux 服务器。脚本会自动安装 Docker 与 Compose 插件,拉取代码,询问并生成 `.env`,初始化数据库,启动面板,最后输出访问地址、反代目标和管理员账号。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/install-jboard-panel.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
脚本会询问这些信息;直接回车即可使用默认值或自动生成值:
|
|
||||||
|
|
||||||
| 提示项 | 含义 |
|
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 安装目录 | 默认 `/opt/jboard`;如果在仓库内运行脚本则默认当前仓库。 |
|
| 安装目录 | 默认 `/opt/jboard`;如果在仓库内运行脚本则默认当前仓库。 |
|
||||||
| 站点名称 | 面板标题、邮件模板和初始化系统设置会使用。 |
|
| 站点名称 | 面板标题、邮件模板和初始化系统设置会使用。 |
|
||||||
| 网站访问地址 | 你准备反向代理到本机 `3000` 端口的面板域名,例如 `https://panel.example.com`。没有域名时可先用 `http://服务器IP:3000` 测试。 |
|
| 网站访问地址 | 你准备反向代理到本机 `3000` 端口的面板域名,例如 `https://panel.example.com`。没有域名时可先用 `http://服务器IP:3000` 测试。 |
|
||||||
| 订阅访问地址 | 用于生成 Clash/V2rayN/Shadowrocket 等客户端订阅链接。可与网站访问地址相同,也可填独立订阅域名,例如 `https://sub.example.com`。 |
|
| 订阅访问地址 | 用于生成 Clash/V2rayN/Shadowrocket 等客户端订阅链接。可以和网站地址相同,也可以填独立订阅域名,例如 `https://sub.example.com`。 |
|
||||||
| 本机监听端口 | 默认 `3000`,Nginx/Caddy/宝塔反代目标就是 `http://127.0.0.1:3000`。 |
|
| 本机监听端口 | 默认 `3000`。Nginx、Caddy、宝塔或 1Panel 的反代目标就是 `http://127.0.0.1:3000`。 |
|
||||||
| 管理员邮箱和密码 | 首次初始化会创建该管理员,脚本完成后会再次打印。 |
|
| 管理员邮箱和密码 | 首次初始化会创建该管理员,脚本完成后会再次打印。 |
|
||||||
| PostgreSQL 密码、`NEXTAUTH_SECRET`、`ENCRYPTION_KEY` | 可手动输入;回车会自动生成安全值。 |
|
| PostgreSQL 密码、`NEXTAUTH_SECRET`、`ENCRYPTION_KEY` | 可手动输入;回车会自动生成安全值。 |
|
||||||
|
|
||||||
也可以用环境变量覆盖默认行为:
|
也可以通过环境变量覆盖默认行为:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
APP_DIR=/opt/jboard GH_REPO=JetSprow/J-Board BRANCH=main bash <(curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/install-jboard-panel.sh)
|
APP_DIR=/opt/jboard GH_REPO=JetSprow/J-Board BRANCH=main bash <(curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/install-jboard-panel.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本完成后,你会看到类似信息:
|
脚本完成后会输出:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
访问地址:https://panel.example.com
|
访问地址:https://panel.example.com
|
||||||
@@ -180,39 +160,9 @@ APP_DIR=/opt/jboard GH_REPO=JetSprow/J-Board BRANCH=main bash <(curl -fsSL https
|
|||||||
管理员密码:自动生成或你输入的密码
|
管理员密码:自动生成或你输入的密码
|
||||||
```
|
```
|
||||||
|
|
||||||
### 反向代理
|
请把管理员密码保存到密码管理器。已有数据库重复部署时,脚本会尽量沿用现有配置,不会随意重置管理员。
|
||||||
|
|
||||||
`NEXTAUTH_URL` 和后台“系统设置 -> 网站 URL”都应该填写面板公网域名,也就是你准备给用户访问、并反向代理到 J-Board 的域名。不要填写 `localhost`、容器名或内网地址。
|
## 手动 Docker 部署
|
||||||
|
|
||||||
`SUBSCRIPTION_URL` 和后台“系统设置 -> 订阅 URL”只用于生成客户端订阅链接。它可以和网站 URL 相同;如果你想单独做 Cloudflare/WAF/访问风控,建议使用 `https://sub.example.com` 这类独立域名,并把它也反向代理到同一个 J-Board 服务。独立订阅域名只需要承载 `/api/subscription/*`,后续可以在反代或 WAF 层对其他路径返回 404。
|
|
||||||
|
|
||||||
Nginx 示例:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name panel.example.com sub.example.com;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:3000;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
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_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
正式上线建议再用 Certbot、宝塔、1Panel、Caddy 或 CDN 申请 HTTPS 证书,然后把 `NEXTAUTH_URL` 改为 `https://panel.example.com`。如果单独使用订阅域名,把 `SUBSCRIPTION_URL` 或后台订阅 URL 改为 `https://sub.example.com`。
|
|
||||||
|
|
||||||
订阅域名套 Cloudflare 时,源站应只允许 Cloudflare 回源或通过 Cloudflare Tunnel 暴露服务,并正确传递 `CF-Connecting-IP` / `X-Forwarded-For`。否则后续订阅访问风控中的真实 IP 可能被直连源站请求伪造。
|
|
||||||
|
|
||||||
J-Board 会记录订阅 API 的真实 IP、User-Agent 和可用的地理位置头,并按后台“系统设置 -> 订阅访问风控”配置执行限流、跨城市/省份告警与自动暂停。默认规则保持为:24 小时内 4 个城市警告、5 个城市暂停;2 个省/地区警告、3 个省/地区暂停;2 个国家/地区警告、3 个国家/地区暂停;IP 180 次/小时、订阅 60 次/小时。管理员可以关闭风控总控,或关闭自动暂停改为只记录警告;也可以在后台“订阅风控”查看关联用户、订阅、IP、地区统计,并将事件标记为待处理、已确认或已解决,必要时可人工恢复被暂停的订阅。项目内置 `data/GeoLite2-City.mmdb` 作为本地 GeoIP 城市库,默认通过 `GEOIP_MMDB_PATH=data/GeoLite2-City.mmdb` 读取;如果反代或 CDN 已传地理位置头,系统优先使用请求头,并用 MMDB 补齐缺失字段。Cloudflare 场景建议在 Rules -> Settings -> Managed Transforms 开启 Add visitor location headers,让回源请求带上 `cf-ipcity`、`cf-region`、`cf-region-code` 等字段;未提供城市/省份字段且 MMDB 不可用时,系统只记录 IP,不会触发地区变化规则。
|
|
||||||
|
|
||||||
### 手动 Docker 部署
|
|
||||||
|
|
||||||
首次启动:
|
首次启动:
|
||||||
|
|
||||||
@@ -241,21 +191,53 @@ docker compose up -d app
|
|||||||
|
|
||||||
常用排障:
|
常用排障:
|
||||||
|
|
||||||
- 查看状态:`docker compose ps`
|
```bash
|
||||||
- 查看日志:`docker compose logs -f app`
|
docker compose ps
|
||||||
- 页面仍是旧版本:确认已执行 `docker compose build init app` 和 `docker compose up -d app`
|
docker compose logs -f app
|
||||||
- Schema 没有生效:单独运行 `docker compose --profile setup run --rm init sh -lc 'npm run db:push'`
|
docker compose --profile setup run --rm init sh -lc 'npm run db:push'
|
||||||
- 登录回调、邮件链接或支付回跳出现 `localhost`:检查 `.env` 里的 `NEXTAUTH_URL` 和后台系统设置里的网站 URL。
|
```
|
||||||
- 订阅链接仍然使用主站域名:检查 `.env` 里的 `SUBSCRIPTION_URL` 或后台系统设置里的订阅 URL;后台配置优先于环境变量。
|
|
||||||
|
|
||||||
### 部署后检查清单
|
如果页面仍是旧版本,确认已执行 `docker compose build init app` 和 `docker compose up -d app`。如果 schema 没生效,单独运行 `npm run db:push` 对应的 setup 命令。
|
||||||
|
|
||||||
1. 登录 `/admin`,进入“系统设置”,确认网站 URL 是面板反代域名,订阅 URL 是你准备给客户端拉取订阅的域名。
|
## 反向代理与域名
|
||||||
2. 配置 SMTP 邮件服务并点击“测试”,再按需要开启注册邮箱验证。
|
|
||||||
3. 进入“支付配置”,填写并启用至少一种支付方式。
|
`NEXTAUTH_URL` 和后台“系统设置 -> 网站 URL”都应该填写面板公网域名,也就是给用户访问、并反向代理到 J-Board 的域名。不要填写 `localhost`、容器名或内网地址,否则登录回调、邮件链接、支付回跳和退出登录提示可能出现错误地址。
|
||||||
4. 添加 3x-ui 节点,测试连接并同步入站。
|
|
||||||
5. 创建套餐,绑定入站或流媒体服务。
|
`SUBSCRIPTION_URL` 和后台“系统设置 -> 订阅 URL”只用于生成客户端订阅链接。它可以和网站 URL 相同;如果希望单独做 Cloudflare/WAF/访问风控,建议使用独立订阅域名,例如 `https://sub.example.com`,并把它也反向代理到同一个 J-Board 服务。
|
||||||
6. 用普通用户注册、下单、支付、查看订阅,走一遍完整流程。
|
|
||||||
|
Nginx 示例:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name panel.example.com sub.example.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
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_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
正式上线建议使用 Certbot、宝塔、1Panel、Caddy 或 CDN 配置 HTTPS。订阅域名套 Cloudflare 时,源站建议只允许 Cloudflare 回源或通过 Cloudflare Tunnel 暴露,并正确传递 `CF-Connecting-IP` / `X-Forwarded-For`。如果源站允许绕过 Cloudflare 直连,订阅访问风控中的真实 IP 可能被伪造。
|
||||||
|
|
||||||
|
## 后台初始化清单
|
||||||
|
|
||||||
|
1. 登录 `/admin`,进入“系统设置”,确认网站 URL 和订阅 URL。
|
||||||
|
2. 配置 SMTP 邮件服务并点击“测试发信”。
|
||||||
|
3. 按需要开启注册邮箱验证。忘记密码和邮箱变更也会使用 SMTP。
|
||||||
|
4. 进入“支付配置”,填写并启用至少一种支付方式。
|
||||||
|
5. 添加 3x-ui 节点,测试连接并同步入站。
|
||||||
|
6. 创建代理套餐,绑定入站;或创建流媒体服务和套餐。
|
||||||
|
7. 在节点页生成探测 Token,安装 Agent。
|
||||||
|
8. 用普通用户注册、下单、支付、查看订阅,走一遍完整流程。
|
||||||
|
9. 进入“订阅风控”,确认地图、IP、分析日志、人工操作按钮都能正常展示。
|
||||||
|
|
||||||
可以展示给用户的常用入口:
|
可以展示给用户的常用入口:
|
||||||
|
|
||||||
@@ -264,10 +246,23 @@ docker compose up -d app
|
|||||||
- 套餐商店:`https://你的域名/store`
|
- 套餐商店:`https://你的域名/store`
|
||||||
- 用户中心:`https://你的域名/dashboard`
|
- 用户中心:`https://你的域名/dashboard`
|
||||||
- 订阅列表:`https://你的域名/subscriptions`
|
- 订阅列表:`https://你的域名/subscriptions`
|
||||||
|
- 工单中心:`https://你的域名/support`
|
||||||
|
|
||||||
|
## 邮件与邮箱验证
|
||||||
|
|
||||||
|
SMTP 配置在后台“系统设置”中完成,密码会加密保存在数据库中。支持的邮件场景包括:
|
||||||
|
|
||||||
|
- 注册邮箱验证,可由管理员开启或关闭。
|
||||||
|
- 忘记密码重置链接。
|
||||||
|
- 修改邮箱验证。
|
||||||
|
- 管理员测试发信。
|
||||||
|
- 风控报告发送和通知辅助。
|
||||||
|
|
||||||
|
建议使用专用发信邮箱或应用专用密码。Gmail、企业邮箱和大多数 SMTP 服务都可以使用 `host + port + user + password + from` 的方式接入。生产环境请优先使用 587 STARTTLS 或服务商推荐端口。
|
||||||
|
|
||||||
## 支付配置
|
## 支付配置
|
||||||
|
|
||||||
支付配置在后台 `/admin/payments` 完成,密钥会保存在数据库中,不写入 `.env`,也不要提交到仓库或截图外传。创建订单时,系统会根据用户选择的支付方式生成支付链接、二维码或链上收款信息;支付成功后进入 `src/services/payment/process.ts` 完成订单确认和订阅开通。
|
支付配置在后台 `/admin/payments` 完成,密钥会加密保存在数据库中,不写入 `.env`,也不要提交到仓库或截图外传。创建订单时,系统会根据用户选择的支付方式生成支付链接、二维码或链上收款信息;支付成功后进入 `src/services/payment/process.ts` 完成订单确认和订阅开通。
|
||||||
|
|
||||||
| 支付方式 | 适用场景 | 必填信息 | 回调 / 查询说明 |
|
| 支付方式 | 适用场景 | 必填信息 | 回调 / 查询说明 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
@@ -277,21 +272,54 @@ docker compose up -d app
|
|||||||
|
|
||||||
支付上线前建议:
|
支付上线前建议:
|
||||||
|
|
||||||
- 在支付平台后台把通知域名、回跳域名、应用网关白名单都设置为你的公网域名。
|
- 在支付平台后台把通知域名、回跳域名、应用网关白名单设置为公网域名。
|
||||||
- 先创建低金额测试套餐,确认“创建订单 -> 支付 -> 回调/查询 -> 自动开通订阅”完整可用。
|
- 先创建低金额测试套餐,确认“创建订单 -> 支付 -> 回调/查询 -> 自动开通订阅”完整可用。
|
||||||
- 易支付的 API 地址不要带尾部路径,例如填 `https://pay.example.com`,系统会自动请求 `/mapi.php`、`/submit.php` 和 `/api.php`。
|
- 易支付 API 地址不要带尾部路径,例如填 `https://pay.example.com`,系统会自动请求 `/mapi.php`、`/submit.php` 和 `/api.php`。
|
||||||
- 支付宝密钥可以填写纯 key 内容或 PEM 格式;系统会自动补 PEM 包装。
|
- 支付宝密钥可以填写纯 key 内容或 PEM 格式;系统会自动补 PEM 包装。
|
||||||
- USDT TRC20 按金额匹配入账,测试时避免短时间出现多笔完全相同金额。
|
- USDT TRC20 按金额匹配入账,测试时避免短时间出现多笔完全相同金额。
|
||||||
|
|
||||||
## 节点与探测
|
## 节点、3x-ui 与 Agent
|
||||||
|
|
||||||
|
节点接入流程:
|
||||||
|
|
||||||
1. 在 VPS 安装并配置 3x-ui,确认面板 API 可访问。
|
1. 在 VPS 安装并配置 3x-ui,确认面板 API 可访问。
|
||||||
2. 管理后台添加 3x-ui 节点。
|
2. 在 3x-ui 中创建真实入站。
|
||||||
3. 保存后 J-Board 会登录 3x-ui 并同步入站。
|
3. 管理后台添加 3x-ui 节点,填写面板地址、用户名和密码。
|
||||||
4. 在代理套餐中绑定已同步入站。
|
4. 保存后 J-Board 会登录 3x-ui 并同步入站到 `NodeInbound`。
|
||||||
5. 如需前台展示延迟/线路,点击“生成探测 Token”,复制弹窗里的一键安装命令到节点执行。
|
5. 在代理套餐中绑定已同步入站。
|
||||||
|
6. 用户购买代理套餐后,J-Board 调用 3x-ui API 创建客户端,并保存 `NodeClient`。
|
||||||
|
7. 订阅暂停、恢复、删除、重置访问时,同步调用 3x-ui API 更新客户端。
|
||||||
|
8. 如需前台展示延迟、线路和节点日志风控,点击“生成探测 Token”,复制一键安装命令到节点执行。
|
||||||
|
|
||||||
探测程序也可手动运行:
|
Agent 安装脚本会:
|
||||||
|
|
||||||
|
- 下载 GitHub Release 中对应架构的 Agent 二进制。
|
||||||
|
- 安装或复用 `nexttrace`。
|
||||||
|
- 自动查找 `/usr/local/x-ui/access.log` 等常见 Xray access log 路径。
|
||||||
|
- 创建 `/var/lib/jboard-agent` 和 `/var/log/jboard`。
|
||||||
|
- 尝试让 Agent 具有 access log 读取权限。
|
||||||
|
- 写入 `/etc/jboard-agent.env`。
|
||||||
|
- 停用并移除旧的 Agent systemd 服务,避免冲突。
|
||||||
|
- 写入并启动 `jboard-agent.service`。
|
||||||
|
|
||||||
|
节点机常用命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status jboard-agent --no-pager -l
|
||||||
|
journalctl -u jboard-agent -n 100 --no-pager
|
||||||
|
journalctl -u jboard-agent -f --no-pager
|
||||||
|
journalctl -u jboard-agent -f --no-pager | grep --line-buffered xray-log
|
||||||
|
cat /etc/jboard-agent.env
|
||||||
|
cat /var/lib/jboard-agent/xray-log-state.json
|
||||||
|
```
|
||||||
|
|
||||||
|
升级 Agent:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/upgrade-jboard-agent.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
如果只想手动运行 Agent:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
SERVER_URL=https://your-domain.com \
|
SERVER_URL=https://your-domain.com \
|
||||||
@@ -299,14 +327,63 @@ AUTH_TOKEN=后台生成的探测Token \
|
|||||||
./jboard-agent
|
./jboard-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
可选变量:
|
更多 Agent 说明见 `agent/jboard-agent/README.md`。
|
||||||
|
|
||||||
- `LATENCY_INTERVAL`:默认 `5m`
|
## 订阅访问风控
|
||||||
- `TRACE_INTERVAL`:默认 `30m`
|
|
||||||
|
|
||||||
路由探测依赖 `nexttrace`。没有该命令时,延迟探测仍可运行,路由探测会记录错误日志。
|
J-Board 的订阅风控分两层。
|
||||||
|
|
||||||
## 备份与安全
|
第一层是订阅 API 访问风控。用户或客户端拉取 `/api/subscription/*` 时,系统记录真实 IP、User-Agent、国家、省/地区、城市、经纬度,并按后台配置判断:
|
||||||
|
|
||||||
|
- 单 IP 每小时访问次数。
|
||||||
|
- 单订阅 token 每小时访问次数。
|
||||||
|
- 24 小时窗口内不同城市数量。
|
||||||
|
- 24 小时窗口内不同省/地区数量。
|
||||||
|
- 24 小时窗口内不同国家/地区数量。
|
||||||
|
|
||||||
|
第二层是节点真实连接风控。Agent 读取 Xray access log,将日志里的 `email: user@example.com-xxxx` 匹配到本地 `NodeClient.email`,再归属到用户和订阅。系统记录:
|
||||||
|
|
||||||
|
- 真实来源 IP。
|
||||||
|
- 真实来源 IP 的 GeoIP。
|
||||||
|
- 入站 tag。
|
||||||
|
- tcp/udp。
|
||||||
|
- 样本目标域名或 IP。
|
||||||
|
- 目标端口。
|
||||||
|
- 聚合窗口内连接数。
|
||||||
|
- 聚合窗口内不同目标数。
|
||||||
|
- 首次和最近连接时间。
|
||||||
|
|
||||||
|
管理员可在“系统设置 -> 订阅访问风控”中配置总开关、自动暂停开关、窗口时长、城市/省/国家阈值、IP/订阅访问频率阈值,以及节点日志风控中的连接数和不同目标数阈值。
|
||||||
|
|
||||||
|
默认规则保持为:
|
||||||
|
|
||||||
|
- 24 小时内 4 个城市警告,5 个城市暂停。
|
||||||
|
- 2 个省/地区警告,3 个省/地区暂停。
|
||||||
|
- 2 个国家/地区警告,3 个国家/地区暂停。
|
||||||
|
- IP 180 次/小时,订阅 60 次/小时。
|
||||||
|
- 节点日志风控默认开启,连接数和不同目标数按 Agent 单次聚合窗口计算。
|
||||||
|
|
||||||
|
风控事件会进入后台“订阅风控”。管理员可以:
|
||||||
|
|
||||||
|
- 查看关联用户和订阅详情。
|
||||||
|
- 查看 IP、国家、省/地区、城市统计。
|
||||||
|
- 在世界地图上查看可识别坐标点。
|
||||||
|
- 展开分析日志,看到每条证据的 IP、时间、来源、Xray 解析详情、连接数和不同目标数。
|
||||||
|
- 生成风险报告。
|
||||||
|
- 选择是否发送到用户端。
|
||||||
|
- 解除限制或保持封禁/暂停。
|
||||||
|
|
||||||
|
用户收到管理员发送的风险报告后,会看到全屏不可关闭的限制通知,只能新建工单联系客服,不能继续进行其他用户端操作。
|
||||||
|
|
||||||
|
## GeoIP 与 Cloudflare
|
||||||
|
|
||||||
|
项目内置 `data/GeoLite2-City.mmdb` 作为本地 GeoIP 城市库,默认通过 `GEOIP_MMDB_PATH=data/GeoLite2-City.mmdb` 读取。系统会优先使用反向代理或 CDN 提供的地理位置头,并用 MMDB 补齐缺失字段。
|
||||||
|
|
||||||
|
Cloudflare 场景建议在 Rules -> Settings -> Managed Transforms 开启 Add visitor location headers,让回源请求带上 `cf-ipcity`、`cf-region`、`cf-region-code` 等字段。未提供城市/省份字段且 MMDB 不可用时,系统只记录 IP,不会触发地区变化规则。
|
||||||
|
|
||||||
|
如果网站域名和订阅域名相同,系统只统计订阅 API 访问,不会把普通网站浏览计入订阅风控。
|
||||||
|
|
||||||
|
## 备份与恢复
|
||||||
|
|
||||||
下载 SQL 备份:
|
下载 SQL 备份:
|
||||||
|
|
||||||
@@ -316,29 +393,113 @@ docker compose exec -T db pg_dump -U jboard jboard > backup_$(date +%Y%m%d_%H%M%
|
|||||||
|
|
||||||
后台也可通过 `/admin/backups` 导出或恢复数据库。恢复前务必先保存当前数据库备份。
|
后台也可通过 `/admin/backups` 导出或恢复数据库。恢复前务必先保存当前数据库备份。
|
||||||
|
|
||||||
安全建议:
|
建议:
|
||||||
|
|
||||||
- 不要提交 `.env`、探测 Token、3x-ui 密码、支付密钥
|
- 定期备份 PostgreSQL volume。
|
||||||
- 数据库备份里包含用户、订单和支付配置,建议加密保存并限制下载权限
|
- 将备份加密保存。
|
||||||
- 生产环境不要公开 PostgreSQL 和 Redis 端口
|
- 备份恢复后立即检查管理员登录、支付配置、节点密码、SMTP、订阅 URL 和 Agent 上报。
|
||||||
- 3x-ui 面板建议限制来源 IP 或使用反向代理鉴权
|
|
||||||
- `ENCRYPTION_KEY` 一旦生产使用不要随意更换,否则已加密数据会无法解密
|
|
||||||
|
|
||||||
## 开发原则
|
## 本地开发
|
||||||
|
|
||||||
- 节点入站与客户端运行配置以 3x-ui 为准,J-Board 只保存售卖镜像
|
```bash
|
||||||
- 后端只保留探测上报接口,不再新增节点控制面接口
|
npm install
|
||||||
- Server Actions 负责权限、校验、审计和缓存刷新
|
cp .env.example .env
|
||||||
- Route Handlers 仅用于外部 HTTP 接口或文件下载
|
npm run db:push
|
||||||
- 重要副作用必须记录审计日志或任务记录
|
npm run db:seed
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
默认管理员账号:
|
||||||
|
|
||||||
|
- 邮箱:`admin@jboard.local`
|
||||||
|
- 密码:`admin123`
|
||||||
|
|
||||||
|
常用检查:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx prisma generate
|
||||||
|
npx tsc --noEmit
|
||||||
|
npm run lint
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
数据库变更:
|
||||||
|
|
||||||
|
- 修改 `prisma/schema.prisma` 后运行 `npm run db:push`。
|
||||||
|
- 生产 Docker 部署更新后,运行 `docker compose --profile setup run --rm init sh -lc 'npm run db:push'`。
|
||||||
|
- 当前项目使用 `prisma db push --accept-data-loss`,上线前请确认 schema 变更不会误删重要数据。
|
||||||
|
|
||||||
|
Agent 开发:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd agent/jboard-agent
|
||||||
|
go test ./...
|
||||||
|
make build-linux
|
||||||
|
shasum -a 256 jboard-agent-linux-amd64 jboard-agent-linux-arm64 > SHA256SUMS
|
||||||
|
```
|
||||||
|
|
||||||
|
## 安全建议
|
||||||
|
|
||||||
|
- 不要提交 `.env`、探测 Token、3x-ui 密码、SMTP 密码、支付密钥。
|
||||||
|
- 数据库备份包含用户、订单、支付配置、节点凭据和邮件配置,建议加密保存并限制下载权限。
|
||||||
|
- 生产环境不要公开 PostgreSQL 和 Redis 端口。
|
||||||
|
- 3x-ui 面板建议限制来源 IP 或使用反向代理鉴权。
|
||||||
|
- `ENCRYPTION_KEY` 一旦生产使用不要随意更换。
|
||||||
|
- 管理后台账号建议使用强密码和专用邮箱。
|
||||||
|
- 订阅域名套 CDN 时应避免源站裸露,否则真实 IP 风控可信度会下降。
|
||||||
|
- Agent 只读 Xray access log,但日志中包含用户 IP、访问目标和 client email,应按敏感数据处理。
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### 登录、退出或邮件链接出现 localhost
|
||||||
|
|
||||||
|
检查 `.env` 中的 `NEXTAUTH_URL` 和后台系统设置中的网站 URL。后台配置优先于环境变量。生产环境必须填写公网域名。
|
||||||
|
|
||||||
|
### 订阅链接使用了错误域名
|
||||||
|
|
||||||
|
检查 `.env` 中的 `SUBSCRIPTION_URL` 和后台系统设置中的订阅 URL。后台配置优先于环境变量。
|
||||||
|
|
||||||
|
### 点击测试发信报错
|
||||||
|
|
||||||
|
先确认 SMTP 是否启用、Host/Port/User/Password/From 是否正确。Gmail 等服务通常需要应用专用密码。生产环境隐藏原始异常时,可查看 `docker compose logs -f app`。
|
||||||
|
|
||||||
|
### 用户不验证邮箱也能注册
|
||||||
|
|
||||||
|
确认后台“注册邮箱验证”已经开启,并检查 SMTP 是否启用。邮箱验证开启后,新用户会进入待验证状态,必须通过邮件链接激活。
|
||||||
|
|
||||||
|
### Agent 没有 xray-log 输出
|
||||||
|
|
||||||
|
先看 Agent 是否运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status jboard-agent --no-pager -l
|
||||||
|
journalctl -u jboard-agent -n 100 --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
再确认 access log 状态:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /etc/jboard-agent.env | grep XRAY
|
||||||
|
cat /var/lib/jboard-agent/xray-log-state.json
|
||||||
|
tail -n 50 /usr/local/x-ui/access.log
|
||||||
|
grep "email:" /usr/local/x-ui/access.log | tail -n 20
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 默认 `XRAY_LOG_START_AT_END=1`,首次启动会从文件末尾开始,只分析启动后的新连接。需要真实客户端连接节点并产生带 `email:` 的 access log,后台才会出现节点真实连接分析。
|
||||||
|
|
||||||
|
### Xray client email 带后缀是否有影响
|
||||||
|
|
||||||
|
没有影响。J-Board 用户邮箱可能是 `user@example.com`,Xray client email 可能是 `user@example.com-cmojtnp3`。节点日志风控用 Xray access log 里的 client email 匹配本地 `NodeClient.email`,再找到真实用户和订阅。不要手动在 3x-ui 改 client email,否则会导致日志无法归属。
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
- `docs/API.md`:HTTP 接口与 Server Actions 参考
|
- `docs/API.md`:HTTP 接口与 Server Actions 参考。
|
||||||
- `docs/openapi.yaml`:对外 HTTP 接口的 OpenAPI 3.1 描述
|
- `docs/openapi.yaml`:对外 HTTP 接口 OpenAPI 3.1 描述。
|
||||||
- `agent/jboard-agent/README.md`:探测程序说明
|
- `agent/jboard-agent/README.md`:Agent 安装、升级、日志与排障说明。
|
||||||
|
- `AGENTS.md`:给代码协作 Agent 的仓库规则。
|
||||||
|
|
||||||
## 请我喝杯咖啡
|
## 请我喝杯咖啡
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
USDT-TRC20: TQfaGEBdnB89V4y6R6bypZXx7Za5QfXBCi
|
USDT-TRC20: TQfaGEBdnB89V4y6R6bypZXx7Za5QfXBCi
|
||||||
|
|||||||
@@ -1,12 +1,289 @@
|
|||||||
# jboard-agent
|
# jboard-agent
|
||||||
|
|
||||||
`jboard-agent` 以旁路方式负责节点探测和可选的 Xray access log 风控上报:
|
`jboard-agent` 是 J-Board 的节点侧旁路程序。它运行在节点 VPS 上,负责把节点体验和节点真实连接证据上报到 J-Board。
|
||||||
|
|
||||||
- 三网 TCP 延迟:`POST /api/agent/latency`
|
它做三件事:
|
||||||
- 三网路由跟踪:`POST /api/agent/trace`
|
|
||||||
- Xray access log 聚合:`POST /api/agent/node-access`,安装/升级脚本会自动探测并写入 `XRAY_ACCESS_LOG_PATH`
|
|
||||||
|
|
||||||
节点入站、客户端开通、暂停、删除、流量限制等配置均由 3x-ui 面板维护。Agent 只读日志文件,不修改 3x-ui 配置、不重启 Xray。
|
- 三网 TCP 延迟探测:`POST /api/agent/latency`
|
||||||
|
- 三网路由追踪:`POST /api/agent/trace`
|
||||||
|
- Xray access log 聚合:`POST /api/agent/node-access`
|
||||||
|
|
||||||
|
它不做这些事:
|
||||||
|
|
||||||
|
- 不创建、删除或修改 3x-ui 入站。
|
||||||
|
- 不创建、删除或修改 Xray 客户端。
|
||||||
|
- 不重启 3x-ui 或 Xray。
|
||||||
|
- 不接管节点流量。
|
||||||
|
- 不作为公共代理或透明代理。
|
||||||
|
|
||||||
|
节点入站、客户端开通、暂停、删除、流量限制等配置均由 3x-ui 面板维护。Agent 只读日志文件,并通过 J-Board 的 Agent Token 上报结果。
|
||||||
|
|
||||||
|
## 工作方式
|
||||||
|
|
||||||
|
```text
|
||||||
|
jboard-agent
|
||||||
|
├─ LatencyLoop:定时 TCP connect 三网目标
|
||||||
|
├─ TraceLoop:定时调用 nexttrace 获取三网路由
|
||||||
|
└─ XrayAccessLogLoop:读取 Xray access log,聚合真实来源 IP、连接数和不同目标数
|
||||||
|
↓
|
||||||
|
J-Board /api/agent/*
|
||||||
|
↓
|
||||||
|
后台节点体验、订阅风控、分析日志、风险报告
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 使用 `AUTH_TOKEN` 认证。这个 token 在 J-Board 后台节点页生成,服务端会通过它匹配到具体 `NodeServer`。
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
推荐在 J-Board 后台“节点管理”中点击生成 Agent Token,然后复制弹窗中的一键安装命令到节点机执行。安装脚本会自动完成:
|
||||||
|
|
||||||
|
- 下载 GitHub Release 中对应架构的二进制。
|
||||||
|
- 校验 `SHA256SUMS`。
|
||||||
|
- 安装或复用 `nexttrace`。
|
||||||
|
- 自动查找 Xray access log。
|
||||||
|
- 创建 `/var/lib/jboard-agent` 和 `/var/log/jboard`。
|
||||||
|
- 写入 `/etc/jboard-agent.env`。
|
||||||
|
- 停用并移除旧的 Agent systemd 服务,避免冲突。
|
||||||
|
- 写入并启动 `jboard-agent.service`。
|
||||||
|
|
||||||
|
手动安装命令形如:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/install-jboard-agent.sh | SERVER_URL=https://panel.example.com AUTH_TOKEN=你的Token bash
|
||||||
|
```
|
||||||
|
|
||||||
|
如果需要指定 Agent Release:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/install-jboard-agent.sh | AGENT_TAG=v3.0.2 SERVER_URL=https://panel.example.com AUTH_TOKEN=你的Token bash
|
||||||
|
```
|
||||||
|
|
||||||
|
## 升级
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/JetSprow/J-Board/main/scripts/upgrade-jboard-agent.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
升级脚本会读取现有 `/etc/jboard-agent.env`,保留服务器地址、Token、探测间隔和 Xray 日志配置,并重新写入当前 systemd service。
|
||||||
|
|
||||||
|
升级后确认版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u jboard-agent -n 30 --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
你应该看到类似:
|
||||||
|
|
||||||
|
```text
|
||||||
|
[agent] jboard-agent v3.0.2 starting in probe-only mode
|
||||||
|
```
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `SERVER_URL` | 必填 | J-Board 面板公网地址,例如 `https://panel.example.com`。 |
|
||||||
|
| `AUTH_TOKEN` | 必填 | 后台节点页生成的 Agent Token。 |
|
||||||
|
| `LATENCY_INTERVAL` | `5m` | 延迟探测间隔,支持 `30s`、`5m` 或纯秒数。 |
|
||||||
|
| `TRACE_INTERVAL` | `30m` | 路由探测间隔,支持 `30m` 或纯秒数。 |
|
||||||
|
| `XRAY_ACCESS_LOG_PATH` | 自动探测 | Xray access log 路径。为空时节点真实连接风控禁用。 |
|
||||||
|
| `XRAY_LOG_INTERVAL` | `1m` | access log 读取、聚合、上报间隔。 |
|
||||||
|
| `XRAY_LOG_STATE_FILE` | `/var/lib/jboard-agent/xray-log-state.json` | access log offset 状态文件。 |
|
||||||
|
| `XRAY_LOG_START_AT_END` | `1` | 首次启动从文件末尾开始,避免上传历史巨量日志;设为 `0` 可从头读取。 |
|
||||||
|
| `INSTALL_NEXTTRACE` | `1` | 安装脚本是否自动安装 nexttrace。 |
|
||||||
|
|
||||||
|
systemd 环境文件默认位于:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/etc/jboard-agent.env
|
||||||
|
```
|
||||||
|
|
||||||
|
修改环境文件后需要重启:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl restart jboard-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Xray access log
|
||||||
|
|
||||||
|
安装/升级脚本会优先查找这些路径:
|
||||||
|
|
||||||
|
- `/usr/local/x-ui/access.log`
|
||||||
|
- `/usr/local/x-ui/bin/access.log`
|
||||||
|
- `/usr/local/x-ui/xray/access.log`
|
||||||
|
- `/etc/x-ui/access.log`
|
||||||
|
- `/etc/x-ui/xray/access.log`
|
||||||
|
- `/var/log/xray/access.log`
|
||||||
|
- `/var/log/x-ui/access.log`
|
||||||
|
- `/opt/3x-ui/access.log`
|
||||||
|
- `/opt/x-ui/access.log`
|
||||||
|
- `/usr/local`、`/etc`、`/var/log`、`/opt`、Docker volume 下名称包含 `access.log` 或 `xray` 的日志
|
||||||
|
|
||||||
|
如果没有找到,脚本会提示你在 3x-ui 的 Xray Config 中开启:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"log": {
|
||||||
|
"access": "/usr/local/x-ui/access.log",
|
||||||
|
"error": "/usr/local/x-ui/error.log",
|
||||||
|
"loglevel": "warning"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
然后重启 x-ui,再重跑 Agent 安装或升级脚本。
|
||||||
|
|
||||||
|
### 支持的日志格式
|
||||||
|
|
||||||
|
Agent 支持常见 Xray access log 格式,包括:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026/04/29 10:11:12 203.0.113.9:51820 accepted tcp:example.com:443 [proxy-in >> freedom] email: user@example.com-cabc1234
|
||||||
|
```
|
||||||
|
|
||||||
|
也支持 3x-ui/Xray 新格式:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026/04/29 09:20:05.982584 from 220.240.111.193:59425 accepted tcp:example.com:443 [inbound-17583 >> direct] email: user@example.com-cmojtnp3
|
||||||
|
2026/04/29 09:20:06.006542 from tcp:220.240.111.193:59433 accepted udp:71.18.167.208:443 [inbound-17583 >> direct] email: user@example.com-cmojtnp3
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 会解析:
|
||||||
|
|
||||||
|
- `sourceIp`:真实来源 IP。
|
||||||
|
- `clientEmail`:Xray client email。
|
||||||
|
- `inboundTag`:入站 tag,例如 `inbound-17583`。
|
||||||
|
- `network`:`tcp` 或 `udp`。
|
||||||
|
- `targetHost` / `targetPort`:样本目标。
|
||||||
|
- `action`:`accepted` 或 `rejected`。
|
||||||
|
- `connectionCount`:聚合窗口内连接数。
|
||||||
|
- `uniqueTargetCount`:聚合窗口内不同目标数。
|
||||||
|
- `firstSeenAt` / `lastSeenAt`:窗口内首次和最近连接时间。
|
||||||
|
|
||||||
|
没有 `email:` 的日志会跳过,因为服务端无法把它归属到 J-Board 的 `NodeClient`。`[api -> api]` 这类 3x-ui 本地 API 通信通常也会跳过。
|
||||||
|
|
||||||
|
## Xray client email 与用户邮箱
|
||||||
|
|
||||||
|
J-Board 用户邮箱和 Xray client email 不一定完全相同。例如:
|
||||||
|
|
||||||
|
```text
|
||||||
|
J-Board 用户邮箱:user@example.com
|
||||||
|
Xray client email:user@example.com-cmojtnp3
|
||||||
|
```
|
||||||
|
|
||||||
|
这是正常设计。节点日志风控使用 Xray access log 里的 `email:` 匹配本地 `NodeClient.email`,再找到对应用户和订阅。不要手动在 3x-ui 修改 client email,否则日志会无法归属。
|
||||||
|
|
||||||
|
## systemd 运维
|
||||||
|
|
||||||
|
查看服务状态:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status jboard-agent --no-pager -l
|
||||||
|
```
|
||||||
|
|
||||||
|
实时日志:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u jboard-agent -f --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
看最近 100 行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u jboard-agent -n 100 --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
只看 Xray 日志采集:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -u jboard-agent -f --no-pager | grep --line-buffered xray-log
|
||||||
|
```
|
||||||
|
|
||||||
|
查看配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /etc/jboard-agent.env
|
||||||
|
```
|
||||||
|
|
||||||
|
查看 access log offset 状态:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /var/lib/jboard-agent/xray-log-state.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## 排障
|
||||||
|
|
||||||
|
### Agent 没有启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status jboard-agent --no-pager -l
|
||||||
|
journalctl -u jboard-agent -n 100 --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
常见原因:
|
||||||
|
|
||||||
|
- `/etc/jboard-agent.env` 缺少 `SERVER_URL` 或 `AUTH_TOKEN`。
|
||||||
|
- 二进制没有执行权限。
|
||||||
|
- 旧服务没有清理干净。新安装/升级脚本会自动停用并移除旧服务。
|
||||||
|
|
||||||
|
### 没有 `[xray-log]` 输出
|
||||||
|
|
||||||
|
这不一定是错误。Agent 只在禁用、报错或成功推送时打印 `xray-log`。如果没有新 access log,实时 grep 会一直等待。
|
||||||
|
|
||||||
|
按顺序检查:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /etc/jboard-agent.env | grep XRAY
|
||||||
|
cat /var/lib/jboard-agent/xray-log-state.json
|
||||||
|
tail -n 50 /usr/local/x-ui/access.log
|
||||||
|
grep "email:" /usr/local/x-ui/access.log | tail -n 20
|
||||||
|
```
|
||||||
|
|
||||||
|
如果状态文件类似:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"path":"/usr/local/x-ui/access.log","inode":393262,"offset":180}
|
||||||
|
```
|
||||||
|
|
||||||
|
说明 Agent 已经找到并跟踪日志。它会从 offset 之后继续读。
|
||||||
|
|
||||||
|
### access log 只有 `[api -> api]`
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026/04/29 09:16:07.001315 from 127.0.0.1:43702 accepted tcp:127.0.0.1:62789 [api -> api]
|
||||||
|
```
|
||||||
|
|
||||||
|
这是 3x-ui / Xray 本地 API 通信,不是用户节点连接。你需要让真实客户端连接节点,再查看是否出现带 `email:` 的记录。
|
||||||
|
|
||||||
|
### 强制从头重读 access log
|
||||||
|
|
||||||
|
仅用于测试。生产环境不建议长期保持从头读取。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl stop jboard-agent
|
||||||
|
rm -f /var/lib/jboard-agent/xray-log-state.json
|
||||||
|
sed -i 's/^XRAY_LOG_START_AT_END=.*/XRAY_LOG_START_AT_END=0/' /etc/jboard-agent.env
|
||||||
|
systemctl start jboard-agent
|
||||||
|
journalctl -u jboard-agent -n 100 --no-pager | grep xray-log
|
||||||
|
```
|
||||||
|
|
||||||
|
测试完成后改回:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sed -i 's/^XRAY_LOG_START_AT_END=.*/XRAY_LOG_START_AT_END=1/' /etc/jboard-agent.env
|
||||||
|
systemctl restart jboard-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
### 服务端没有收到节点日志风控
|
||||||
|
|
||||||
|
检查:
|
||||||
|
|
||||||
|
- 后台系统设置是否开启订阅风控总控。
|
||||||
|
- 后台是否开启节点日志风控。
|
||||||
|
- access log 是否包含 `email:`。
|
||||||
|
- `email:` 是否与 J-Board 数据库里的 `NodeClient.email` 一致。
|
||||||
|
- Agent Token 是否属于当前节点。
|
||||||
|
- 面板日志是否有 `/api/agent/node-access` 的错误。
|
||||||
|
|
||||||
## 构建
|
## 构建
|
||||||
|
|
||||||
@@ -16,31 +293,27 @@ make build
|
|||||||
make build-linux
|
make build-linux
|
||||||
```
|
```
|
||||||
|
|
||||||
## 运行
|
生成校验和:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
SERVER_URL=https://your-domain.com \
|
shasum -a 256 jboard-agent-linux-amd64 jboard-agent-linux-arm64 > SHA256SUMS
|
||||||
AUTH_TOKEN=后台生成的探测Token \
|
|
||||||
./jboard-agent
|
|
||||||
```
|
```
|
||||||
|
|
||||||
可选环境变量:
|
## Release 规则
|
||||||
|
|
||||||
| 变量 | 默认值 | 说明 |
|
只有 Agent 代码或 Agent 安装/升级体验需要随二进制发布时,才创建新的 Agent tag 和 GitHub Release。普通面板页面、后台 UI、文档或 Server Action 改动不需要强行更新 Agent release。
|
||||||
| --- | --- | --- |
|
|
||||||
| `LATENCY_INTERVAL` | `5m` | 延迟探测间隔,支持 `30s`、`5m` 或秒数 |
|
|
||||||
| `TRACE_INTERVAL` | `30m` | 路由探测间隔,支持 `30m` 或秒数 |
|
|
||||||
| `XRAY_ACCESS_LOG_PATH` | 自动探测 | Xray access log 路径;安装/升级脚本会优先查找 `/usr/local/x-ui/access.log` 等常见路径,仍为空时禁用节点真实连接风控 |
|
|
||||||
| `XRAY_LOG_INTERVAL` | `1m` | 日志读取和聚合上报间隔 |
|
|
||||||
| `XRAY_LOG_STATE_FILE` | `/var/lib/jboard-agent/xray-log-state.json` | 日志 offset 状态文件 |
|
|
||||||
| `XRAY_LOG_START_AT_END` | `1` | 首次启动从文件末尾开始,避免上传历史巨量日志;设为 `0` 可从头读取 |
|
|
||||||
|
|
||||||
路由探测依赖 `nexttrace` 命令;延迟探测无需额外依赖。
|
Release 需要包含:
|
||||||
|
|
||||||
## systemd
|
- `jboard-agent-linux-amd64`
|
||||||
|
- `jboard-agent-linux-arm64`
|
||||||
|
- `SHA256SUMS`
|
||||||
|
|
||||||
推荐从 J-Board 后台节点页复制一键安装命令。该命令会下载 release 二进制、安装 `nexttrace`、自动探测 3x-ui/Xray access log、写入 systemd 服务并启动。
|
安装/升级脚本默认使用 GitHub 最新 Release。需要固定版本时传入 `AGENT_TAG=vX.Y.Z`。
|
||||||
|
|
||||||
## 延迟算法
|
## 安全边界
|
||||||
|
|
||||||
延迟探测使用三组 zstaticcdn 运营商目标,先解析域名再开始计时,只统计 TCP connect 耗时,避免 DNS 抖动混入延迟;当单次结果超过 1000ms 时会额外重试最多 3 次并采用更低的有效结果。
|
- Agent 只读 Xray access log,但日志中包含真实来源 IP、访问目标和 client email,应按敏感数据处理。
|
||||||
|
- Agent Token 等同节点上报凭据,不要外传。
|
||||||
|
- 节点服务器上不要公开 `/etc/jboard-agent.env`。
|
||||||
|
- 3x-ui 面板建议限制来源 IP 或使用反向代理鉴权。
|
||||||
|
|||||||
297
docs/API.md
297
docs/API.md
@@ -1,20 +1,22 @@
|
|||||||
# J-Board API
|
# J-Board API 与 Server Actions
|
||||||
|
|
||||||
本文整理当前有效的 HTTP Route Handlers 和内部 Server Actions。对外 HTTP 结构化描述见 `docs/openapi.yaml`。
|
本文整理 J-Board 当前有效的 HTTP Route Handlers 和内部 Server Actions。HTTP 对外结构化描述见 `docs/openapi.yaml`;本文更偏向工程阅读和排障。
|
||||||
|
|
||||||
## 1. 通用约定
|
## 通用约定
|
||||||
|
|
||||||
- 用户会话:NextAuth Cookie
|
- 普通用户身份:NextAuth Cookie 会话。
|
||||||
- 管理接口:必须是管理员会话
|
- 管理员身份:NextAuth Cookie 会话,且用户角色为 `ADMIN`。
|
||||||
- 探测接口:`Authorization: Bearer <probe-token>`
|
- Agent 身份:`Authorization: Bearer <agent-token>`。
|
||||||
- 返回格式:JSON,文件下载接口除外
|
- 返回格式:默认 JSON,订阅内容和文件下载接口除外。
|
||||||
- 时间字段:ISO 8601 字符串
|
- 时间字段:ISO 8601 字符串。
|
||||||
|
- 写操作:必须做权限校验、输入校验、审计记录和必要的 `revalidatePath`。
|
||||||
|
- 3x-ui 密码、Agent Token、SMTP 密码、支付密钥等敏感字段在数据库中加密保存。
|
||||||
|
|
||||||
## 2. 认证
|
## 认证与公开信息
|
||||||
|
|
||||||
### `POST /api/auth/register`
|
### `POST /api/auth/register`
|
||||||
|
|
||||||
注册普通用户。
|
注册普通用户。是否允许注册、是否必须邀请码、是否需要邮箱验证由后台系统设置控制。
|
||||||
|
|
||||||
请求体:
|
请求体:
|
||||||
|
|
||||||
@@ -28,15 +30,21 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
行为:
|
||||||
|
|
||||||
|
- 校验邮箱、密码、邀请码和 Turnstile。
|
||||||
|
- 当注册邮箱验证开启时,用户会进入 `PENDING_EMAIL` 状态并收到验证邮件。
|
||||||
|
- 当注册邮箱验证关闭时,用户直接成为可登录用户。
|
||||||
|
|
||||||
### `GET|POST /api/auth/[...nextauth]`
|
### `GET|POST /api/auth/[...nextauth]`
|
||||||
|
|
||||||
NextAuth 内置登录、登出、会话接口。
|
NextAuth 内置登录、登出、会话接口。
|
||||||
|
|
||||||
## 3. 公共数据
|
|
||||||
|
|
||||||
### `GET /api/public/app-info`
|
### `GET /api/public/app-info`
|
||||||
|
|
||||||
返回站点名称、注册策略、维护公告、Turnstile 配置等公开信息。
|
返回站点名称、注册策略、维护公告、Turnstile 配置、网站公开配置等信息。前端登录页、注册页和公共布局会使用它。
|
||||||
|
|
||||||
|
## 延迟与路由展示
|
||||||
|
|
||||||
### `GET /api/latency?nodeId=<id>`
|
### `GET /api/latency?nodeId=<id>`
|
||||||
|
|
||||||
@@ -44,17 +52,21 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
|
|
||||||
### `GET /api/latency/history?nodeId=<id>&carrier=telecom&range=7d`
|
### `GET /api/latency/history?nodeId=<id>&carrier=telecom&range=7d`
|
||||||
|
|
||||||
返回节点延迟历史,`range` 支持 `1d`、`7d`、`30d`。
|
返回节点延迟历史。`carrier` 通常为 `telecom`、`unicom`、`mobile`;`range` 支持 `1d`、`7d`、`30d`。
|
||||||
|
|
||||||
|
### `GET /api/latency/recommendations`
|
||||||
|
|
||||||
|
返回前台线路推荐所需的延迟聚合结果。
|
||||||
|
|
||||||
### `GET /api/traces?nodeId=<id>`
|
### `GET /api/traces?nodeId=<id>`
|
||||||
|
|
||||||
返回节点三网路由追踪结果。
|
返回节点三网路由追踪结果。服务端会重新归一化历史数据,修正 CN2 GIA、CN2 GT、CMIN2、CMI 等线路分类。
|
||||||
|
|
||||||
## 4. 支付
|
## 支付接口
|
||||||
|
|
||||||
### `GET /api/payment/providers`
|
### `GET /api/payment/providers`
|
||||||
|
|
||||||
返回当前启用的支付方式。
|
返回当前启用的支付方式。普通用户创建订单或切换支付方式时使用。
|
||||||
|
|
||||||
### `POST /api/payment/create`
|
### `POST /api/payment/create`
|
||||||
|
|
||||||
@@ -69,19 +81,63 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
行为:
|
||||||
|
|
||||||
|
- 校验订单属于当前用户且仍待支付。
|
||||||
|
- 根据支付方式生成支付链接、二维码或链上支付信息。
|
||||||
|
- 记录支付流水,便于后续回调或查询。
|
||||||
|
|
||||||
### `GET /api/payment/order/{orderId}`
|
### `GET /api/payment/order/{orderId}`
|
||||||
|
|
||||||
查询当前用户自己的订单支付状态。
|
查询当前用户自己的订单支付状态。
|
||||||
|
|
||||||
### `GET /api/payment/query/{tradeNo}`
|
### `GET /api/payment/query/{tradeNo}`
|
||||||
|
|
||||||
按支付流水号查询支付状态。
|
按支付流水号主动查询支付状态。用于前端轮询或支付平台回调异常时兜底。
|
||||||
|
|
||||||
### `GET|POST /api/payment/notify/{provider}`
|
### `GET|POST /api/payment/notify/{provider}`
|
||||||
|
|
||||||
支付平台异步通知入口。
|
支付平台异步通知入口。当前 provider 包括:
|
||||||
|
|
||||||
## 5. 管理导出与节点读取
|
- `epay`
|
||||||
|
- `alipay_f2f`
|
||||||
|
- `usdt_trc20` 的链上入账由查询任务处理,不依赖传统 HTTP 回调。
|
||||||
|
|
||||||
|
行为:
|
||||||
|
|
||||||
|
- 校验签名或链上入账。
|
||||||
|
- 标记订单已支付。
|
||||||
|
- 调用 `src/services/provision.ts` 创建或续费订阅。
|
||||||
|
- 代理订阅会同步 3x-ui client。
|
||||||
|
|
||||||
|
## 订阅与用户资源
|
||||||
|
|
||||||
|
### `GET /api/subscription/{id}?token=<downloadToken>`
|
||||||
|
|
||||||
|
无需登录,但必须提供合法下载 token。成功返回 `text/plain` 订阅内容。
|
||||||
|
|
||||||
|
行为:
|
||||||
|
|
||||||
|
- 校验订阅状态、到期时间和 token。
|
||||||
|
- 记录订阅访问日志和真实 IP。
|
||||||
|
- 执行订阅访问限流和地区变化风控。
|
||||||
|
- 当订阅被暂停或风控限制时,返回错误内容或拒绝访问。
|
||||||
|
|
||||||
|
### `GET /api/subscription/all`
|
||||||
|
|
||||||
|
返回用户聚合订阅内容。用于部分客户端的一键导入或总订阅入口。
|
||||||
|
|
||||||
|
### `GET /api/notifications`
|
||||||
|
|
||||||
|
返回当前用户通知列表。
|
||||||
|
|
||||||
|
### `GET /api/support/attachments/{id}`
|
||||||
|
|
||||||
|
工单附件访问接口。要求登录用户是附件所属工单用户本人或管理员。加 `?download=1` 可触发下载。
|
||||||
|
|
||||||
|
## 管理读取与导出
|
||||||
|
|
||||||
|
以下接口要求管理员会话。
|
||||||
|
|
||||||
### `GET /api/admin/nodes`
|
### `GET /api/admin/nodes`
|
||||||
|
|
||||||
@@ -89,11 +145,11 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
|
|
||||||
### `GET /api/admin/nodes/{id}/inbounds`
|
### `GET /api/admin/nodes/{id}/inbounds`
|
||||||
|
|
||||||
返回指定节点的已同步入站。
|
返回指定节点的已同步入站。套餐绑定和节点详情页会使用。
|
||||||
|
|
||||||
### `GET /api/admin/export/config`
|
### `GET /api/admin/export/config`
|
||||||
|
|
||||||
导出配置快照,包含站点设置、公告、服务、套餐、节点、入站、支付配置等。
|
导出配置快照,包含站点设置、公告、服务、套餐、节点、入站、支付配置等。敏感值会按实现规则脱敏或加密保存,不应公开传播。
|
||||||
|
|
||||||
### `GET /api/admin/export/audit-logs?q=<keyword>`
|
### `GET /api/admin/export/audit-logs?q=<keyword>`
|
||||||
|
|
||||||
@@ -101,11 +157,17 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
|
|
||||||
### `GET /api/admin/backup/database`
|
### `GET /api/admin/backup/database`
|
||||||
|
|
||||||
导出 SQL 数据库备份。
|
导出 SQL 数据库备份。备份包含用户、订单、节点、支付、SMTP 等敏感信息,应加密保存。
|
||||||
|
|
||||||
## 6. 探测上报
|
## Agent 上报接口
|
||||||
|
|
||||||
以下接口由 `agent/jboard-agent` 调用,探测 Token 存储在 `NodeServer.agentToken` 中并加密保存。
|
以下接口由 `agent/jboard-agent` 调用。Agent Token 存储在 `NodeServer.agentToken` 中,并加密保存。请求头必须为:
|
||||||
|
|
||||||
|
```http
|
||||||
|
Authorization: Bearer <agent-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
服务端会通过 Token 匹配到具体节点 `nodeId`。
|
||||||
|
|
||||||
### `POST /api/agent/latency`
|
### `POST /api/agent/latency`
|
||||||
|
|
||||||
@@ -121,7 +183,11 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
行为:更新 `NodeLatency` 并写入 `NodeLatencyLog`。
|
行为:
|
||||||
|
|
||||||
|
- 更新 `NodeLatency`。
|
||||||
|
- 写入 `NodeLatencyLog`。
|
||||||
|
- 前台节点延迟、历史图表和推荐会使用这些数据。
|
||||||
|
|
||||||
### `POST /api/agent/trace`
|
### `POST /api/agent/trace`
|
||||||
|
|
||||||
@@ -132,7 +198,17 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
"traces": [
|
"traces": [
|
||||||
{
|
{
|
||||||
"carrier": "telecom",
|
"carrier": "telecom",
|
||||||
"hops": [{ "hop": 1, "ip": "*", "geo": "", "latency": 0 }],
|
"hops": [
|
||||||
|
{
|
||||||
|
"hop": 1,
|
||||||
|
"ip": "203.0.113.1",
|
||||||
|
"geo": "CN",
|
||||||
|
"latency": 3.5,
|
||||||
|
"asn": "AS4809",
|
||||||
|
"owner": "China Telecom CN2",
|
||||||
|
"isp": "China Telecom"
|
||||||
|
}
|
||||||
|
],
|
||||||
"summary": "CN2 GIA",
|
"summary": "CN2 GIA",
|
||||||
"hopCount": 12
|
"hopCount": 12
|
||||||
}
|
}
|
||||||
@@ -140,53 +216,111 @@ NextAuth 内置登录、登出、会话接口。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
行为:按 `nodeId + carrier` 更新 `RouteTrace`。
|
行为:
|
||||||
|
|
||||||
## 7. 订阅与附件
|
- 服务端重新分类线路,避免旧 Agent 或 nexttrace 文案导致误判。
|
||||||
|
- 按 `nodeId + carrier` 更新 `RouteTrace`。
|
||||||
|
- 线路分类会优先识别 CN2 GIA、CN2 GT、CMIN2、CMI 等常见中国方向线路。
|
||||||
|
|
||||||
### `GET /api/subscription/{id}?token=<downloadToken>`
|
### `POST /api/agent/node-access`
|
||||||
|
|
||||||
无需会话,但必须提供合法下载 token。成功返回 `text/plain` 订阅内容。
|
接收 Agent 从 Xray access log 聚合出的真实节点连接事件。
|
||||||
|
|
||||||
### `GET /api/support/attachments/{id}`
|
请求体:
|
||||||
|
|
||||||
工单附件访问接口,要求登录用户是附件所属工单用户本人或管理员。加 `?download=1` 可触发下载。
|
```json
|
||||||
|
{
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"clientEmail": "user@example.com-cmojtnp3",
|
||||||
|
"sourceIp": "220.240.111.193",
|
||||||
|
"inboundTag": "inbound-17583",
|
||||||
|
"network": "tcp",
|
||||||
|
"targetHost": "example.com",
|
||||||
|
"targetPort": 443,
|
||||||
|
"action": "accepted",
|
||||||
|
"connectionCount": 18,
|
||||||
|
"uniqueTargetCount": 14,
|
||||||
|
"firstSeenAt": "2026-04-29T09:20:05+10:00",
|
||||||
|
"lastSeenAt": "2026-04-29T09:20:07+10:00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 8. Server Actions
|
行为:
|
||||||
|
|
||||||
Server Actions 是后台和用户端写操作的主要入口。所有管理动作必须经过 `requireAdmin()`,用户动作必须校验资源归属。
|
- 通过 `clientEmail` 匹配 `NodeClient.email`。
|
||||||
|
- 同时要求该 client 属于当前 Agent Token 对应节点。
|
||||||
|
- 写入 `SubscriptionAccessLog`,来源标记为“节点真实连接”。
|
||||||
|
- 使用 `sourceIp` 执行国家、省/地区、城市变化风控。
|
||||||
|
- 使用 `connectionCount` 和 `uniqueTargetCount` 执行节点日志行为风控。
|
||||||
|
- 创建 `SubscriptionRiskEvent`、通知、审计日志,并在需要时自动暂停订阅。
|
||||||
|
|
||||||
### 管理端
|
返回示例:
|
||||||
|
|
||||||
节点:`src/actions/admin/nodes.ts`
|
```json
|
||||||
|
{
|
||||||
|
"ok": true,
|
||||||
|
"processed": 1,
|
||||||
|
"skipped": 0,
|
||||||
|
"warnings": 0,
|
||||||
|
"suspended": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
- `createNode(formData)`:创建 3x-ui 节点并同步入站
|
常见跳过原因:
|
||||||
- `updateNode(id, formData)`:更新 3x-ui 节点连接信息并重新同步入站
|
|
||||||
- `deleteNode(id)`:删除节点及本地关联数据
|
|
||||||
- `testNodeConnection(id)`:测试 3x-ui 登录并同步入站
|
|
||||||
- `batchTestNodeConnections(formData)`:批量测试并同步节点
|
|
||||||
- `updateInboundDisplayName(id, formData)`:修改同步入站的前台展示名称
|
|
||||||
- `deleteInbound(id)`:仅删除本地入站镜像,不删除 3x-ui 入站
|
|
||||||
- `generateAgentToken(nodeId)`:生成探测 Token
|
|
||||||
- `revokeAgentToken(nodeId)`:撤销探测 Token
|
|
||||||
|
|
||||||
订阅:`src/actions/admin/subscriptions.ts`
|
- Xray access log 没有 `email:` 字段。
|
||||||
|
- `email:` 与本地 `NodeClient.email` 不一致。
|
||||||
|
- 日志来自 `[api -> api]` 这类 3x-ui 本地 API 通信。
|
||||||
|
- 后台关闭了订阅风控总控或节点日志风控。
|
||||||
|
|
||||||
- `suspendSubscription(id)`:暂停订阅,并通过 3x-ui 禁用代理客户端
|
## Server Actions
|
||||||
- `activateSubscription(id)`:恢复订阅,并通过 3x-ui 启用代理客户端
|
|
||||||
- `cancelSubscription(id)`:取消订阅
|
|
||||||
- `deleteSubscriptionPermanently(id)`:删除订阅,并通过 3x-ui 删除代理客户端
|
|
||||||
- `reassignStreamingSlot(...)`:调整流媒体槽位
|
|
||||||
- `batchSubscriptionOperation(formData)`:批量处理订阅
|
|
||||||
|
|
||||||
订单:`src/actions/admin/orders.ts`
|
Server Actions 是后台和用户端写操作的主要入口。它们不是公开 HTTP API,不建议第三方直接调用。
|
||||||
|
|
||||||
- `confirmOrder(orderId)`:手动确认订单并触发开通
|
### 管理端 Actions
|
||||||
- `cancelOrder(orderId)`:取消订单
|
|
||||||
- `updateOrderReview(...)`:更新风控/复核状态
|
|
||||||
- `batchOrderOperation(formData)`:批量操作订单
|
|
||||||
|
|
||||||
其他管理动作:
|
#### 节点:`src/actions/admin/nodes.ts`
|
||||||
|
|
||||||
|
- `createNode(formData)`:创建 3x-ui 节点并同步入站。
|
||||||
|
- `updateNode(id, formData)`:更新 3x-ui 节点连接信息并重新同步入站。
|
||||||
|
- `deleteNode(id)`:删除节点及本地关联数据。
|
||||||
|
- `testNodeConnection(id)`:测试 3x-ui 登录并同步入站。
|
||||||
|
- `batchTestNodeConnections(formData)`:批量测试并同步节点。
|
||||||
|
- `updateInboundDisplayName(id, formData)`:修改同步入站的前台展示名称。
|
||||||
|
- `deleteInbound(id)`:仅删除本地入站镜像,不删除 3x-ui 入站。
|
||||||
|
- `generateAgentToken(nodeId)`:生成 Agent Token。
|
||||||
|
- `revokeAgentToken(nodeId)`:撤销 Agent Token。
|
||||||
|
|
||||||
|
#### 订阅:`src/actions/admin/subscriptions.ts`
|
||||||
|
|
||||||
|
- `suspendSubscription(id)`:暂停订阅,并通过 3x-ui 禁用代理客户端。
|
||||||
|
- `activateSubscription(id)`:恢复订阅,并通过 3x-ui 启用代理客户端。
|
||||||
|
- `cancelSubscription(id)`:取消订阅。
|
||||||
|
- `deleteSubscriptionPermanently(id)`:强制删除订阅及名下关联数据,并尽量删除 3x-ui 客户端。
|
||||||
|
- `reassignStreamingSlot(...)`:调整流媒体槽位。
|
||||||
|
- `batchSubscriptionOperation(formData)`:批量处理订阅。
|
||||||
|
|
||||||
|
#### 订阅风控:`src/actions/admin/subscription-risk.ts`
|
||||||
|
|
||||||
|
- 更新复核状态和复核备注。
|
||||||
|
- 生成风险报告。
|
||||||
|
- 向用户发送风险报告并开启用户端全屏限制。
|
||||||
|
- 解除封控限制并恢复可恢复的代理订阅。
|
||||||
|
- 保持封禁/暂停并记录最终处理结果。
|
||||||
|
|
||||||
|
后台“订阅风控”页面依赖 `src/services/subscription-risk-review.ts` 整理地图、IP、分析日志和报告文本。
|
||||||
|
|
||||||
|
#### 订单:`src/actions/admin/orders.ts`
|
||||||
|
|
||||||
|
- `confirmOrder(orderId)`:手动确认订单并触发开通。
|
||||||
|
- `cancelOrder(orderId)`:取消订单。
|
||||||
|
- `updateOrderReview(...)`:更新风控/复核状态。
|
||||||
|
- `batchOrderOperation(formData)`:批量操作订单。
|
||||||
|
|
||||||
|
#### 其他管理动作
|
||||||
|
|
||||||
- 用户:`src/actions/admin/users.ts`
|
- 用户:`src/actions/admin/users.ts`
|
||||||
- 套餐:`src/actions/admin/plans.ts`
|
- 套餐:`src/actions/admin/plans.ts`
|
||||||
@@ -200,20 +334,37 @@ Server Actions 是后台和用户端写操作的主要入口。所有管理动
|
|||||||
- 流量视图刷新:`src/actions/admin/traffic.ts`
|
- 流量视图刷新:`src/actions/admin/traffic.ts`
|
||||||
- 优惠券与促销:`src/actions/admin/commerce.ts`
|
- 优惠券与促销:`src/actions/admin/commerce.ts`
|
||||||
|
|
||||||
### 用户端
|
### 用户端 Actions
|
||||||
|
|
||||||
- `src/actions/user/purchase.ts`:立即购买、续费、增流量、查询库存
|
- `src/actions/user/purchase.ts`:立即购买、续费、增流量、查询库存。
|
||||||
- `src/actions/user/cart.ts`:加入购物车、移除、清空、结算
|
- `src/actions/user/cart.ts`:加入购物车、移除、清空、结算。
|
||||||
- `rotateSubscriptionAccess(subscriptionId)`:重置代理订阅访问凭据,并同步更新 3x-ui 客户端
|
- `rotateSubscriptionAccess(subscriptionId)`:重置代理订阅访问凭据,并同步更新 3x-ui 客户端。
|
||||||
- `src/actions/user/account.ts`:资料、密码、邀请码
|
- `src/actions/user/account.ts`:资料、密码、邀请码、邮箱变更。
|
||||||
- `src/actions/user/notifications.ts`:已读、删除、清空
|
- `src/actions/user/notifications.ts`:已读、删除、清空。
|
||||||
- `src/actions/user/support.ts`:创建、回复、关闭、删除工单
|
- `src/actions/user/support.ts`:创建、回复、关闭、删除工单。创建工单会受后台工单上限控制。
|
||||||
- `src/actions/user/orders.ts`:取消待支付订单、重新选择支付方式
|
- `src/actions/user/orders.ts`:取消待支付订单、重新选择支付方式。
|
||||||
|
|
||||||
### 约定
|
## 风控数据模型要点
|
||||||
|
|
||||||
- 写操作必须做权限校验和输入校验
|
- `SubscriptionAccessLog`:保存订阅 API 访问和节点真实连接证据。
|
||||||
- 重要副作用必须记录审计日志
|
- `SubscriptionRiskEvent`:保存风控事件、复核状态、报告、用户端限制和最终处理动作。
|
||||||
- 影响页面展示后必须 `revalidatePath`
|
- `SubscriptionRiskReason`:包含城市、省/地区、国家变化,以及节点高频、目标分散等原因。
|
||||||
- 代理客户端变更必须通过 `src/services/node-panel` 同步 3x-ui
|
- `AppConfig`:保存订阅风控总控、自动暂停开关、阈值、节点日志风控阈值。
|
||||||
- 不再新增节点控制面、运行配置下发、进程管理类 Action
|
- `NodeClient.email`:用于匹配 Xray access log 中的 `email:`。它可能形如 `user@example.com-cmojtnp3`,不要手动在 3x-ui 修改。
|
||||||
|
|
||||||
|
## 错误处理约定
|
||||||
|
|
||||||
|
- 输入校验失败:返回 400 或在 Server Action 中返回可展示错误。
|
||||||
|
- 未登录:返回 401 或跳转登录。
|
||||||
|
- 权限不足:返回 403 或抛出权限错误。
|
||||||
|
- 资源不存在:返回 404 或抛出 not found。
|
||||||
|
- 外部服务失败:保留审计日志或任务记录,前端展示简洁错误。
|
||||||
|
- 生产环境 Server Components 会隐藏原始堆栈;排障时看 `docker compose logs -f app`。
|
||||||
|
|
||||||
|
## 维护约定
|
||||||
|
|
||||||
|
- 新增公开 HTTP 接口时,同时更新 `docs/API.md` 和 `docs/openapi.yaml`。
|
||||||
|
- 新增 Agent 上报字段时,同时更新 `agent/jboard-agent/README.md`。
|
||||||
|
- 新增系统设置时,同时更新 `.env.example` 或 README 中对应后台配置说明。
|
||||||
|
- 涉及 3x-ui 客户端状态的写操作必须通过 `src/services/node-panel` 同步。
|
||||||
|
- 不再新增节点控制面、运行配置下发、Xray 进程管理类 Action。
|
||||||
|
|||||||
Reference in New Issue
Block a user