# 新项目路由与部署规则（多租户路径前缀）

## 1. 路由总览

### 1.1 约定

- 当前实现使用 `/v1` 与 `/super/v1`，多租户前缀待统一改造
- 租户前缀：`/t/:tenant_code/`（不区分大小写；服务端统一按 `lower()` 识别）
- API：`/t/:tenant_code/v1/...`
- Admin SPA：`/t/:tenant_code/admin/...`
- WeChat SPA：`/t/:tenant_code/...`（除 `v1` 与 `admin` 子路径）

### 1.2 为什么必须这样分层

- WeChat/后台前端都是 SPA，通常需要一个 catch-all 回退到 `index.html`
- 同时 API 又需要精确匹配，必须确保 API 路由优先于静态路由

---

## 2. 后端（HTTP Server）路由注册顺序建议

以 Fiber 为例，推荐顺序：

1) `GET /t/:tenant_code/v1/...`：注册所有 API（并注入 TenantContext 中间件）
2) `GET /t/:tenant_code/admin*`：回退到 Admin 的 `index.html`（并正确设置静态资源 base）
3) `GET /t/:tenant_code/*`：回退到 WeChat 的 `index.html`

> 重点：不要用全局 `GET /*` 直接接管，否则会吞掉 API 与 admin。

---

## 3. 前端（Admin）

### 3.1 Router base

- `createWebHistory("/t/<tenant_code>/admin/")`

### 3.2 API baseURL 推导

- 运行时从 `location.pathname` 提取 `tenant_code`
- axios `baseURL = "/t/<tenant_code>/v1"`

### 3.3 Token

- `Authorization: Bearer <token>`（租户后台登录返回）

---

## 4. 前端（WeChat H5）

### 4.1 Router base

- `createWebHistory("/t/<tenant_code>/")`

### 4.2 API baseURL 与 Cookie

- axios `baseURL = "/t/<tenant_code>/v1"`
- `withCredentials = true`（历史 WeChat 方案）
- 当前实现改为 JWT：`Authorization: Bearer <token>`

### 4.3 未登录跳转

- 401 时跳：`/t/<tenant_code>/v1/auth/wechat?redirect=<encodeURIComponent(currentUrl)>`
- 当前实现为 OTP 登录，不走微信授权回调

---

## 5. tenant_code 提取规则（前端共用）

从路径 `/t/<tenant_code>/...` 提取第二段：

- `tenant_code = decodeURIComponent(pathname.split('/')[2] || '')`
- 使用时建议 `tenant_code.toLowerCase()`
- 允许字符集：`a-z0-9_-`（不允许空）

---

## 6. OSS Key 规则

- 统一格式：`quyun/<tenant_uuid>/<md5>.<ext>`
- `tenant_uuid` 来自 `tenants.tenant_uuid`
- `md5` 来自上传文件内容 hash
