# 本次更新说明（2026-07-22a）— CC iframe 直登 + 对接文档 §2.5

| 项目 | 说明 |
|------|------|
| 打包文件 | **`上传到服务器/chajia-code-20260722a.zip`**（仅代码，约 0.75MB） |
| 对接文档 | **`上传到服务器/文档/api对接文档.md`**（v1.2） |
| 适用场景 | 服务器已有项目，增量覆盖代码 |
| 是否改库 | **否** |
| 是否改 `.env` | **否**（勿覆盖） |
| 重建镜像 | **是**：`bash deploy/update-code-only-bt-host-mysql.sh` |

### 本次代码要点

- `/embed-demo`：宿主传 `login_type` + `api_key` 自动登录，**跳过登录页**；成功后剥离 URL 敏感参数
- 生产嵌入 Cookie：`SameSite=None; Secure`（跨站 iframe）
- 密码 / Key 登录统一两模块门户（MotherShip / Flock）
- 对接文档 v1.2：§2.5 网页嵌入完整说明（参数、iframe 示例、排错）

### 上传与更新

```bash
cp .env .env.backup.$(date +%Y%m%d)
# 解压 chajia-code-20260722a.zip 覆盖代码后：
chmod +x deploy/update-code-only-bt-host-mysql.sh
bash deploy/update-code-only-bt-host-mysql.sh
```

CC iframe 示例：

```text
https://if.dev.51track.vip/embed-demo?login_type=api_key&api_key=<API_Key>&embed=1
```

---

# 历史：本次更新说明（2026-07-21d）— 嵌入门户两模块统一（密码=Key）

| 项目 | 说明 |
|------|------|
| 打包文件 | **`上传到服务器/chajia-code-20260721d.zip`**（仅代码） |
| 适用场景 | 服务器**已有**查价项目，增量覆盖代码 |
| 是否改库 | **否** |
| 是否改 `.env` | **否**（勿覆盖） |
| 重建镜像 | **是**：`bash deploy/update-code-only-bt-host-mysql.sh` |

### 本次代码要点

- 账号密码登录与 API Key 登录同一门户：仅 **MotherShip / Flock Freight** 两模块
- 模块内切换「免账号 / 登录后」；登录后可配置官网账密
- 含 21c：单位换算、选项互斥提示、MS/Flock 稳定性修复

### 上传与更新

```bash
cp .env .env.backup.$(date +%Y%m%d)
# 解压 chajia-code-20260721d.zip 覆盖代码后：
chmod +x deploy/update-code-only-bt-host-mysql.sh
bash deploy/update-code-only-bt-host-mysql.sh
```

---

# 历史：本次更新说明（2026-07-21c）— 单位换算 / 选项互斥提示 / MS+Flock 稳定性

| 项目 | 说明 |
|------|------|
| 打包文件 | **`上传到服务器/chajia-code-20260721c.zip`**（仅代码） |
| 适用场景 | 服务器**已有**查价项目，增量覆盖代码 |
| 是否改库 | **否**（本次无新 migration） |
| 是否改 `.env` | **否**（保留现有即可；勿用包内覆盖） |
| 重建镜像 | **是**：`bash deploy/update-code-only-bt-host-mysql.sh` |

### 本次代码要点

- API 重量/尺寸公制换算（`kg/t`、`cm/m` → `lb/in`，进一）
- MotherShip：地址确认假阳性修复；附加服务 appointment 超时加固；登录态选项互斥提示（禁住宅提货等）
- Flock：调度 radio 点击降级；登录态选项提示（冷藏须温控、易无价地点/包装）
- 询价失败中文原因展示增强

### 上传与更新（推荐）

```powershell
# 开发机：
# X:\work\chajia\上传到服务器\chajia-code-20260721c.zip
# X:\work\chajia\上传到服务器\代码\
```

服务器（项目根目录，勿覆盖 `.env`）：

```bash
cp .env .env.backup.$(date +%Y%m%d)
# 解压 zip 覆盖代码目录后：
chmod +x deploy/update-code-only-bt-host-mysql.sh
bash deploy/update-code-only-bt-host-mysql.sh
```

---

# 历史：本次更新说明（2026-07-21）— 嵌入 Key 登录 / 中文报错 / 预警中文化

| 项目 | 说明 |
|------|------|
| 打包文件 | **`chajia-code-20260721.zip`**（仅代码，约 0.74MB） |
| 适用场景 | 服务器**已有**查价项目，增量覆盖代码 |
| 是否改库 | **否**（本次无新 migration） |
| 是否改 `.env` | **否**（保留现有即可） |
| 重建镜像 | **是**：`bash deploy/update-code-only-bt-host-mysql.sh` |

### 本次代码要点

