# studio-cloud-bridge｜公司云端公共中转服务

## 定位

`studio-cloud-bridge` 是放在公司云服务器上的 **Node.js 公共中转服务基础框架**。

它的边界是：

1. 统一托管云端中转能力：后续需要在云服务器上做转发、鉴权、签名、密钥隔离、第三方 API 代理时，都优先加到这个服务里。
2. 统一封装对象存储：当前第一期接入腾讯云 COS 私有 Bucket，提供服务端上传/下载/删除烟测与签名下载能力。
3. 不做业务系统本体：财务、合同、发票、商品等业务逻辑不要直接塞进这里，只在这里放共用的基础设施适配层。
4. 不把永久密钥暴露给前端：前端/其他服务只能拿本服务签出来的短期能力，不能拿腾讯云永久 SecretId/SecretKey。

## 命名规则

- 项目/代码目录：`studio-cloud-bridge`
- PM2 进程名：`studio-cloud-bridge`
- 云端安装目录：`/opt/studio-cloud-bridge/current`
- 云端发布目录：`/opt/studio-cloud-bridge/releases/<YYYYMMDDHHMMSS>`
- 云端环境变量文件：`/opt/studio-cloud-bridge/current/.env`
- 云端日志目录：`/var/log/studio-cloud-bridge/`
- 公开路径建议：`https://wwyl.yipeng.online/studio-cloud-bridge/`
- 默认内网监听：`127.0.0.1:8788`

## 当前 API

| API | 鉴权 | 用途 |
|---|---|---|
| `GET /healthz` | 无 | 健康检查，返回服务状态与 COS 是否已配置 |
| `GET /v1/meta` | `Authorization: Bearer TOKEN_PLACEHOLDER` | 查看服务范围、版本与配置摘要 |
| `POST /v1/cos/sign-download` | `Authorization: Bearer TOKEN_...DER` | 为指定 COS 对象生成短期下载链接 |
| `POST /v1/cos/put-object` | `Authorization: Bearer TOKEN_...DER` | 受控上传 base64 对象，返回 bucket/region/key/etag/sha256/size 等审计元数据 |

示例：

```bash
curl https://wwyl.yipeng.online/studio-cloud-bridge/healthz

curl -H "Authorization: Bearer <API_TOKEN>" \
  https://wwyl.yipeng.online/studio-cloud-bridge/v1/meta
```

## 环境变量

真实值只放在云服务器 `.env`，不要提交到 Git/README/聊天记录。

```bash
NODE_ENV=production
PORT=8788
SERVICE_NAME=studio-cloud-bridge
PUBLIC_BASE_URL=https://wwyl.yipeng.online/studio-cloud-bridge
API_TOKEN=<随机强 token>

TENCENT_SECRET_ID=<腾讯云 CAM SecretId>
TENCENT_SECRET_KEY=<腾讯云 CAM SecretKey>
COS_BUCKET=<bucket-appid，例如 studio-bridge-1250000000>
COS_REGION=<地域，例如 ap-shanghai>
COS_ALLOW_PREFIXES=uploads/,smoke-tests/,finance/invoices/,finance/contracts/,finance/proofs/,finance/sources/
COS_TEST_PREFIX=smoke-tests/
CORS_ORIGINS=
```

## 腾讯云 COS Bucket 创建建议（需要用户确认后再执行/配置）

建议创建一个独立私有 Bucket，作为公司级中转服务的基础存储桶：

- Bucket 名称建议：`studio-cloud-bridge-<你的腾讯云APPID>`
- 地域建议：优先选靠近云服务器/业务用户的地域，例如 `ap-shanghai`；如果你已有公司统一地域，就沿用公司统一地域。
- 访问权限：**私有读写**。
- 目录/前缀策略：
  - `uploads/`：后续业务上传对象；
  - `smoke-tests/`：自动烟测临时对象，脚本会上传、下载校验、删除；
  - 后续每个业务可以再增加前缀，如 `finance/`、`contracts/`、`invoices/`。
- CAM 密钥：建议创建一个专用子账号/策略，不要使用主账号密钥。
- 最小权限策略：只允许对该 Bucket 指定前缀执行 `PutObject`、`GetObject`、`DeleteObject` 等必要动作。

我需要你确认/提供：

1. `COS_BUCKET`：完整 bucket 名，必须包含 APPID，例如 `xxx-1250000000`。
2. `COS_REGION`：地域代码，例如 `ap-shanghai`、`ap-guangzhou`。
3. 一组专用 CAM `SecretId` / `SecretKey`：只给这个 Bucket/前缀的最小权限。
4. 是否确认允许我用 `smoke-tests/` 前缀做真实烟测：上传一个小 txt、下载校验、随后删除。
5. 公开域名路径是否确认使用：`https://wwyl.yipeng.online/studio-cloud-bridge/`。

## 测试与烟测

当前状态（2026-06-08）：已配置 `studio-cloud-1257633934` / `ap-nanjing`，云端真实 COS smoke-tests 上传、下载校验、签名 URL 生成、删除均已通过；`/v1/cos/put-object` 已上线并通过 `finance/sources/...` HTTP 上传/下载/删除 smoke。密钥只保存在本地安全文件和云端 `.env`，不写入 README。

本地/云端基础测试：

```bash
npm test
npm run smoke:local
npm audit --omit=dev --audit-level=high
```

COS 真实烟测（需要配置真实 COS 密钥后执行）：

```bash
npm run smoke:cos
```

`smoke:cos` 会执行：

1. 在 `COS_TEST_PREFIX` 下生成一个随机测试 key；
2. PUT 上传一段小文本；
3. GET 下载并比对内容；
4. 生成短期签名下载 URL；
5. DELETE 删除测试对象；
6. 返回 `ok: true`。

## 云端运维命令

```bash
pm2 status studio-cloud-bridge
pm2 logs studio-cloud-bridge --lines 80
pm2 restart studio-cloud-bridge
pm2 save
curl http://127.0.0.1:8788/healthz
```

如果走 Nginx 公开路径，还需要验证：

```bash
curl https://wwyl.yipeng.online/studio-cloud-bridge/healthz
```

## 安全边界

- 永久密钥只在云端 `.env`，不进代码库、不进 README、不发聊天。
- 所有受保护接口都必须走 `API_TOKEN` 或后续更细的调用方鉴权。
- COS 对象 key 必须落在 `COS_ALLOW_PREFIXES` 内，禁止 `../`、绝对路径、URL 形式 key。
- 真实 Bucket 创建、真实密钥配置、真实烟测执行前，需要用户确认 bucket、region、前缀和测试动作。

