6.4 KiB
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. 端口与运行
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 下划线转义 / 生产扫描排除
的纪律在本仓无直接落点,但两条相关的仍适用:
- 集成用例打的是共享 Keycloak 与共享 NATS,不许起本地替身;不可达就如实跳过或失败。
test/support/token.ts是三仓同一性文件(逐字节相同)——改它要同步三仓并重跑同一性脚本。- 用例造出来的 taskId / workflowId 一律用
zz_test_前缀:它们会经服务账号 token 打到 任务服务的/access端点上,落在共用的jx_dispatch库前面,前缀是那边扫描排除的抓手。
6. 门禁与验收
pnpm typecheck # tsc --noEmit
pnpm lint # eslint src test
pnpm vitest run # 全量
pnpm gates # 上面三条
跨仓同一性由 Task 仓的脚本统一跑(三仓需为同级目录):
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 边界)。