跳转至

前端架构与数据流

1. 总体架构

PE Agent 前端总体架构

浏览器只访问 PE Agent 的同源地址:

  • /server/*:转发到项目配置的后端 API;
  • /api/*:PE Agent 前端自身的 Route Handler;
  • /project-preview/*:受控的项目预览代理;
  • 页面和静态资源:由 Next.js standalone 服务提供。

浏览器不应直接读取或访问 API_SERVER_URL

2. 根布局与主布局

2.1 根布局

src/app/layout.tsx 负责:

  • HTML 外壳和全局样式;
  • Metadata 和品牌图标;
  • 构建浏览器运行时配置;
  • 注入 window.__RUNTIME_CONFIG__
  • 挂载应用 Provider 和客户端诊断组件。

2.2 主布局

src/app/(main)/layout.tsx 负责:

  • 服务端读取当前用户;
  • 服务端读取业务分区;
  • 向 Zustand Provider 注入首屏状态;
  • 挂载全局用户事件和主界面。

加入 (main) 路由分组不等于自动获得完整权限保护。新页面仍需根据需求显式执行登录检查、功能开关判断和服务端权限验证。

3. 请求链路

PE Agent 前端请求链路

3.1 后端接口:apiClient

src/lib/api/axios.ts 中的 apiClient 面向后端接口:

  • 浏览器基地址为同源 /server
  • 自动附加登录、分区和会话上下文;
  • FormData 请求让浏览器自动设置 Content-Type;
  • 统一规范化错误;
  • 未处理的 401 会清理登录状态并跳转登录页;
  • stream() 为 SSE 和流式请求提供 Reader、文本流和 JSON SSE 能力。

3.2 前端自有接口:appApiClient

appApiClient 面向同源 /api,用于:

  • 健康检查和版本;
  • 客户端日志上传;
  • ONLYOFFICE Token;
  • Sandpack CSS 编译;
  • 项目预览控制。

普通后端 CRUD 不要重复包装成 /api Route Handler。

3.3 服务端请求:serverApiClient

Server Component 和服务端布局通过 src/lib/api/serverFetcher.ts 请求后端。该实例从请求 Cookie 读取登录和分区信息,并附加请求 ID、会话 ID和结构化日志。

3.4 /server/* 代理

src/lib/server/proxyToApiServer.ts 是统一代理实现,src/app/server/[...path]/route.ts 提供通用 GET、POST、PUT、PATCH、DELETE 入口。

代理负责:

  • 去掉 /server 前缀并拼接上游地址;
  • 转发查询参数、请求体和必要请求头;
  • 从 Cookie 注入访问令牌;
  • 需要时刷新令牌;
  • 传递 x-request-idx-session-id
  • 重写认证 Cookie Path;
  • 记录耗时、状态和错误类型;
  • 上游不可用时返回受控错误。

4. API 业务响应

后端业务响应通常包含:

interface ApiResponse<TData> {
  code: number;
  message: string;
  data: TData;
}

HTTP 2xx 不一定代表业务成功。提交、保存、删除等操作应使用 ensureApiResponseSuccess() 检查业务码,再显示成功提示或刷新状态。

5. 状态管理

推荐数据流:

Server Layout -> server service -> initial Store state

Client Page -> Store action -> Service -> /server or /api -> Store update

Client Component -> Store selector -> Render

适合放入 Store:

  • 跨组件共享的用户、分区和 Agent 数据;
  • 可缓存列表和详情;
  • 需要请求去重的数据;
  • 多 Tab 会话之间共享的导航与通知状态。

适合使用 useServiceRequest

  • 表单提交;
  • 删除、兑换、修改密码等一次性操作;
  • 需要独立 loading、success 和 error 状态的交互。

6. 登录状态

前端登录链路包括:

  • 登录、注册和找回密码表单;
  • 浏览器认证 Cookie;
  • getServerUser() 服务端用户获取;
  • 缺少 access token 时刷新;
  • 401 后刷新或清理 Cookie;
  • userStore.authStatus
  • useRequireLogin() 客户端登录守卫。

user_id Cookie 只用于日志关联,不是授权凭据。

安全边界

当前认证 Cookie 可被浏览器 JavaScript 读取。Cookie Domain 配置为跨子域共享时会扩大安全影响范围。私有化部署必须启用 HTTPS、限制同域站点,并由安全人员评估 Cookie 与 XSS 风险。

7. SSE 和长任务

部分长连接使用显式 Route Handler,例如用户事件和 Agent 执行流。这些入口使用 Node.js runtime、动态渲染和较长的 maxDuration

二开流式功能时必须同时处理:

  • AbortSignal 和用户点击停止;
  • x-request-idx-session-id
  • Token 刷新;
  • 流建立、结束、中断和读取错误日志;
  • Nginx 和中间网关超时;
  • 页面切换和组件卸载;
  • 重试是否会产生业务副作用。

8. 多 Tab 会话

总控工作台通过 MasterAgentContentMasterAgentTabSession 保持已打开标签:

  • 切换标签通常不销毁会话;
  • 后台 SSE 可以继续运行;
  • 完成后可以显示未读点;
  • 每个标签保持独立消息和运行状态;
  • 动态任务会话数量存在前端挂载上限。

修改该区域时,不要用单一全局 current record 替代按 Tab 隔离的会话状态。

9. 日志与错误关联

服务端日志入口:src/lib/logger/server.ts
客户端日志入口:src/lib/logger/client.ts
客户端日志上传:src/app/api/client-logs/route.ts

关键关联字段:

  • x-request-id:单次请求;
  • x-session-id:浏览器标签会话;
  • userId:脱敏或受控的用户关联信息;
  • errorCode / errorId:前端展示和日志查询。

生产日志中不得记录密码、验证码、API 密钥或完整认证令牌。上线前必须专项检查认证诊断日志并清理历史敏感日志。