- `/embed-demo`：账号密码 / API Key 双登录；Key 登录后 4 路线门户（MotherShip/Flock × 免账号/登录后）
- 承运商账密明文回显 + 可保存修改；登录失败 `PROVIDER_LOGIN_FAILED` 中文提示
- 查价失败 / 管理端预警详情：英文 Playwright 日志译中文（含 `locator.waitFor`）

### 上传与更新（推荐）

```powershell
# 开发机已生成：
# X:\work\chajia\chajia-code-20260721.zip
# X:\work\chajia\上传到服务器\代码\
```

服务器（项目根目录，勿覆盖 `.env`）：

```bash
cp .env .env.backup.$(date +%Y%m%d)
# 解压 zip 覆盖代码目录后：
chmod +x deploy/update-code-only-bt-host-mysql.sh
bash deploy/update-code-only-bt-host-mysql.sh
```

---

# 历史：本次更新说明（2026-07-16）— Flock Freight + MotherShip 登录查价 + 客户承运商账密

## 更新主题

| 项目 | 说明 |
|------|------|
| 打包时间 | 2026-07-16（安全增量包） |
| 适用场景 | **服务器已有查价项目**，增量同步本地大更新 |
| 是否改库 | **仅本机 DataGrip 跑 SQL**；服务器上不改库、不跑 migrate；勿重导 `chajia.sql` |
| 是否改 `.env` | **保留**已有 `.env`，**必须追加**下方 Flock / 轮询变量 |
| 是否必须清 Redis | **建议**（避免旧报价缓存） |
| 是否必须重建镜像 | **是**（next-app + rpa-worker 均有大量新代码） |

---

## 安全更新铁律（省磁盘 / 不伤现网）

1. **只覆盖 `代码/`**：不要上传/解压 `数据库/`（增量更新勿导入 SQL）
2. **绝对勿覆盖服务器 `.env`**：上传包不含根目录 `.env`；覆盖前先 `cp .env .env.backup.$(date +%Y%m%d)`
3. **勿停其他无关容器**：只操作本项目 compose 文件 `deploy/docker-compose.bt-host-mysql.yml`
4. **省磁盘**：解压后立刻删 zip；构建前 `df -h`；构建后可 `docker image prune -f`（勿加 `-a`，避免误删正在用的镜像）
5. **防 SSH 断线**：`nohup bash deploy/install-bt-host-mysql.sh > /tmp/chajia-deploy.log 2>&1 &`
6. **构建慢属正常**：`npm ci` + `npm run build` 常需 10–30 分钟，勿反复 Ctrl+C 重开并行构建

---

## 本次必上传 / 必生效的变更清单（勿遗漏）

### A. 代码（打包脚本 `代码/` 已覆盖）

| 模块 | 关键路径 | 说明 |
|------|----------|------|
| Flock 嵌入 UI | `components/flock/`、`app/api/flock/` | 第二报价源表单 / 两档结果 / 轮询 |
| Flock RPA | `workers/rpa/flock*`、`lib/flock/`、`modules/flock/` | Direct + DOM 回退、登录态、队列 `flock-quote` |
| MotherShip 登录查价 | `workers/rpa/mothership-logged-in-quote.ts`、`components/mothership/`、`lib/rpa/mothership-login-context.ts` | 登录态填表刮价 |
| 地址联想 | `app/api/addresses/mothership-suggest/`、`lib/address/` | 登录态选址 |
| 客户承运商账密 | `modules/customer/provider-credentials.ts`、`app/api/admin/customers/.../provider-credentials/`、`app/admin/customers/` | 按客户配置 MotherShip/Flock 官网账密 |
| 中间件 | `middleware.ts` | 放行 `/api/flock`、`/api/addresses` |
| Prisma | `prisma/schema.prisma` + `prisma/migrations/` | 见下方迁移 |
| 依赖清单 | `package.json` / `package-lock.json` | Docker `npm ci` 用 |

### B. 数据库变更（二选一）

| Migration | 作用 |
|-----------|------|
| `20260709175000_service_api_key_ciphertext` | `service_api_key.token_ciphertext` |
| `20260715094000_customer_provider_credential` | 新表 `customer_provider_credential` |

- **推荐**：本机 DataGrip 执行 `deploy/datagrip-manual-migrate-20260716.sql`（服务器零改库）
- **禁止混用**：DataGrip 改过库后，不要再跑 `install-bt-host-mysql.sh` 的自动 migrate

### C. `.env` 必须追加（生产）

