From 8d261afbbc5cfe1324c117682213bc56bdf634f6 Mon Sep 17 00:00:00 2001 From: zh Date: Tue, 22 Sep 2026 18:33:22 +0800 Subject: [PATCH] =?UTF-8?q?docs(adr):=20=E8=A1=A5=E9=BD=90=20ADR-0002/0003?= =?UTF-8?q?/0004=EF=BC=88=E9=83=A8=E7=BD=B2=E5=BD=A2=E6=80=81=E3=80=81?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BD=9C=E7=94=A8=E5=9F=9F=E3=80=81=E6=A1=8C?= =?UTF-8?q?=E9=9D=A2=E7=AB=AF=E8=BE=B9=E7=95=8C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/adr/0001-tech-stack-and-repo.md | 2 +- docs/adr/0002-engine-provider-deployment.md | 36 +++++++++++++++ docs/adr/0003-data-scope-and-authority.md | 44 +++++++++++++++++++ .../0004-desktop-and-local-capabilities.md | 43 ++++++++++++++++++ docs/adr/README.md | 6 +-- 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 docs/adr/0002-engine-provider-deployment.md create mode 100644 docs/adr/0003-data-scope-and-authority.md create mode 100644 docs/adr/0004-desktop-and-local-capabilities.md diff --git a/docs/adr/0001-tech-stack-and-repo.md b/docs/adr/0001-tech-stack-and-repo.md index 72059ec..e01e492 100644 --- a/docs/adr/0001-tech-stack-and-repo.md +++ b/docs/adr/0001-tech-stack-and-repo.md @@ -2,7 +2,7 @@ - **状态**:已接受 - **日期**:2026-09-22 -- **决策人**: +- **决策人**:技术负责人 - **相关**:任务表 A0.1、A0.2;设计文档《架构设计》第 2 节 ## 背景 diff --git a/docs/adr/0002-engine-provider-deployment.md b/docs/adr/0002-engine-provider-deployment.md new file mode 100644 index 0000000..dde934b --- /dev/null +++ b/docs/adr/0002-engine-provider-deployment.md @@ -0,0 +1,36 @@ +# ADR-0002:引擎与 Provider 的部署形态 + +- **状态**:已接受 +- **日期**:2026-09-22 +- **决策人**:技术负责人 +- **相关**:任务表 A0.3(决策 D1);设计文档《架构设计》第 6 节 + +## 背景 + +平台要调用 APS、ERP、EMS 这些业务系统。Provider(能力适配器)跑在平台进程里,还是跑成独立服务,决定了三件事:实现复杂度、故障隔离程度、以及凭据怎么交给 Provider。 + +约束:「凭据不进模型上下文、不落日志」是硬要求;首版只有内部团队接入,没有第三方;工厂内网部署。 + +## 选项 + +| 选项 | 做法 | 代价 | 不选的理由 | +| --- | --- | --- | --- | +| A 进程内 Provider | Core 按 execution 注入短期凭据,Provider 与平台同进程 | 实现简单、无网络鉴权、调试直接 | 选定 | +| B 跨进程 Provider 服务 | 独立服务,双向认证 + 一次性凭据 | 隔离好、可独立发版 | 首版就把鉴权、序列化、部署复杂度前置 | + +## 结论 + +选 A:首版 Provider 运行在平台信任域内,Core 按 execution 注入短期凭据,Provider 不落库、不缓存。 + +代价用三条约束兜住:**Provider 不得阻塞事件循环**;**重活走异步任务**;**每类调用带超时**。跨进程模式留给第三方接入或 Provider 需要独立发版时启用。 + +## 影响 + +- **对代码**:`providers/` 与 `server/core/execution` 同进程运行;`server/provider-sdk/http.ts` 先写好,供将来切跨进程时复用,不改 Provider 实现 +- **对任务**:A2 的假 Provider、A5 的首个真实 Provider 都按进程内实现;B5 的契约化接口做成 HTTP,正是为了将来能平滑切成跨进程 +- **对文档**:设计文档《架构设计》第 6 节「Provider 契约」 +- **不这么做的后果**:首版做跨进程,团队要先把鉴权体系、序列化协议、服务发现做出来,才写第一个能力 + +## 遗留 + +跨进程模式的启动条件:第三方团队接入,或某个 Provider 需要独立发版。到 A8 或更晚再评估,不预先设计。 diff --git a/docs/adr/0003-data-scope-and-authority.md b/docs/adr/0003-data-scope-and-authority.md new file mode 100644 index 0000000..e5fa111 --- /dev/null +++ b/docs/adr/0003-data-scope-and-authority.md @@ -0,0 +1,44 @@ +# ADR-0003:数据作用域与权威数据源 + +- **状态**:已接受 +- **日期**:2026-09-22 +- **决策人**:技术负责人 +- **相关**:任务表 A0.4(决策 D2);设计文档《实施设计》1.5 + +## 背景 + +引擎会在开发或部署期被替换,业务系统会被拆出去独立演进。数据归属如果跟着变,每次调整都要迁数据。所以要在重构开始前把两件事定死:会话的作用域怎么划分,以及每类数据的权威方是谁。 + +## 选项 + +| 选项 | 做法 | 代价 | 不选的理由 | +| --- | --- | --- | --- | +| A 只做项目内共享 | 所有会话归属于项目 | 简单 | 个人临时提问、调研无处安放 | +| B 个人与项目并存,都可写 | 两种作用域一视同仁 | 灵活 | 个人会话能发起写操作时,确认与审计缺少项目归属 | +| C 并存但个人只读 | 个人会话用于查询与调研;写操作必须在项目会话内 | 多一条判定规则 | 选定 | + +## 结论 + +选 C。理由:写操作要过确认、留审计、归集证据,这三件事都要求项目归属;只读的个人会话既保留便利,也不产生无归属的写操作。 + +同时定下权威数据源: + +| 数据 | 权威方 | +| --- | --- | +| 会话与消息、上下文检查点 | 平台(应用服务) | +| 执行记录、确认记录、审计 | 平台(Core) | +| 引擎原生状态(内存上下文、线程) | 对应引擎,仅用于同引擎恢复 | +| 客户端本地 JSONL | 离线副本,冲突以服务端为准 | +| 业务数据(订单、主数据、排产结果) | 业务系统(APS) | + +## 影响 + +- **对代码**:会话表加 `scope` 字段;权限判定收在单一入口,不在各处写 if +- **对任务**:A1.7 定义的事件模型是界面契约;A3.7 会话落库写明"平台检查点为权威、引擎原生状态只作同引擎恢复" +- **对文档**:设计文档《实施设计》1.5「谁是权威数据源」 +- **不这么做的后果**:个人会话能写时,审计链缺主体归属;引擎原生状态若被当作业务真相,换引擎就要迁数据 + +## 遗留 + +- APS 独立后要自带项目与租户概念(任务 B2) +- 既有审批数据里有在途状态,处置方式见 ADR-0005 diff --git a/docs/adr/0004-desktop-and-local-capabilities.md b/docs/adr/0004-desktop-and-local-capabilities.md new file mode 100644 index 0000000..eadbb55 --- /dev/null +++ b/docs/adr/0004-desktop-and-local-capabilities.md @@ -0,0 +1,43 @@ +# ADR-0004:桌面端与本地能力边界 + +- **状态**:已接受 +- **日期**:2026-09-22 +- **决策人**:技术负责人 +- **相关**:任务表 A0.5(决策 D4);设计文档《架构设计》第 7 节 + +## 背景 + +工厂现场用的是 Windows PC,部分机器离线。桌面端要承载界面,还要做打印、扫码、文件访问这类本地能力。平台服务可以集中部署在内网,也可以与客户端同机部署。 + +## 选项 + +| 选项 | 做法 | 代价 | 不选的理由 | +| --- | --- | --- | --- | +| A Electron | 自带 Node 与 Chromium | 体积 150MB 起 | 选定 | +| B Tauri v2 | 系统 WebView,体积 10–20MB | 无 Node 运行时,主进程逻辑要用 Rust 重写;依赖系统 WebView2 | 老机器可能缺 WebView2;重写 sidecar 与离线升级成本高 | +| C 纯浏览器 / PWA | 不装客户端 | 最省 | 没有本地设备能力与离线能力 | + +## 结论 + +首版选 Electron,不投入 Tauri 评估。理由是工厂离线 PC 不必赌系统里有 WebView2,且离线升级、进程守护、单实例这些事都有成熟做法。等包体或内存成为硬指标时再评估 Tauri。 + +桌面端边界: + +| 边界 | 说明 | +| --- | --- | +| 不直连 Provider | 所有业务调用走平台 API,桌面端只是入口 | +| 不持有业务凭据 | 凭据只存在平台凭据代理,本地不落长期密钥 | +| 本地 runner 只做本地事 | 打印、扫码、文件、设备采集可以本地做;业务写操作仍要过 Core | +| 离线只缓存不越权 | 断网时排队与重试,恢复后仍要过策略与确认 | +| 授权沿用现有方式 | 授权码 + 设备绑定。这是既定的商务与运维约定,不在技术选型范围内 | + +## 影响 + +- **对代码**:`client/desktop/`(main / preload / sidecar / updater);sidecar 的语义从"拉 Python 服务"改为"拉起引擎中立的平台服务" +- **对任务**:A10.5 Electron 壳与本地守护、A10.6 离线升级与回滚 +- **对文档**:设计文档《架构设计》第 7 节 +- **不这么做的后果**:选 Tauri 会把 sidecar 编排与离线升级重写成 Rust,工期显著增加,而离线机缺少 WebView2 的风险仍要靠额外方案兜 + +## 遗留 + +设备身份的签发方式(自签证书还是接入现有 PKI)待 A4 身份模块设计时定。 diff --git a/docs/adr/README.md b/docs/adr/README.md index a992c5d..b452f2c 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -39,9 +39,9 @@ ADR 写完不再修改。要改结论就**新写一份**,并在两份里互相 | 编号 | 标题 | 状态 | 来源 | | --- | --- | --- | --- | | [0001](./0001-tech-stack-and-repo.md) | 技术栈与仓库形态 | 已接受 | 任务表 A0.1、A0.2 | -| 0002 | 引擎与 Provider 部署形态 | 待写 | 任务表 A0.3(决策 D1) | -| 0003 | 数据作用域与权威数据源 | 待写 | 任务表 A0.4(决策 D2) | -| 0004 | 桌面端与本地能力边界 | 待写 | 任务表 A0.5(决策 D4) | +| [0002](./0002-engine-provider-deployment.md) | 引擎与 Provider 的部署形态 | 已接受 | 任务表 A0.3(决策 D1) | +| [0003](./0003-data-scope-and-authority.md) | 数据作用域与权威数据源 | 已接受 | 任务表 A0.4(决策 D2) | +| [0004](./0004-desktop-and-local-capabilities.md) | 桌面端与本地能力边界 | 已接受 | 任务表 A0.5(决策 D4) | | 0005 | 迁移与切换策略 | 待写 | 任务表 A0.9(决策 D7) | 编号在写之前先在本表登记,避免多人并行时撞号。