> ## Documentation Index
> Fetch the complete documentation index at: https://docs.magic-resume.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 云端模式

> 云端模式如何把 Clerk、Core API、Agent 后端串到 Magic Resume 里。

云端模式打开了自托管模式下关闭的三件事：

1. **Clerk 鉴权** —— 必须登录，每个 API 请求都带上 JWT。
2. **云端同步** —— 简历经过一套 NestJS 写的 **Core API** 往返，附带版本历史和简历分享。
3. **agent-service**（TypeScript，后端侧）—— 对话、面试、翻译、JD 优化、PDF 解析。

## 模式判定逻辑

`apps/web/src/lib/config/app.ts` 解析当前模式：

```ts theme={null}
// 伪代码
const explicit = process.env.NEXT_PUBLIC_APP_MODE
const hasClerk = !!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY

export const APP_MODE =
  explicit ?? (hasClerk ? 'cloud' : 'self-hosted')
```

`src/middleware.ts` 在模块加载时根据 APP\_MODE 切换 Clerk 的 `clerkMiddleware` 或一个 no-op handler。**没有运行时开关** —— 模式在构建时就定死了。

<Warning>
  如果你设了 `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` 但忘了 `NEXT_PUBLIC_API_URL`，应用仍然会以云端模式启动，所有鉴权请求都会 404。两个一起设，或者两个都别设。
</Warning>

## 环境变量

| 变量                                  | 是否必需（云端） | 作用                                                                                             |
| ----------------------------------- | -------- | ---------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_APP_MODE`              | 可选       | `cloud`。如果存在 Clerk Key，会自动判定为 `cloud`。                                                         |
| `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` | 是        | Clerk 公钥。也是触发云端自动判定的标志。                                                                        |
| `CLERK_SECRET_KEY`                  | 是        | Clerk 服务端密钥。                                                                                   |
| `NEXT_PUBLIC_API_URL`               | 是        | **网关**源——整个后端只用这一个 URL（dev 默认 `http://localhost:3110`）。网关按路径前缀把 `/api/*` 转发到 Core API / agent。 |

## 后端服务

后端（Core API + agent）**独立部署**，不在本 monorepo 内，前面统一挡着一个**网关**。本地开发云端模式时，把后端跑起来，然后用 `NEXT_PUBLIC_API_URL` 指向它的网关（dev 默认 `http://localhost:3110`）——前端永远只需要这一个 URL。如果你只想改前端，自托管模式更快。

## 鉴权流程

* Clerk 在登录时签发一个 JWT。
* `apps/web/src/lib/api/httpClient.ts` 在 Axios 请求拦截器里（`configureHttpClient`）把这个 JWT 作为 `Bearer` token 附上。
* `httpClient.api` 和 `httpClient.agent` 都指向同一个网关源、共用同一个拦截器 —— 你不应该手动传 token。

完整的请求路径见 [架构 → HTTP 客户端](/zh/architecture/http-clients)。