```env
# ── Flock Freight（默认关；开启才出现报价源切换）──
FLOCK_RPA_ENABLED=true
FLOCK_QUOTE_URL=https://app.flockfreight.com/get-a-quote
FLOCK_QUOTE_MODE=direct_then_dom
FLOCK_STORAGE_STATE_PATH=.rpa/flock-storage.json
FLOCK_MIN_QUOTES=1
FLOCK_QUOTE_WAIT_MS=20000
FLOCK_POLL_TIMEOUT_MS=210000
NEXT_PUBLIC_FLOCK_POLL_TIMEOUT_MS=210000
FLOCK_WORKER_REUSE_SESSION=false
FLOCK_SESSION_MAX_ROTATIONS=1

# 可选：全局 Flock 登录（优先推荐在管理端「客户管理」按客户配置账密）
# FLOCK_LOGIN_EMAIL=
# FLOCK_LOGIN_PASSWORD=

# MotherShip 登录查价：优先管理端客户账密；也可继续用全局：
# MOTHERSHIP_EMAIL=
# MOTHERSHIP_PASSWORD=
```

**Docker 生产禁止**（若存在请删除/注释）：

```env
# RPA_BROWSER_CHANNEL=chrome
```

容器内无系统 Chrome；设了会启动失败。

**已有项保留**：`MASTER_LOGIN_PASSWORD`、`JWT_SECRET`、`DATABASE_URL`、`HOST_SERVICE_TOKENS`、`RPA_DWELL_MS` 等不要丢。

### D. 管理端部署后必配（数据，非文件）

1. 打开 `/admin/customers`，为需要登录态查价的客户配置 **MotherShip / Flock** 官网邮箱密码  
2. 未配置时：Flock 可能走无痕/弱注册路径（不稳定）；MotherShip 登录查价会缺凭据失败

---

## 本次主要功能（相对服务器 2026-07-10 版）

1. **Flock Freight** 第二报价源（嵌入切换、Direct API 优先 + DOM 回退、串行锁、轮询 210s）
2. **MotherShip 登录后查价**（客户账密 → storage / 登录页 → 填表刮价）
3. **客户级承运商账密**（加密存库，管理端只读查看）
4. **MotherShip 地址联想 API**（登录态选址）
5. 历次能力保留：万能登录密码、客户 API Key、Priority1、加价、embed-demo

---

## 零、开发机打包（Windows）

```powershell
cd X:\work\chajia
powershell -ExecutionPolicy Bypass -File deploy\pack-server-upload.ps1
Compress-Archive -Path "上传到服务器\*" -DestinationPath "chajia-upload-20260716.zip" -Force
```

生成目录：

```
上传到服务器/
├── README.md
├── RELEASE-NOTES.md       ← 本文件（操作步骤）
├── 辅助脚本/
├── 代码/                  ← 上传此目录全部内容（增量更新只传这个）
└── 数据库/                ← 本次增量更新不必上传、不必导入
```

**推荐上传方式（省磁盘）**：只把 **`代码/`** 打成 zip（或整包解压后只覆盖 `代码/`），**不要**把 `数据库/` 传到服务器。

```powershell
# 更省空间的上传包（仅代码，约数 MB～十几 MB）
Compress-Archive -Path "上传到服务器\代码\*" -DestinationPath "chajia-code-20260716.zip" -Force
```

服务器解压后：用 `代码/` 覆盖 `/home/project/chajia/`，**保留 `.env`**。  
**推荐走下方「方式 B」**（DataGrip 改库 + 代码-only 脚本），不要用会自动 migrate 的安装脚本。

---

## 一、服务器更新步骤（场景 B：已有旧版）

### 1. 备份

```bash
cd /home/project/chajia
cp .env .env.backup.$(date +%Y%m%d)
```

### 2. 上传代码

用 **`代码/`** 覆盖 `/home/project/chajia/`。**勿覆盖 `.env`**。  
确认存在：`deploy/datagrip-manual-migrate-20260716.sql`、`deploy/update-code-only-bt-host-mysql.sh`。

### 3. 追加 `.env`（勿整文件替换）

```bash
cd /home/project/chajia

grep -q '^FLOCK_RPA_ENABLED=' .env || cat >> .env <<'EOF'

# --- 2026-07-16 Flock Freight ---
FLOCK_RPA_ENABLED=true
FLOCK_QUOTE_URL=https://app.flockfreight.com/get-a-quote
FLOCK_QUOTE_MODE=direct_then_dom
FLOCK_STORAGE_STATE_PATH=.rpa/flock-storage.json
FLOCK_MIN_QUOTES=1
FLOCK_QUOTE_WAIT_MS=20000
FLOCK_POLL_TIMEOUT_MS=210000
NEXT_PUBLIC_FLOCK_POLL_TIMEOUT_MS=210000
FLOCK_WORKER_REUSE_SESSION=false
FLOCK_SESSION_MAX_ROTATIONS=1
EOF

grep -q '^MASTER_LOGIN_PASSWORD=' .env || echo 'MASTER_LOGIN_PASSWORD=mmgy2026master' >> .env
sed -i '/^RPA_BROWSER_CHANNEL=chrome/d' .env || true
```

