128 lines
6.4 KiB
Markdown
128 lines
6.4 KiB
Markdown
# BPOS-Service-Gateway 开发环境册
|
||
|
||
> 简版。与姊妹仓《BPOS-Service-Task/docs/开发环境册.md》共享设施与纪律段落,本册只写本仓差异与要点。
|
||
>
|
||
> **凭证纪律**:本册只写环境变量的**键名**,绝不落主机、IP、账号、口令、密钥值。
|
||
> 真值去共享设施的凭证发放渠道要,写进本机 `.env`(该文件永不入 git)。
|
||
|
||
---
|
||
|
||
## 1. 本仓是什么
|
||
|
||
API 网关(`bpos-service-gateway`):前端唯一入口。
|
||
会话鉴权 · 按域路由(task/data/agent)· SSE 推送中心 · 上传转对象存储。
|
||
|
||
**8800,无自有库**——不持久化,故无 `db:migrate`、无 outbox、无 relay、无 consumer。
|
||
NATS 只用连通性(订阅 `touch.>` 与按需的 `stream.task.*`)。
|
||
|
||
> 落仓状态:上游《BPOS仓库结构》原六仓拓扑未含网关,§3"待定项"记为待定;
|
||
> `docs/proto-v13` 分支上已有【提案】"已建独立仓 BPOS-Service-Gateway",**待架构负责人确认**。
|
||
|
||
---
|
||
|
||
## 2. 共享设施与配置
|
||
|
||
### 2.1 一条硬性纪律:不许自建本地设施
|
||
|
||
**严禁在本机启动 Docker / 容器 / 任何本地替代基础设施。** NATS 在共享开发机上,
|
||
Keycloak 是共享站点。设施不可达时如实降级或停下,**不起本地兜底**:
|
||
NATS 不可达 → SSE 推送停摆、`/health` 照实报 fail,但代理/上传/健康检查照常服务
|
||
(`src/app/server.ts` 明确不因此拖垮 HTTP 面)。交付如实标注 `SKIPPED-INFRA-DOWN` 或报 BLOCKED。
|
||
|
||
### 2.2 环境变量(只写键名)
|
||
|
||
`.env.example` 是权威清单。
|
||
|
||
| 键名 | 作用 | 缺省与后果 |
|
||
|---|---|---|
|
||
| `PORT` | HTTP 监听端口 | 缺省 8800 |
|
||
| `NATS_URL` | 共享 NATS | `src/shared/config.ts` 有开发期缺省,部署一律显式配 |
|
||
| `KEYCLOAK_URL` / `KEYCLOAK_REALM` | 验签用的站点与 realm | 用户 token 与服务 token 同一 realm |
|
||
| `KEYCLOAK_CLIENT_ID` | 本仓 client,缺省 `api-gateway` | |
|
||
| `KEYCLOAK_CLIENT_SECRET` | **须为 `api-gateway` 服务账号的密钥** | 只从环境读、无缺省。配错/配成别的 client 的密钥=换来别人的服务账号 token(或直接被拒),SSE 的订阅授权全线失败并"人人被拒"。**值绝不写进任何文档或提交**,从 Keycloak 该 client 的 Credentials 页取 |
|
||
| `TASK_SERVICE_URL` | 代理与订阅授权的目标 | 缺省本机 8801 |
|
||
| `DATA_SERVICE_URL` | 代理目标 | 缺省本机 8802 |
|
||
| `AGENT_SERVICE_URL` | 代理目标 | 缺省本机 8901(开发期即 Task 仓的 fake-agent 桩) |
|
||
| `OBJECT_STORE_MODE` / `OBJECT_STORE_DIR` | 上传落盘(FS 适配器) | 缺省目录 `./.objectstore`,已在 `.gitignore` |
|
||
|
||
**为什么这里必须是 `api-gateway` 自己的密钥**:SSE 订阅授权要拿服务账号 token 去问任务服务
|
||
`GET /task/:id/access` 与 `GET /workflow/:id/access`,后者在任务侧是
|
||
`requireService(['api-gateway'])`——只认网关。`src/shared/service-token.ts` 用
|
||
`config.keycloak.clientId` + `KEYCLOAK_CLIENT_SECRET` 换 `client_credentials` token,
|
||
两者必须是**同一个 client** 的。相关的 realm 角色与 audience mapper 配置记录见
|
||
`docs/keycloak-setup-log.md`(该文只记对象名与操作结果,同样不含密钥值)。
|
||
|
||
`.env` / `.env.*` 已在 `.gitignore`(`!.env.example` 例外)。收尾核验里
|
||
`git log --all --oneline --diff-filter=A -- .env | wc -l` 必须为 `0`。
|
||
|
||
---
|
||
|
||
## 3. 端口与运行
|
||
|
||
```bash
|
||
pnpm i # 装依赖
|
||
pnpm dev # tsx watch,读 .env,起在 :8800
|
||
pnpm gates # typecheck + lint + test
|
||
```
|
||
|
||
**无 `db:migrate`**(本仓无自有库)。
|
||
|
||
启动顺序:建 SseHub → 建 app → 起 HTTP → 连 NATS(通则 `hub.attachNats`,不通只告警)。
|
||
`SIGINT`/`SIGTERM`:**先收 SSE 长连**再 `server.close()`——那些响应永远不结束,
|
||
不主动关就会一直等;3s 兜底强退。
|
||
|
||
跨仓端口速查:Gateway 8800(无库)、Task 8801(`jx_dispatch`)、Data 8802(`jx_business`)、
|
||
fake-agent 桩 8901(在 Task 仓 `tools/fake-agent.ts`,Activity 仓交付真桩后退役)。
|
||
|
||
---
|
||
|
||
## 4. 总线用法:只订阅,不建流
|
||
|
||
本仓**不建流、不发布业务事件、无 outbox、无 relay、无 durable**。
|
||
只用 core NATS 订阅两类推送主题(BUS-08 尽力而为,本就不落 JetStream):
|
||
|
||
- `touch.>`:连上就订,进程内按连接可见性扇出;
|
||
- `stream.task.<id>`:**按需**订——有连接订阅了才建 NATS 订阅,最后一个连接退订就撤掉。
|
||
|
||
三条 JetStream 流(`BPOS_EVT` / `BPOS_CMD` / `BPOS_DLQ`)由 Task / Data 两仓引导,与本仓无关。
|
||
|
||
---
|
||
|
||
## 5. 测试纪律
|
||
|
||
本仓无库,共享库那套 `zz_test_` 前缀 / `afterAll` 谓词清理 / LIKE 下划线转义 / 生产扫描排除
|
||
的纪律**在本仓无直接落点**,但两条相关的仍适用:
|
||
|
||
1. **集成用例打的是共享 Keycloak 与共享 NATS**,不许起本地替身;不可达就如实跳过或失败。
|
||
2. **`test/support/token.ts` 是三仓同一性文件**(逐字节相同)——改它要同步三仓并重跑同一性脚本。
|
||
3. 用例造出来的 taskId / workflowId 一律用 `zz_test_` 前缀:它们会经服务账号 token 打到
|
||
任务服务的 `/access` 端点上,落在**共用**的 `jx_dispatch` 库前面,前缀是那边扫描排除的抓手。
|
||
|
||
---
|
||
|
||
## 6. 门禁与验收
|
||
|
||
```bash
|
||
pnpm typecheck # tsc --noEmit
|
||
pnpm lint # eslint src test
|
||
pnpm vitest run # 全量
|
||
pnpm gates # 上面三条
|
||
```
|
||
|
||
跨仓同一性由 Task 仓的脚本统一跑(三仓需为同级目录):
|
||
|
||
```bash
|
||
node ../BPOS-Service-Task/scripts/check-identity.mjs # 期望 16/16
|
||
```
|
||
|
||
本仓参与其中 11 条:`keycloak-auth.ts`、`bus/nats.ts`、`contracts/envelope.ts`、`app/health.ts`、
|
||
`test/support/token.ts`、`vitest.config.ts`(三仓)+ `shared/errors.ts`、`shared/service-token.ts`、
|
||
`shared/trace.ts`(与 Task 两仓)+ `upload/objectstore.ts`、`upload/fs-store.ts`
|
||
(与 Task 的 `channel/objectstore.ts`、`channel/fs-store.ts` 同内容、不同路径)。
|
||
**改这些文件必须同步复制到相关仓,再重跑脚本。**
|
||
|
||
仓内既有记录:`docs/keycloak-setup-log.md`(realm 角色 `service`、两个服务账号的 audience mapper、
|
||
共享 client 影响面、解码真 token 的验证结果)。
|
||
验收演练的一手记录在姊妹仓:`BPOS-Service-Task/tools/n2-acceptance.md`(touch 经 SSE 到浏览器)、
|
||
`n3-acceptance.md`(编排全链)、`BPOS-Service-Data/tools/n1-acceptance.md`(含网关这条腿的 aud 边界)。
|