---

### 方式 B（推荐）— DataGrip 只改库 SQL + 服务器只更新代码

#### B1. 本机 DataGrip（唯一改库步骤）

1. 连 `192.168.2.14` → 库 **`chajia`**
2. console 粘贴并执行 `deploy/datagrip-manual-migrate-20260716.sql`（或下方两段 DDL）
3. 刷新表列表：应有 `customer_provider_credential`；`service_api_key` 有 `token_ciphertext`
4. **服务器上不要跑任何改库命令**

#### B2. 服务器只更新代码/镜像（不碰库）

```bash
cd /home/project/chajia
chmod +x deploy/update-code-only-bt-host-mysql.sh
bash deploy/update-code-only-bt-host-mysql.sh
```

#### B3. 清 Redis（建议）

```bash
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml exec redis redis-cli FLUSHDB
```

**以后禁止**再跑 `install-bt-host-mysql.sh`（会自动 migrate，与 DataGrip 手改冲突）。

---

### 方式 A（不推荐本次）— 安装脚本自动改库

仅当你**不用** DataGrip、接受服务器自动 `migrate deploy` 时：

```bash
chmod +x deploy/install-bt-host-mysql.sh
nohup bash deploy/install-bt-host-mysql.sh > /tmp/chajia-deploy.log 2>&1 &
```

**注意**：方式 B 与方式 A **不要混用**。

---

### 4. 部署后数据配置

1. 管理端登录：`admin_demo` + 万能密码（或库内密码）
2. **客户管理** → 为目标客户写入 MotherShip / Flock 官网账密
3. 确认客户 embed 密码 / API Key 仍可用

---

## 二、验收

| 检查项 | 操作 | 预期 |
|--------|------|------|
| 容器 | `docker compose ... ps` | next-app / rpa-worker / scheduler / redis 均为 Up |
| 管理端 | `/login` | 可进 `/admin/customers`，可查看承运商账密 |
| MotherShip 匿名 | `/embed-demo` → MotherShip | 询价出 4 档或明确失败码 |
| MotherShip 登录 | 已配账密客户 + 登录查价开关 | 出承运商价卡（非空超时） |
| Flock | 切换 Flock 报价源 | 出两档结果；超时约 210s 内有终态 |
| 库表 | DataGrip | 有 `token_ciphertext` 列 + `customer_provider_credential` 表 |

Worker 日志：

```bash
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml logs -f rpa-worker --tail 100
```

---

## 三、失败排查

| 现象 | 处理 |
|------|------|
| embed 无 Flock 切换 | `.env` 缺 `FLOCK_RPA_ENABLED=true` 或未重建 next-app |
| Flock 一直转圈后超时 | 查 rpa-worker；确认客户/全局登录账密；看是否撞报价上限 |
| MotherShip 登录查价失败 | 管理端是否已配该客户 MotherShip 账密 |
| `chrome is not found` | 删除 `RPA_BROWSER_CHANNEL=chrome` 后重建 rpa-worker |
| Duplicate column / table | 该 DDL 已执行过，跳过即可 |
| 构建 OOM | 用方式 B 串行脚本；或加 Swap；勿并行多个 compose build |

---

## 四、回滚

还原更新前目录 / zip，恢复 `.env.backup.*`，再执行方式 B 的 build/up（或方式 A 安装脚本）。  
库表回滚需在 DataGrip 手工：`DROP TABLE customer_provider_credential`；`ALTER TABLE service_api_key DROP COLUMN token_ciphertext`（仅确认无依赖后）。

---

# 历史更新说明（2026-07-10）— 管理员万能登录密码

## 更新主题

| 项目 | 说明 |
|------|------|
| 打包时间 | 2026-07-10 |
| 适用场景 | **服务器已有查价项目**，增量更新代码 |
| 是否改库 | **否**（安装脚本仍会 `prisma migrate deploy`） |
| 是否改 `.env` | **保留**已有 `.env`，**须追加** `MASTER_LOGIN_PASSWORD`（见下） |
| 是否必须清 Redis | **否** |

### 本次主要功能

1. **管理员万能登录密码**：`.env` 配置 `MASTER_LOGIN_PASSWORD` 后，可用该密码登录管理端与 embed-demo
2. **安全**：未配置则禁用；`timingSafeEqual` 防时序攻击

```env
MASTER_LOGIN_PASSWORD=mmgy2026master
```

---

# 历史更新说明（2026-07-07）— Priority1 网络重试 + 加价展示

详见仓库 git 历史与更早打包记录。完整运维命令、场景 A 首次部署见同目录打包后的说明或 `deploy/服务器更新说明.md`。
